Skip to content

Commit

Permalink
fix: Do not try to update unsupported config file formats (#893)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S authored May 24, 2021
1 parent 859b953 commit 6ed7393
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 23 deletions.
1 change: 1 addition & 0 deletions fixtures/workspaces/js-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ WORKSPACEWORD - a word only in the workspace.

Terms:
customterm - Added to Custom Terms.
ignoreterm - A term that is ignored.
11 changes: 1 addition & 10 deletions fixtures/workspaces/js-config/js-config.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,5 @@
"path": "."
}
],
"settings": {
"cSpell.customWorkspaceDictionaries": [
{
"addWords": true,
"description": "Alternate dictionary 2",
"name": "alt-terms",
"path": "${workspaceFolder}/alt-words.txt"
}
]
}
"settings": {}
}
5 changes: 5 additions & 0 deletions fixtures/workspaces/js-config/packages/nested/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Nested folder

This is a nested folder with its own `cspell.config.js` file.

customterm - Added to Custom Terms.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

/** @type { import("@cspell/cspell-types").CSpellUserSettings } */
const cspell = {
description: 'nested js-config example',
};

module.exports = cspell;
5 changes: 5 additions & 0 deletions fixtures/workspaces/js-config/packages/pkg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Config in `package.json` folder

This is a nested folder with `cspell` config stored in the `package.json` file.

customterm - A custom word.
16 changes: 16 additions & 0 deletions fixtures/workspaces/js-config/packages/pkg/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "pkg",
"version": "1.0.0",
"description": "Sample Package",
"main": "index.js",
"scripts": {
"test": "echo test"
},
"cspell": {
"words": [
"customterm"
]
},
"author": "",
"license": "MIT"
}
37 changes: 33 additions & 4 deletions packages/client/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,19 @@ export function addWordToUserDictionary(word: string): Thenable<void> {
}

function addWordToTarget(word: string, target: Settings.Target, docUri: string | null | Uri | undefined) {
return handleErrors(_addWordToTarget(word, target, docUri));
}

function _addWordToTarget(word: string, target: Settings.Target, docUri: string | null | Uri | undefined) {
docUri = parseOptionalUri(docUri);
return di.dependencies.dictionaryHelper.addWordToTarget(word, target, docUri);
}

