All files / services/core/migrations index-exclude-files-migration.ts

92.85% Statements 26/28
90% Branches 9/10
85.71% Functions 6/7
92.85% Lines 26/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85        1x 1x                   1x     4x 2x       4x 1x       4x                             4x   4x     4x   4x 4x   4x       4x 12x     12x 9x     3x 12x   12x 4x 3x         3x 2x       3x        
import * as vscode from 'vscode';
import { getConfig } from '@src/utilities/vscode/config';
import { ISettingsMigration } from '../settings-migration.interface';
 
const OLD_KEY = 'index.ignoreFolders';
const NEW_KEY = 'index.excludeFiles';
 
/**
 * The configuration scopes to migrate, paired with the property on
 * {@link vscode.WorkspaceConfiguration.inspect} that exposes their per-scope value.
 */
const SCOPES: ReadonlyArray<{
	target: vscode.ConfigurationTarget;
	oldOf: (i: ReturnType<vscode.WorkspaceConfiguration['inspect']>) => string[] | undefined;
	newOf: (i: ReturnType<vscode.WorkspaceConfiguration['inspect']>) => string[] | undefined;
}> = [
	{
		target: vscode.ConfigurationTarget.Global,
		oldOf: i => i?.globalValue as string[] | undefined,
		newOf: i => i?.globalValue as string[] | undefined,
	},
	{
		target: vscode.ConfigurationTarget.Workspace,
		oldOf: i => i?.workspaceValue as string[] | undefined,
		newOf: i => i?.workspaceValue as string[] | undefined,
	},
	{
		target: vscode.ConfigurationTarget.WorkspaceFolder,
		oldOf: i => i?.workspaceFolderValue as string[] | undefined,
		newOf: i => i?.workspaceFolderValue as string[] | undefined,
	},
];
 
/**
 * Migrates the deprecated `mentor.index.ignoreFolders` setting to the new
 * glob-based `mentor.index.excludeFiles` setting.
 *
 * For each configuration scope that still defines the old key, its values are
 * merged into the new key (union, order-preserving) and the old key is cleared.
 * The routine is idempotent: scopes without the old key are left untouched, so
 * running it on every activation is safe.
 */
export class IndexExcludeFilesMigration implements ISettingsMigration {
	readonly id = 'index.excludeFiles';
 
	readonly description = 'Migrate the deprecated `index.ignoreFolders` setting to the glob-based `index.excludeFiles` setting.';
 
	async migrate(): Promise<void> {
		const config = getConfig();
 
		const oldInspect = config.inspect<string[]>(OLD_KEY);
		const newInspect = config.inspect<string[]>(NEW_KEY);
 
		Iif (!oldInspect) {
			return;
		}
 
		for (const scope of SCOPES) {
			const oldValue = scope.oldOf(oldInspect);
 
			// Nothing to migrate for this scope.
			if (oldValue === undefined) {
				continue;
			}
 
			const existing = scope.newOf(newInspect) ?? [];
			const merged = [...existing];
 
			for (const pattern of oldValue) {
				if (!merged.includes(pattern)) {
					merged.push(pattern);
				}
			}
 
			// Only write the new key if there is anything to carry over.
			if (oldValue.length > 0) {
				await config.update(NEW_KEY, merged, scope.target);
			}
 
			// Remove the deprecated key from this scope.
			await config.update(OLD_KEY, undefined, scope.target);
		}
	}
}