migrations.rs

  1use anyhow::Result;
  2use serde_json::Value;
  3use settings_content::{PlatformOverrides, ReleaseChannelOverrides};
  4
  5/// Applies a migration callback to the root settings object as well as all
  6/// nested platform, release-channel, and profile override objects.
  7pub(crate) fn migrate_settings(
  8    value: &mut Value,
  9    migrate_one: &mut dyn FnMut(&mut serde_json::Map<String, Value>) -> Result<()>,
 10) -> Result<()> {
 11    let Some(root_object) = value.as_object_mut() else {
 12        return Ok(());
 13    };
 14
 15    migrate_one(root_object)?;
 16
 17    let override_keys = ReleaseChannelOverrides::OVERRIDE_KEYS
 18        .iter()
 19        .copied()
 20        .chain(PlatformOverrides::OVERRIDE_KEYS.iter().copied());
 21
 22    for key in override_keys {
 23        if let Some(sub_object) = root_object.get_mut(key) {
 24            if let Some(sub_map) = sub_object.as_object_mut() {
 25                migrate_one(sub_map)?;
 26            }
 27        }
 28    }
 29
 30    if let Some(profiles) = root_object.get_mut("profiles") {
 31        if let Some(profiles_object) = profiles.as_object_mut() {
 32            for (_profile_name, profile_settings) in profiles_object.iter_mut() {
 33                if let Some(profile_map) = profile_settings.as_object_mut() {
 34                    migrate_one(profile_map)?;
 35                }
 36            }
 37        }
 38    }
 39
 40    Ok(())
 41}
 42
 43/// Applies a migration callback to a value and its `languages` children,
 44/// at the root level as well as all nested platform, release-channel, and
 45/// profile override objects.
 46pub(crate) fn migrate_language_setting(
 47    value: &mut Value,
 48    migrate_fn: fn(&mut Value, path: &[&str]) -> Result<()>,
 49) -> Result<()> {
 50    fn apply_to_value_and_languages(
 51        value: &mut Value,
 52        prefix: &[&str],
 53        migrate_fn: fn(&mut Value, path: &[&str]) -> Result<()>,
 54    ) -> Result<()> {
 55        migrate_fn(value, prefix)?;
 56        let languages = value
 57            .as_object_mut()
 58            .and_then(|obj| obj.get_mut("languages"))
 59            .and_then(|languages| languages.as_object_mut());
 60        if let Some(languages) = languages {
 61            for (language_name, language) in languages.iter_mut() {
 62                let mut path: Vec<&str> = prefix.to_vec();
 63                path.push("languages");
 64                path.push(language_name);
 65                migrate_fn(language, &path)?;
 66            }
 67        }
 68        Ok(())
 69    }
 70
 71    if !value.is_object() {
 72        return Ok(());
 73    }
 74
 75    apply_to_value_and_languages(value, &[], migrate_fn)?;
 76
 77    let Some(root_object) = value.as_object_mut() else {
 78        return Ok(());
 79    };
 80
 81    let override_keys = ReleaseChannelOverrides::OVERRIDE_KEYS
 82        .iter()
 83        .copied()
 84        .chain(PlatformOverrides::OVERRIDE_KEYS.iter().copied());
 85
 86    for key in override_keys {
 87        if let Some(sub_value) = root_object.get_mut(key) {
 88            apply_to_value_and_languages(sub_value, &[key], migrate_fn)?;
 89        }
 90    }
 91
 92    if let Some(profiles) = root_object.get_mut("profiles") {
 93        if let Some(profiles_object) = profiles.as_object_mut() {
 94            let profile_names: Vec<String> = profiles_object.keys().cloned().collect();
 95            for profile_name in &profile_names {
 96                if let Some(profile_settings) = profiles_object.get_mut(profile_name.as_str()) {
 97                    apply_to_value_and_languages(
 98                        profile_settings,
 99                        &["profiles", profile_name],
100                        migrate_fn,
101                    )?;
102                }
103            }
104        }
105    }
106
107    Ok(())
108}
109
110pub(crate) mod m_2025_01_02 {
111    mod settings;
112
113    pub(crate) use settings::SETTINGS_PATTERNS;
114}
115
116pub(crate) mod m_2025_01_29 {
117    mod keymap;
118    mod settings;
119
120    pub(crate) use keymap::KEYMAP_PATTERNS;
121    pub(crate) use settings::{SETTINGS_PATTERNS, replace_edit_prediction_provider_setting};
122}
123
124pub(crate) mod m_2025_01_30 {
125    mod keymap;
126    mod settings;
127
128    pub(crate) use keymap::KEYMAP_PATTERNS;
129    pub(crate) use settings::SETTINGS_PATTERNS;
130}
131
132pub(crate) mod m_2025_03_03 {
133    mod keymap;
134
135    pub(crate) use keymap::KEYMAP_PATTERNS;
136}
137
138pub(crate) mod m_2025_03_06 {
139    mod keymap;
140
141    pub(crate) use keymap::KEYMAP_PATTERNS;
142}
143
144pub(crate) mod m_2025_03_29 {
145    mod settings;
146
147    pub(crate) use settings::SETTINGS_PATTERNS;
148}
149
150pub(crate) mod m_2025_04_15 {
151    mod keymap;
152    mod settings;
153
154    pub(crate) use keymap::KEYMAP_PATTERNS;
155    pub(crate) use settings::SETTINGS_PATTERNS;
156}
157
158pub(crate) mod m_2025_04_21 {
159    mod settings;
160
161    pub(crate) use settings::SETTINGS_PATTERNS;
162}
163
164pub(crate) mod m_2025_04_23 {
165    mod settings;
166
167    pub(crate) use settings::SETTINGS_PATTERNS;
168}
169
170pub(crate) mod m_2025_05_05 {
171    mod settings;
172
173    pub(crate) use settings::SETTINGS_PATTERNS;
174}
175
176pub(crate) mod m_2025_05_08 {
177    mod settings;
178
179    pub(crate) use settings::SETTINGS_PATTERNS;
180}
181
182pub(crate) mod m_2025_06_16 {
183    mod settings;
184
185    pub(crate) use settings::SETTINGS_PATTERNS;
186}
187
188pub(crate) mod m_2025_06_25 {
189    mod settings;
190
191    pub(crate) use settings::SETTINGS_PATTERNS;
192}
193
194pub(crate) mod m_2025_06_27 {
195    mod settings;
196
197    pub(crate) use settings::SETTINGS_PATTERNS;
198}
199
200pub(crate) mod m_2025_07_08 {
201    mod settings;
202
203    pub(crate) use settings::SETTINGS_PATTERNS;
204}
205
206pub(crate) mod m_2025_10_01 {
207    mod settings;
208
209    pub(crate) use settings::flatten_code_actions_formatters;
210}
211
212pub(crate) mod m_2025_10_02 {
213    mod settings;
214
215    pub(crate) use settings::remove_formatters_on_save;
216}
217
218pub(crate) mod m_2025_10_03 {
219    mod settings;
220
221    pub(crate) use settings::SETTINGS_PATTERNS;
222}
223
224pub(crate) mod m_2025_10_16 {
225    mod settings;
226
227    pub(crate) use settings::restore_code_actions_on_format;
228}
229
230pub(crate) mod m_2025_10_17 {
231    mod settings;
232
233    pub(crate) use settings::make_file_finder_include_ignored_an_enum;
234}
235
236pub(crate) mod m_2025_10_21 {
237    mod settings;
238
239    pub(crate) use settings::make_relative_line_numbers_an_enum;
240}
241
242pub(crate) mod m_2025_11_12 {
243    mod settings;
244
245    pub(crate) use settings::SETTINGS_PATTERNS;
246}
247
248pub(crate) mod m_2025_11_20 {
249    mod settings;
250
251    pub(crate) use settings::SETTINGS_PATTERNS;
252}
253
254pub(crate) mod m_2025_11_25 {
255    mod settings;
256
257    pub(crate) use settings::remove_context_server_source;
258}
259
260pub(crate) mod m_2025_12_01 {
261    mod settings;
262
263    pub(crate) use settings::SETTINGS_PATTERNS;
264}
265
266pub(crate) mod m_2025_12_08 {
267    mod keymap;
268
269    pub(crate) use keymap::KEYMAP_PATTERNS;
270}
271
272pub(crate) mod m_2025_12_15 {
273    mod settings;
274
275    pub(crate) use settings::SETTINGS_PATTERNS;
276}
277
278pub(crate) mod m_2025_01_27 {
279    mod settings;
280
281    pub(crate) use settings::make_auto_indent_an_enum;
282}
283
284pub(crate) mod m_2026_02_02 {
285    mod settings;
286
287    pub(crate) use settings::move_edit_prediction_provider_to_edit_predictions;
288}
289
290pub(crate) mod m_2026_02_03 {
291    mod settings;
292
293    pub(crate) use settings::migrate_experimental_sweep_mercury;
294}
295
296pub(crate) mod m_2026_02_04 {
297    mod settings;
298
299    pub(crate) use settings::migrate_tool_permission_defaults;
300}
301
302pub(crate) mod m_2026_02_25 {
303    mod settings;
304
305    pub(crate) use settings::migrate_builtin_agent_servers_to_registry;
306}