[ty] Avoid warning for old settings schema too aggresively (#19787)

## Summary

This PR avoids warning the users too aggressively by checking the
structure of the initialization and workspace options and avoids the
warning if they conform to the old schema.

## Test Plan



https://github.com/user-attachments/assets/9ade9dc4-90cb-4fd4-abd0-4bc4177df3db
This commit is contained in:
Dhruv Manilawala 2025-08-06 21:46:59 +05:30 committed by GitHub
parent b96929ee19
commit ec5660d786
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 22 deletions

View file

@ -98,13 +98,31 @@ impl Server {
let (main_loop_sender, main_loop_receiver) = crossbeam::channel::bounded(32); let (main_loop_sender, main_loop_receiver) = crossbeam::channel::bounded(32);
let client = Client::new(main_loop_sender.clone(), connection.sender.clone()); let client = Client::new(main_loop_sender.clone(), connection.sender.clone());
if !initialization_options.options.unknown.is_empty() { let unknown_options = &initialization_options.options.unknown;
let options = serde_json::to_string_pretty(&initialization_options.options.unknown) if !unknown_options.is_empty() {
.unwrap_or_else(|_| "<invalid JSON>".to_string()); // HACK: Old versions of the ty VS Code extension used a custom schema for settings
tracing::warn!("Received unknown options during initialization: {options}"); // which was changed in version 2025.35.0. This is to ensure that users don't receive
client.show_warning_message(format_args!( // unnecessary warnings when using an older version of the extension. This should be
"Received unknown options during initialization: {options}" // removed after a few releases.
)); if !unknown_options.contains_key("settings")
|| !unknown_options.contains_key("globalSettings")
{
tracing::warn!(
"Received unknown options during initialization: {}",
serde_json::to_string_pretty(unknown_options)
.unwrap_or_else(|_| format!("{unknown_options:?}"))
);
client.show_warning_message(format_args!(
"Received unknown options during initialization: '{}'. \
Refer to the logs for more details",
unknown_options
.keys()
.map(String::as_str)
.collect::<Vec<_>>()
.join("', '")
));
}
} }
// Get workspace URLs without settings - settings will come from workspace/configuration // Get workspace URLs without settings - settings will come from workspace/configuration

View file

@ -458,13 +458,30 @@ impl Session {
.clone() .clone()
.combine(options.clone()); .combine(options.clone());
if !options.unknown.is_empty() { let unknown_options = &options.unknown;
let options = serde_json::to_string_pretty(&options.unknown) if !unknown_options.is_empty() {
.unwrap_or_else(|_| "<invalid JSON>".to_string()); // HACK: This is to ensure that users with an older version of the ty VS Code
tracing::warn!("Received unknown options for workspace `{url}`: {options}"); // extension don't get warnings about unknown options when they are using a newer
client.show_warning_message(format!( // version of the language server. This should be removed after a few releases.
"Received unknown options for workspace `{url}`: {options}", if !unknown_options.contains_key("importStrategy")
)); && !unknown_options.contains_key("interpreter")
{
tracing::warn!(
"Received unknown options for workspace `{url}`: {}",
serde_json::to_string_pretty(unknown_options)
.unwrap_or_else(|_| format!("{unknown_options:?}"))
);
client.show_warning_message(format!(
"Received unknown options for workspace `{url}`: '{}'. \
Refer to the logs for more details.",
unknown_options
.keys()
.map(String::as_str)
.collect::<Vec<_>>()
.join("', '")
));
}
} }
combined_global_options.combine_with(Some(global)); combined_global_options.combine_with(Some(global));

View file

@ -392,8 +392,7 @@ fn unknown_initialization_options() -> Result<()> {
let mut server = TestServerBuilder::new()? let mut server = TestServerBuilder::new()?
.with_workspace(workspace_root, None)? .with_workspace(workspace_root, None)?
.with_initialization_options( .with_initialization_options(
ClientOptions::default() ClientOptions::default().with_unknown([("bar".to_string(), Value::Null)].into()),
.with_unknown([("foo".to_string(), Value::String("bar".to_string()))].into()),
) )
.build()? .build()?
.wait_until_workspaces_are_initialized()?; .wait_until_workspaces_are_initialized()?;
@ -403,7 +402,7 @@ fn unknown_initialization_options() -> Result<()> {
insta::assert_json_snapshot!(show_message_params, @r#" insta::assert_json_snapshot!(show_message_params, @r#"
{ {
"type": 2, "type": 2,
"message": "Received unknown options during initialization: {\n /"foo/": /"bar/"\n}" "message": "Received unknown options during initialization: 'bar'. Refer to the logs for more details"
} }
"#); "#);
@ -418,10 +417,7 @@ fn unknown_options_in_workspace_configuration() -> Result<()> {
let mut server = TestServerBuilder::new()? let mut server = TestServerBuilder::new()?
.with_workspace( .with_workspace(
workspace_root, workspace_root,
Some( Some(ClientOptions::default().with_unknown([("bar".to_string(), Value::Null)].into())),
ClientOptions::default()
.with_unknown([("foo".to_string(), Value::String("bar".to_string()))].into()),
),
)? )?
.build()? .build()?
.wait_until_workspaces_are_initialized()?; .wait_until_workspaces_are_initialized()?;
@ -431,7 +427,7 @@ fn unknown_options_in_workspace_configuration() -> Result<()> {
insta::assert_json_snapshot!(show_message_params, @r#" insta::assert_json_snapshot!(show_message_params, @r#"
{ {
"type": 2, "type": 2,
"message": "Received unknown options for workspace `file://<temp_dir>/foo`: {\n /"foo/": /"bar/"\n}" "message": "Received unknown options for workspace `file://<temp_dir>/foo`: 'bar'. Refer to the logs for more details."
} }
"#); "#);