diff --git a/CHANGELOG.md b/CHANGELOG.md index 3156788..8e21ecb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # Changelog +## 5.3.0 - April 02, 2022 +* (refs [#38](https://github.com/pascalre/vscode-yaml-sort/issues/38)) How to sort on save? +* New configuration `sortOnSave` + ## 5.2.2 - March 31, 2022 * Fix [CVE-2021-44906](https://nvd.nist.gov/vuln/detail/CVE-2021-44906) diff --git a/README.md b/README.md index 0f746c3..050232b 100644 --- a/README.md +++ b/README.md @@ -10,43 +10,56 @@ YAML Sort extends VS Code to sort, format and validate YAML files. # Commands This extension contributes the following commands: -| Command | Description | -|------------------------------------------------|-------------------------------------------------------------------------------------------------------| +| Command | Description | +|------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------| | `Custom Sort 1` | This command will sort a given YAML with custom order. If some of the keys of `customSortKeywords_1` will be found at the top level of the YAML, these will be put at the beginning of the YAML file (in the given order). You can use this e. g. to sort Kubernetes configmaps. | -| `Custom Sort 2` | Same as `Custom Sort 1` | -| `Custom Sort 3` | Same as `Custom Sort 1` | +| `Custom Sort 2` | Same as `Custom Sort 1` | +| `Custom Sort 3` | Same as `Custom Sort 1` | | `Format Document` | Formats a yaml document without sorting it. Also possible using the shortcut (e. g. `SHIFT` + `OPTION` + `F` on Mac). | -| `Recursively sort YAML files` | Sorts all `.yaml` and `.yml` files in a directory and all its subdirectories. | -| `Sort YAML` | Sorts a given YAML. You can either sort the whole YAML document or sort only a selection of the text. | -| `Validate YAML` | Validates a given YAML. | +| `Recursively sort YAML files` | Sorts all `.yaml` and `.yml` files in a directory and all its subdirectories. | +| `Sort YAML` | Sorts a given YAML. You can either sort the whole YAML document or sort only a selection of the text. | +| `Validate YAML` | Validates a given YAML. | # Configuration This extension contributes the following settings: -| Setting | Description | Default | -|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| `emptyLinesUntilLevel` | When bigger than `0`, will add a new line before each keyword on level n. | `0` | -| `customSortKeywords_1` | List of keywords for `Custom Sort 1` | `["apiVersion", "kind", "metadata", "spec", "data"]`| -| `customSortKeywords_2` | List of keywords for `Custom Sort 2` | - | -| `customSortKeywords_3` | List of keywords for `Custom Sort 3` | - | -| `forceQuotes` | When `true`, all non-key strings will be quoted even if they normally don't need to. | `false` | -| `indent` | Indentation width in spaces | `2` | -| `lineWidth` | Maximum line width for YAML files | `500` | -| `locale` | Language whose sort order should be used | `en` | -| `noArrayIndent` | When `true`, will not add an indentation level to array elements. | `false` | -| `noCompatMode` | if `true` don't try to be compatible with older yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 | `false` | -| `quotingType` | Strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. | `'` | -| `schema` | Schema to use. Possible values are `HOMEASSISTANT_SCHEMA`, `CLOUDFORMATION_SCHEMA`, `CORE_SCHEMA`, `DEFAULT_SCHEMA`, `FAILSAFE_SCHEMA`, `JSON_SCHEMA`. | `DEFAULT_SCHEMA` | -| `useAsFormatter` | When `true`, will enable default YAML formatter (requires restart). | `false` | -| `useCustomSortRecursively` | When `true`, will use the custom sort keywords recursively on a file, when using custom sort. | `false` | -| `useLeadingDashes` | When `true`, sorted YAML files begin with leading dashes. | `true` | +| Setting | Description | Default | +|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| ---------------- | +| `emptyLinesUntilLevel` | When bigger than `0`, will add a new line before each keyword on level n. | `0` | +| `customSortKeywords_1` | List of keywords for `Custom Sort 1` | `["apiVersion", "kind", "metadata", "spec", "data"]`| +| `customSortKeywords_2` | List of keywords for `Custom Sort 2` | - | +| `customSortKeywords_3` | List of keywords for `Custom Sort 3` | - | +| `forceQuotes` | When `true`, all non-key strings will be quoted even if they normally don't need to. | `false` | +| `indent` | Indentation width in spaces | `2` | +| `lineWidth` | Maximum line width for YAML files | `500` | +| `locale` | Language whose sort order should be used | `en` | +| `noArrayIndent` | When `true`, will not add an indentation level to array elements. | `false` | +| `noCompatMode` | When `true` don't try to be compatible with older yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 | `false` | +| `quotingType` | Strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. | `'` | +| `schema` | Schema to use. Possible values are `HOMEASSISTANT_SCHEMA`, `CLOUDFORMATION_SCHEMA`, `CORE_SCHEMA`, `DEFAULT_SCHEMA`, `FAILSAFE_SCHEMA`, `JSON_SCHEMA`. | `DEFAULT_SCHEMA` | +| `sortOnSave` | When `true`, will sort file when saving document. Only works in combination with `editor.formatOnSave` and `vscode-yaml-sort.useAsFormatter` both set to `true`. | `true` | +| `useAsFormatter` | When `true`, will enable default YAML formatter (requires restart). | `false` | +| `useCustomSortRecursively` | When `true`, will use the custom sort keywords recursively on a file, when using custom sort. | `false` | +| `useLeadingDashes` | When `true`, sorted YAML files begin with leading dashes. | `true` | + +# FAQ +## How to sort on save? +Register this extension as VS Code formatter. Also configure VS Code to format files on save. Caution: This setting will apply for all files. Changes will require a restart of VS Code. If you wish to also sort (not only format) the file on saving, set `sortOnSave` to `true`. + +#### **`.vscode/settings.json`** +```json +{ + "editor.formatOnSave": true, + "vscode-yaml-sort.sortOnSave": true, + "vscode-yaml-sort.useAsFormatter": true +} +``` # Support If you like YAML Sort, please feel free to [rate it](https://marketplace.visualstudio.com/items?itemName=PascalReitermann93.vscode-yaml-sort&ssr=false#review-details) on the marketplace. -# Issues -If you miss something or found a bug, please let me know and [open an issue](https://github.com/pascalre/vscode-yaml-sort/issues/new) on this project on GitHub. I am very happy about every issue which makes this project better. Do not hesitate to open a pull request with your changes. +If you miss something or found a bug, please let me know and [open an issue](https://github.com/pascalre/vscode-yaml-sort/issues/new) on this project on GitHub. Do not hesitate to open a pull request with your changes. Check [open issues](https://github.com/pascalre/vscode-yaml-sort/issues) on GitHub. diff --git a/package.json b/package.json index d3f8c00..ee58501 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-yaml-sort", "displayName": "YAML Sort", "description": "This VS Code extension exposes the possibility to sort, format and validate yaml files.", - "version": "5.2.2", + "version": "5.3.0", "engines": { "vscode": "^1.49.0" }, @@ -120,7 +120,7 @@ "vscode-yaml-sort.noCompatMode": { "type": "boolean", "default": false, - "description": "If true don't try to be compatible with older yaml versions. Currently: don't quote 'yes', 'no' and so on, as required for YAML 1.1" + "description": "When true, don't try to be compatible with older yaml versions. Currently: don't quote 'yes', 'no' and so on, as required for YAML 1.1" }, "vscode-yaml-sort.quotingType": { "type": "string", @@ -144,6 +144,11 @@ ], "description": "Schema to use" }, + "vscode-yaml-sort.sortOnSave": { + "type": "boolean", + "default": true, + "description": "When true, will sort files when saving" + }, "vscode-yaml-sort.useAsFormatter": { "type": "boolean", "default": false, @@ -242,4 +247,4 @@ "homeassistant-js-yaml-schema": "^1.0.2", "js-yaml": "^4.1.0" } -} +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 350193a..cb855de 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -22,7 +22,12 @@ export function activate(context: vscode.ExtensionContext) { const formatter: vscode.DocumentFormattingEditProvider = { provideDocumentFormattingEdits(): vscode.TextEdit[] { - return formatYamlWrapper() + const sortOnSave = vscode.workspace.getConfiguration().get('vscode-yaml-sort.sortOnSave') as boolean; + if (sortOnSave) {/* istanbul ignore next */ + return sortYamlWrapper() + } else {/* istanbul ignore next */ + return formatYamlWrapper() + } } } @@ -31,10 +36,10 @@ export function activate(context: vscode.ExtensionContext) { let registration: vscode.Disposable | undefined; function registerFormatterIfEnabled() { const isEnabled = vscode.workspace.getConfiguration().get('vscode-yaml-sort.useAsFormatter', true); - if (isEnabled && !registration) { + if (isEnabled && !registration) {/* istanbul ignore next */ registration = vscode.languages.registerDocumentFormattingEditProvider('yaml', formatter); - } else if (!isEnabled && registration) { - registration.dispose(); + } else if (!isEnabled && registration) {/* istanbul ignore next */ + registration.dispose();/* istanbul ignore next */ registration = undefined; } } @@ -82,14 +87,14 @@ export function dumpYaml(text: string, sortKeys: boolean, customSort: number, in } let yaml = jsyaml.dump(text, { - indent : indent, - forceQuotes : forceQuotes, - lineWidth : lineWidth, - noArrayIndent : noArrayIndent, - noCompatMode : noCompatMode, - quotingType : quotingType, - schema : schema, - sortKeys : (!(customSort > 0 && useCustomSortRecursively) ? sortKeys : (a: string, b: string) => { + indent: indent, + forceQuotes: forceQuotes, + lineWidth: lineWidth, + noArrayIndent: noArrayIndent, + noCompatMode: noCompatMode, + quotingType: quotingType, + schema: schema, + sortKeys: (!(customSort > 0 && useCustomSortRecursively) ? sortKeys : (a: string, b: string) => { const sortOrder = getCustomSortKeywords(customSort) const indexA = sortOrder.indexOf(a) const indexB = sortOrder.indexOf(b) @@ -125,29 +130,42 @@ export function getCustomSortKeywords(count: number): [string] { throw new Error("The count parameter is not in a valid range") } -export function sortYamlWrapper(customSort = 0): boolean { +/** + * Applys edits to a text editor + * @param activeEditor Editor to apply the changes + * @param edits Changes to apply + */ +export function applyEdits(activeEditor: vscode.TextEditor, edits: [vscode.TextEdit]) { + if (activeEditor) { + const workEdits = new vscode.WorkspaceEdit() + workEdits.set(activeEditor.document.uri, edits) + vscode.workspace.applyEdit(workEdits) + } +} + +export function sortYamlWrapper(customSort = 0): vscode.TextEdit[] { if (vscode.window.activeTextEditor) { - const activeEditor = vscode.window.activeTextEditor - const emptyLinesUntilLevel = vscode.workspace.getConfiguration().get("vscode-yaml-sort.emptyLinesUntilLevel") as number - const forceQuotes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.forceQuotes") as boolean - const indent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number - const lineWidth = vscode.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number - const locale = vscode.workspace.getConfiguration().get("vscode-yaml-sort.locale") as string - const noArrayIndent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noArrayIndent") as boolean - const noCompatMode = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noCompatMode") as boolean - const quotingType = vscode.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | '"' - const schema = vscode.workspace.getConfiguration().get("vscode-yaml-sort.schema") as "HOMEASSISTANT_SCHEMA" | "CLOUDFORMATION_SCHEMA" | "CORE_SCHEMA" | "DEFAULT_SCHEMA" | "FAILSAFE_SCHEMA" | "JSON_SCHEMA" + const activeEditor = vscode.window.activeTextEditor + const emptyLinesUntilLevel = vscode.workspace.getConfiguration().get("vscode-yaml-sort.emptyLinesUntilLevel") as number + const forceQuotes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.forceQuotes") as boolean + const indent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number + const lineWidth = vscode.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number + const locale = vscode.workspace.getConfiguration().get("vscode-yaml-sort.locale") as string + const noArrayIndent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noArrayIndent") as boolean + const noCompatMode = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noCompatMode") as boolean + const quotingType = vscode.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | '"' + const schema = vscode.workspace.getConfiguration().get("vscode-yaml-sort.schema") as "HOMEASSISTANT_SCHEMA" | "CLOUDFORMATION_SCHEMA" | "CORE_SCHEMA" | "DEFAULT_SCHEMA" | "FAILSAFE_SCHEMA" | "JSON_SCHEMA" const useCustomSortRecursively = vscode.workspace.getConfiguration().get("vscode-yaml-sort.useCustomSortRecursively") as boolean - const useLeadingDashes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.useLeadingDashes") as boolean - let doc = activeEditor.document.getText() - let numberOfLeadingSpaces = 0 - let rangeToBeReplaced = new vscode.Range( + const useLeadingDashes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.useLeadingDashes") as boolean + let doc = activeEditor.document.getText() + let numberOfLeadingSpaces = 0 + let rangeToBeReplaced = new vscode.Range( new vscode.Position(0, 0), new vscode.Position(activeEditor.document.lineCount + 1, 0)) if (!["'", "\""].includes(quotingType)) { vscode.window.showErrorMessage("Quoting type is an invalid value. Please check your settings.") - return false + return [] } if (!activeEditor.selection.isEmpty) { @@ -166,11 +184,11 @@ export function sortYamlWrapper(customSort = 0): boolean { // check if selection to sort is valid, maybe the user missed a trailing line if (isSelectionInvalid(doc, getSchema(schema))) { vscode.window.showErrorMessage("YAML selection is invalid. Please check the ending of your selection.") - return false + return [] } } else { if (!validateYaml(doc, getSchema(schema))) { - return false + return [] } } @@ -210,35 +228,35 @@ export function sortYamlWrapper(customSort = 0): boolean { } if (validYaml) { - // update yaml - activeEditor.edit((builder) => builder.replace(rangeToBeReplaced, newText)) + const edits = vscode.TextEdit.replace(rangeToBeReplaced, newText) vscode.window.showInformationMessage("Keys resorted successfully") + applyEdits(activeEditor, [edits]) + return [edits] } - return true } - return false + return [] } export function sortYaml( - unsortedYaml : string, - customSort = 0, - emptyLinesUntilLevel : number, - indent : number, - useCustomSortRecursively : boolean, - forceQuotes : boolean, - lineWidth : number, - noArrayIndent : boolean, - noCompatMode : boolean, - quotingType : "'" | '"', - schema : jsyaml.Schema, - locale : string - ): string|null { + unsortedYaml: string, + customSort = 0, + emptyLinesUntilLevel: number, + indent: number, + useCustomSortRecursively: boolean, + forceQuotes: boolean, + lineWidth: number, + noArrayIndent: boolean, + noCompatMode: boolean, + quotingType: "'" | '"', + schema: jsyaml.Schema, + locale: string +): string | null { try { - const loadOptions = {schema: schema} + const loadOptions = { schema: schema } const unsortedYamlWithoutTabs = replaceTabsWithSpaces(unsortedYaml, indent) // eslint-disable-next-line @typescript-eslint/no-explicit-any - const doc = jsyaml.load(unsortedYamlWithoutTabs, loadOptions) as any - let sortedYaml = "" + const doc = jsyaml.load(unsortedYamlWithoutTabs, loadOptions) as any + let sortedYaml = "" if (customSort > 0 && !useCustomSortRecursively) { const keywords = getCustomSortKeywords(customSort) @@ -247,13 +265,13 @@ export function sortYaml( if (doc[key]) { let sortedSubYaml = dumpYaml(doc[key], true, customSort, indent, forceQuotes, lineWidth, noArrayIndent, noCompatMode, quotingType, useCustomSortRecursively, schema, locale) if ((sortedSubYaml.includes(":") && !sortedSubYaml.startsWith("|")) || sortedSubYaml.startsWith("-")) { - // when key cotains more than one line, we need some transformation: - // add a new line and indent each line some spaces - sortedSubYaml = prependWhitespacesOnEachLine(sortedSubYaml, indent) - if (sortedSubYaml.endsWith("\n")) { - sortedSubYaml = removeTrailingCharacters(sortedSubYaml, indent) - } - sortedYaml += key + ":\n" + sortedSubYaml + "\n" + // when key cotains more than one line, we need some transformation: + // add a new line and indent each line some spaces + sortedSubYaml = prependWhitespacesOnEachLine(sortedSubYaml, indent) + if (sortedSubYaml.endsWith("\n")) { + sortedSubYaml = removeTrailingCharacters(sortedSubYaml, indent) + } + sortedYaml += key + ":\n" + sortedSubYaml + "\n" } else { sortedYaml += key + ": " + sortedSubYaml + "\n" } @@ -297,7 +315,7 @@ export function validateYamlWrapper(): boolean { export function validateYaml(text: string, schema: jsyaml.Schema): boolean { try { splitYaml(text).forEach((yaml) => { - jsyaml.load(yaml, {schema: schema}) + jsyaml.load(yaml, { schema: schema }) }) vscode.window.showInformationMessage("YAML is valid.") return true @@ -310,15 +328,15 @@ export function validateYaml(text: string, schema: jsyaml.Schema): boolean { } export function formatYamlWrapper(): vscode.TextEdit[] { - const activeEditor = vscode.window.activeTextEditor - const forceQuotes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.forceQuotes") as boolean - const indent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number - const lineWidth = vscode.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number - const locale = vscode.workspace.getConfiguration().get("vscode-yaml-sort.locale") as string - const noArrayIndent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noArrayIndent") as boolean - const noCompatMode = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noCompatMode") as boolean - const quotingType = vscode.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | '"' - const schema = vscode.workspace.getConfiguration().get("vscode-yaml-sort.schema") as "HOMEASSISTANT_SCHEMA" | "CLOUDFORMATION_SCHEMA" | "CORE_SCHEMA" | "DEFAULT_SCHEMA" | "FAILSAFE_SCHEMA" | "JSON_SCHEMA" + const activeEditor = vscode.window.activeTextEditor + const forceQuotes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.forceQuotes") as boolean + const indent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number + const lineWidth = vscode.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number + const locale = vscode.workspace.getConfiguration().get("vscode-yaml-sort.locale") as string + const noArrayIndent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noArrayIndent") as boolean + const noCompatMode = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noCompatMode") as boolean + const quotingType = vscode.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | '"' + const schema = vscode.workspace.getConfiguration().get("vscode-yaml-sort.schema") as "HOMEASSISTANT_SCHEMA" | "CLOUDFORMATION_SCHEMA" | "CORE_SCHEMA" | "DEFAULT_SCHEMA" | "FAILSAFE_SCHEMA" | "JSON_SCHEMA" const useLeadingDashes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.useLeadingDashes") as boolean if (activeEditor) { @@ -338,7 +356,7 @@ export function formatYamlWrapper(): vscode.TextEdit[] { let formattedYaml let validYaml = true const yamls = splitYaml(doc) - for(const unformattedYaml of yamls) { + for (const unformattedYaml of yamls) { formattedYaml = formatYaml(unformattedYaml, false, indent, forceQuotes, lineWidth, noArrayIndent, noCompatMode, quotingType, getSchema(schema), locale) if (formattedYaml) { newText += delimiters.shift() + formattedYaml @@ -355,7 +373,8 @@ export function formatYamlWrapper(): vscode.TextEdit[] { new vscode.Range( new vscode.Position(0, 0), new vscode.Position(activeEditor.document.lineCount + 1, 0)), - newText) + newText) + applyEdits(activeEditor, [edits]) return [edits] } } @@ -368,20 +387,20 @@ export function formatYamlWrapper(): vscode.TextEdit[] { * @returns {string} Formatted yaml. */ export function formatYaml( - yaml : string, - useLeadingDashes : boolean, - indent : number, - forceQuotes : boolean, - lineWidth : number, - noArrayIndent : boolean, - noCompatMode : boolean, - quotingType : "'" | '"', - schema : jsyaml.Schema, - locale : string - ): string|null { + yaml: string, + useLeadingDashes: boolean, + indent: number, + forceQuotes: boolean, + lineWidth: number, + noArrayIndent: boolean, + noCompatMode: boolean, + quotingType: "'" | '"', + schema: jsyaml.Schema, + locale: string +): string | null { try { - const loadOptions = {schema: schema} - let doc = dumpYaml(jsyaml.load(yaml, loadOptions) as string, false, 0, indent, forceQuotes, lineWidth, noArrayIndent, noCompatMode, quotingType, false, schema, locale) + const loadOptions = { schema: schema } + let doc = dumpYaml(jsyaml.load(yaml, loadOptions) as string, false, 0, indent, forceQuotes, lineWidth, noArrayIndent, noCompatMode, quotingType, false, schema, locale) if (useLeadingDashes) { doc = "---\n" + doc } @@ -400,20 +419,20 @@ export function formatYaml( * @param {vscode.Uri} uri Base URI */ export function sortYamlFiles(uri: vscode.Uri): boolean { - const emptyLinesUntilLevel = vscode.workspace.getConfiguration().get("vscode-yaml-sort.emptyLinesUntilLevel") as number - const forceQuotes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.forceQuotes") as boolean - const indent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number - const lineWidth = vscode.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number - const locale = vscode.workspace.getConfiguration().get("vscode-yaml-sort.locale") as string - const noArrayIndent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noArrayIndent") as boolean - const noCompatMode = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noCompatMode") as boolean - const quotingType = vscode.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | '"' - const schema = vscode.workspace.getConfiguration().get("vscode-yaml-sort.schema") as "HOMEASSISTANT_SCHEMA" | "CLOUDFORMATION_SCHEMA" | "CORE_SCHEMA" | "DEFAULT_SCHEMA" | "FAILSAFE_SCHEMA" | "JSON_SCHEMA" + const emptyLinesUntilLevel = vscode.workspace.getConfiguration().get("vscode-yaml-sort.emptyLinesUntilLevel") as number + const forceQuotes = vscode.workspace.getConfiguration().get("vscode-yaml-sort.forceQuotes") as boolean + const indent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number + const lineWidth = vscode.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number + const locale = vscode.workspace.getConfiguration().get("vscode-yaml-sort.locale") as string + const noArrayIndent = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noArrayIndent") as boolean + const noCompatMode = vscode.workspace.getConfiguration().get("vscode-yaml-sort.noCompatMode") as boolean + const quotingType = vscode.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | '"' + const schema = vscode.workspace.getConfiguration().get("vscode-yaml-sort.schema") as "HOMEASSISTANT_SCHEMA" | "CLOUDFORMATION_SCHEMA" | "CORE_SCHEMA" | "DEFAULT_SCHEMA" | "FAILSAFE_SCHEMA" | "JSON_SCHEMA" const useCustomSortRecursively = vscode.workspace.getConfiguration().get("vscode-yaml-sort.useCustomSortRecursively") as boolean const files = getYamlFilesInDirectory(uri.fsPath) files.forEach((file: string) => { - const yaml = fs.readFileSync(file, 'utf-8').toString() + const yaml = fs.readFileSync(file, 'utf-8').toString() const sortedYaml = sortYaml(yaml, 0, emptyLinesUntilLevel, indent, useCustomSortRecursively, forceQuotes, lineWidth, noArrayIndent, noCompatMode, quotingType, getSchema(schema), locale) if (sortedYaml) { try { @@ -421,7 +440,7 @@ export function sortYamlFiles(uri: vscode.Uri): boolean { } catch (e) { /* istanbul ignore next */ vscode.window.showErrorMessage("File " + file + " could not be sorted") - } + } } else { vscode.window.showErrorMessage("File " + file + " could not be sorted") } @@ -436,7 +455,7 @@ export function sortYamlFiles(uri: vscode.Uri): boolean { * @param {jsyaml.Schema} schema * @returns {boolean} true, if selection is missing something */ - export function isSelectionInvalid(text: string, schema: jsyaml.Schema):boolean { +export function isSelectionInvalid(text: string, schema: jsyaml.Schema): boolean { // remove trailing whitespaces, to check for things like 'text: ' text = text.trim() const notValidEndingCharacters = [":", "|", ">"] diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index 605d6ba..1abb932 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -36,9 +36,9 @@ suite("Test getCustomSortKeywords", () => { }) test("should fail when parameter is not in [1, 2, 3]", () => { - assert.throws(() => getCustomSortKeywords( 0), new Error("The count parameter is not in a valid range")) - assert.throws(() => getCustomSortKeywords( 4), new Error("The count parameter is not in a valid range")) - assert.throws(() => getCustomSortKeywords( -1), new Error("The count parameter is not in a valid range")) + assert.throws(() => getCustomSortKeywords(0), new Error("The count parameter is not in a valid range")) + assert.throws(() => getCustomSortKeywords(4), new Error("The count parameter is not in a valid range")) + assert.throws(() => getCustomSortKeywords(-1), new Error("The count parameter is not in a valid range")) assert.throws(() => getCustomSortKeywords(1.5), new Error("The count parameter is not in a valid range")) }) }) @@ -101,7 +101,7 @@ suite("Test validateYaml", () => { test("do not fail when executing command", async () => { const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + await vscode.window.showTextDocument(doc, { preview: false }) await vscode.commands.executeCommand("vscode-yaml-sort.validateYaml") }) }) @@ -118,7 +118,7 @@ suite("Test sortYamlFiles", () => { assert.strictEqual(sortedFile, "akey: value\nkey: value") fs.writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file.yaml", "key: value\nakey: value") - fs.writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file2.yaml", "key: value\nakey: value") + fs.writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file2.yaml", "key: value\nakey: value") }) test("should return `true` on invalid yaml", async () => { const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/folder2")) @@ -204,7 +204,7 @@ suite("Test formatYamlWrapper", () => { 'key:\n' + ' key2: value' - assert.strictEqual(formatYamlWrapper()[0].newText, expected) + assert.strictEqual(formatYamlWrapper()[0].newText, expected) } else { assert.strictEqual(true, false) } @@ -222,7 +222,7 @@ suite("Test formatYamlWrapper", () => { '---\n' + 'key2: value' - assert.strictEqual(formatYamlWrapper()[0].newText, expected) + assert.strictEqual(formatYamlWrapper()[0].newText, expected) } else { assert.strictEqual(true, false) } @@ -234,7 +234,7 @@ suite("Test formatYamlWrapper", () => { const activeEditor = vscode.window.activeTextEditor if (activeEditor) { - assert.strictEqual(undefined, undefined) + assert.strictEqual(undefined, undefined) } else { assert.strictEqual(true, false) } @@ -242,7 +242,7 @@ suite("Test formatYamlWrapper", () => { }) suite("Test sortYamlWrapper", () => { - test("should return false on invalid quotingType", async () => { + test("should return `[]` on invalid quotingType", async () => { const settings = vscode.workspace.getConfiguration("vscode-yaml-sort") await settings.update("quotingType", "`", vscode.ConfigurationTarget.Global) @@ -262,14 +262,14 @@ suite("Test sortYamlWrapper", () => { new vscode.Position(activeEditor.document.lineCount + 1, 0)), actual)) - assert.strictEqual(sortYamlWrapper(), false) + assert.deepStrictEqual(sortYamlWrapper(), []) } else { assert.strictEqual(true, false) } - + await settings.update("quotingType", "'", vscode.ConfigurationTarget.Global) }) - test("should return true on a valid yaml", async () => { + test("should return edits on a valid yaml", async () => { const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) const doc = await vscode.workspace.openTextDocument(uri) await vscode.window.showTextDocument(doc, { preview: false }) @@ -278,7 +278,7 @@ suite("Test sortYamlWrapper", () => { if (activeEditor) { const actual = 'key:\n' + - ' key2: value' + ' key2: value' activeEditor.edit((builder) => builder.replace( new vscode.Range( @@ -286,12 +286,12 @@ suite("Test sortYamlWrapper", () => { new vscode.Position(activeEditor.document.lineCount + 1, 0)), actual)) - assert.strictEqual(sortYamlWrapper(), true) + assert.notDeepStrictEqual(sortYamlWrapper(), []) } else { assert.strictEqual(true, false) } }) - test("should return false on invalid selection", async () => { + test("should return `[]` on invalid selection", async () => { const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) const doc = await vscode.workspace.openTextDocument(uri) await vscode.window.showTextDocument(doc, { preview: false }) @@ -307,9 +307,9 @@ suite("Test sortYamlWrapper", () => { new vscode.Position(0, 0), new vscode.Position(activeEditor.document.lineCount + 1, 0)), actual)) - + activeEditor.selection = new vscode.Selection(0, 0, 0, 4) - assert.strictEqual(sortYamlWrapper(), false) + assert.deepStrictEqual(sortYamlWrapper(), []) } else { assert.strictEqual(true, false) } @@ -326,7 +326,7 @@ suite("Test sortYamlWrapper", () => { ' key2: value\n' + ' key3: value\n' + 'key4: value' - + activeEditor.selection = new vscode.Selection(0, 0, 3, 0) await vscode.commands.executeCommand("vscode-yaml-sort.sortYaml") // do not assert too fast @@ -359,7 +359,7 @@ suite("Test sortYamlWrapper", () => { new vscode.Position(0, 0), new vscode.Position(activeEditor.document.lineCount + 1, 0)), actual)) - + await vscode.commands.executeCommand("vscode-yaml-sort.sortYaml") // do not assert too fast // await new Promise(r => setTimeout(r, 2000)); @@ -372,7 +372,7 @@ suite("Test sortYamlWrapper", () => { suite("Test formatYaml", () => { test("should sort all yaml files in directory", () => { - const actual = + const actual = 'persons:\n' + ' bob:\n' + ' place: "Germany"\n' + @@ -539,40 +539,40 @@ suite("Test sortYaml", () => { let expected = 'AWSTemplateFormatVersion: 2010-09-09T00:00:00.000Z' assert.strictEqual(sortYaml(actual, 0, 2, 2, false, false, 500, false, true, "'", jsyaml.DEFAULT_SCHEMA, locale), expected) - expected = actual - assert.strictEqual(sortYaml(actual, 0, 2, 2, false, false, 500, false, true, "'", jsyaml.CORE_SCHEMA, locale), expected) + expected = actual + assert.strictEqual(sortYaml(actual, 0, 2, 2, false, false, 500, false, true, "'", jsyaml.CORE_SCHEMA, locale), expected) }) test("should sort a yaml with CLOUDFORMATION_SCHEMA", () => { const actual = - 'LoggingBucketKMSKeyAlias:\n' + - ' Properties:\n' + - ' TargetKeyId: !Sub "LoggingBucketKMSKey"\n' + - ' AliasName: !Sub "alias/AppName/Environment/s3-logging-kms"' + 'LoggingBucketKMSKeyAlias:\n' + + ' Properties:\n' + + ' TargetKeyId: !Sub "LoggingBucketKMSKey"\n' + + ' AliasName: !Sub "alias/AppName/Environment/s3-logging-kms"' const expected = - 'LoggingBucketKMSKeyAlias:\n' + - '\n' + - ' Properties:\n' + - ' AliasName: !Sub "alias/AppName/Environment/s3-logging-kms"\n' + - ' TargetKeyId: !Sub "LoggingBucketKMSKey"' - assert.strictEqual(sortYaml(actual, 0, 2, 2, false, true, 500, false, true, "\"", CLOUDFORMATION_SCHEMA, locale), expected) + 'LoggingBucketKMSKeyAlias:\n' + + '\n' + + ' Properties:\n' + + ' AliasName: !Sub "alias/AppName/Environment/s3-logging-kms"\n' + + ' TargetKeyId: !Sub "LoggingBucketKMSKey"' + assert.strictEqual(sortYaml(actual, 0, 2, 2, false, true, 500, false, true, "\"", CLOUDFORMATION_SCHEMA, locale), expected) }) test("compatibility with older yaml versions should be configurable", () => { const actual = - 'key:\n' + - ' on: foo\n' + - ' off: egg' + 'key:\n' + + ' on: foo\n' + + ' off: egg' let expected = - 'key:\n' + - ' "off": egg\n' + - ' "on": foo' - assert.strictEqual(sortYaml(actual, 0, 0, 2, false, false, 500, false, false, "\"", CLOUDFORMATION_SCHEMA, locale), expected) + 'key:\n' + + ' "off": egg\n' + + ' "on": foo' + assert.strictEqual(sortYaml(actual, 0, 0, 2, false, false, 500, false, false, "\"", CLOUDFORMATION_SCHEMA, locale), expected) expected = - 'key:\n' + - ' off: egg\n' + - ' on: foo' - assert.strictEqual(sortYaml(actual, 0, 0, 2, false, false, 500, false, true, "\"", CLOUDFORMATION_SCHEMA, locale), expected) + 'key:\n' + + ' off: egg\n' + + ' on: foo' + assert.strictEqual(sortYaml(actual, 0, 0, 2, false, false, 500, false, true, "\"", CLOUDFORMATION_SCHEMA, locale), expected) }) }) \ No newline at end of file