export async function addIgnoreWordToTarget(word: string, target: Settings.Target, uri: string | null | Uri | undefined): Promise<void> {
export function addIgnoreWordToTarget(word: string, target: Settings.Target, uri: string | null | Uri | undefined): Promise<void> {
return handleErrors(_addIgnoreWordToTarget(word, target, uri));
}

async function _addIgnoreWordToTarget(word: string, target: Settings.Target, uri: string | null | Uri | undefined): Promise<void> {
uri = parseOptionalUri(uri);
const actualTarget = resolveTarget(target, uri);
await Settings.addIgnoreWordToSettings(actualTarget, word);
Expand All @@ -99,7 +107,11 @@ export function removeWordFromUserDictionary(word: string): Thenable<void> {
return removeWordFromTarget(word, Settings.Target.Global, undefined);
}

async function removeWordFromTarget(word: string, target: Settings.Target, uri: string | null | Uri | undefined) {
function removeWordFromTarget(word: string, target: Settings.Target, uri: string | null | Uri | undefined) {
return handleErrors(_removeWordFromTarget(word, target, uri));
}

async function _removeWordFromTarget(word: string, target: Settings.Target, uri: string | null | Uri | undefined) {
uri = parseOptionalUri(uri);
const actualTarget = resolveTarget(target, uri);
await Settings.removeWordFromSettings(actualTarget, word);
Expand All @@ -109,12 +121,12 @@ async function removeWordFromTarget(word: string, target: Settings.Target, uri:

export function enableLanguageId(languageId: string, uri?: string | Uri): Promise<void> {
uri = parseOptionalUri(uri);
return Settings.enableLanguageIdForClosestTarget(languageId, true, uri);
return handleErrors(Settings.enableLanguageIdForClosestTarget(languageId, true, uri));
}

export function disableLanguageId(languageId: string, uri?: string | Uri): Promise<void> {
uri = parseOptionalUri(uri);
return Settings.enableLanguageIdForClosestTarget(languageId, false, uri);
return handleErrors(Settings.enableLanguageIdForClosestTarget(languageId, false, uri));
}

export function userCommandOnCurrentSelectionOrPrompt(
Expand All @@ -134,6 +146,23 @@ export function userCommandOnCurrentSelectionOrPrompt(
};
}

function isError(e: unknown): e is Error {
if (!e) return false;
const err = <Error>e;
return err.message !== undefined && err.name !== undefined;
}

function onError(reason: unknown): Promise<void> {
if (isError(reason)) {
window.showErrorMessage(reason.message);
}
return Promise.resolve();
}

function handleErrors(p: Promise<void>): Promise<void> {
return p.catch(onError);
}

function parseOptionalUri(uri: string | Uri): Uri;
function parseOptionalUri(uri: null | undefined): Uri | undefined;
function parseOptionalUri(uri: string | Uri | null | undefined): Uri | undefined;
Expand Down
4 changes: 3 additions & 1 deletion packages/client/src/settings/CSpellSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const configFileLocations = [
export const nestedConfigLocations = ['package.json'];

const regIsJson = /\.jsonc?$/;
const regIsPackageJson = /package\.json$/i;

export const possibleConfigFiles = new Set(configFileLocations.concat(nestedConfigLocations));
/**
Expand Down Expand Up @@ -167,7 +168,8 @@ export function normalizeWord(word: string): string[] {

export function isUpdateSupportedForConfigFileFormat(uri: Uri): boolean {
const u = uri.with({ fragment: '', query: '' });
return regIsJson.test(u.toString());
const s = u.toString();
return regIsJson.test(s) && !regIsPackageJson.test(s);
}

export class FailedToUpdateConfigFile extends Error {
Expand Down
18 changes: 10 additions & 8 deletions packages/client/src/settings/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
readSettings,
filterOutWords,
readSettingsFileAndApplyUpdate,
isUpdateSupportedForConfigFileFormat,
} from './CSpellSettings';
import { workspace, ConfigurationTarget } from 'vscode';
performance.mark('settings.ts imports 1');
Expand Down Expand Up @@ -69,7 +70,7 @@ export function hasWorkspaceLocation(): boolean {
* Returns a list of files in the order of Best to Worst Match.
* @param uri
*/
export function findSettingsFiles(uri?: Uri): Promise<Uri[]> {
export function findSettingsFiles(uri?: Uri, isUpdatable?: boolean): Promise<Uri[]> {
const { workspaceFolders } = workspace;
if (!workspaceFolders || !hasWorkspaceLocation()) {
return Promise.resolve([]);
Expand All @@ -89,15 +90,16 @@ export function findSettingsFiles(uri?: Uri): Promise<Uri[]> {
.filter((found) => found.exists)
.map((found) => found.filename)
.map((filename) => Uri.file(filename))
.filter((uri) => !isUpdatable || isUpdateSupportedForConfigFileFormat(uri))
);
}

export function findExistingSettingsFileLocation(uri?: Uri): Promise<Uri | undefined> {
return findSettingsFiles(uri).then((paths) => paths[0]);
export function findExistingSettingsFileLocation(uri?: Uri, isUpdatable?: boolean): Promise<Uri | undefined> {
return findSettingsFiles(uri, isUpdatable).then((paths) => paths[0]);
}

export function findSettingsFileLocation(): Promise<Uri | undefined> {
return findExistingSettingsFileLocation().then((path) => path || getDefaultWorkspaceConfigLocation());
export function findSettingsFileLocation(isUpdatable?: boolean): Promise<Uri | undefined> {
return findExistingSettingsFileLocation(undefined, isUpdatable).then((path) => path || getDefaultWorkspaceConfigLocation());
}

export function loadTheSettingsFile(): Promise<SettingsInfo | undefined> {
Expand Down Expand Up @@ -330,7 +332,7 @@ export async function updateSettingInConfig<K extends keyof CSpellUserSettings>(
const orig = config.findScopedSettingFromVSConfig(section, scope);
const uri = (config.isConfigTargetWithOptionalResource(target) && target.uri) || undefined;
const settingsFilename =
(updateCSpell && !config.isGlobalLevelTarget(target) && (await findExistingSettingsFileLocation(uri))) || undefined;
(updateCSpell && !config.isGlobalLevelTarget(target) && (await findExistingSettingsFileLocation(uri, true))) || undefined;

async function updateConfig(): Promise<false | Result> {
if (create || (orig.value !== undefined && orig.scope === config.extractScope(scope))) {
Expand Down Expand Up @@ -381,7 +383,7 @@ export async function determineSettingsPaths(target: config.ConfigTarget, docUri
}

if (config.isWorkspaceLevelTarget(target)) {
const files = await findSettingsFiles();
const files = await findSettingsFiles(undefined, true);
const cfgFileSet = new Set(docConfigFiles?.map((u) => u.toString()) || []);
const filtered = cfgFileSet.size ? files.filter((u) => cfgFileSet.has(u.toString())) : files;
const found = filtered.length ? filtered : docConfigFiles?.slice(0, 1) || [];
Expand All @@ -393,7 +395,7 @@ export async function determineSettingsPaths(target: config.ConfigTarget, docUri
}

const useUri = docUri || undefined;
const path = await findExistingSettingsFileLocation(useUri);
const path = await findExistingSettingsFileLocation(useUri, true);
return path ? [path] : [];
}

Expand Down

0 comments on commit 6ed7393

Please sign in to comment.