├── .npmignore ├── test ├── test-utf16le.yml ├── test.yml ├── sorted.yml ├── test-multiple.yml ├── test-duplicate-keys.yml ├── test-multiple-sorted.yml ├── test-multiple-unsorted.yml ├── test-edges.yml ├── test-long-line.yml └── test.js ├── .github └── workflows │ ├── node.js.yml │ └── npm-publish.yml ├── package.json ├── LICENSE ├── README.md ├── .gitignore └── yaml-sort.js /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | .github/ -------------------------------------------------------------------------------- /test/test-utf16le.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddebin/yaml-sort/HEAD/test/test-utf16le.yml -------------------------------------------------------------------------------- /test/test.yml: -------------------------------------------------------------------------------- 1 | b: 2 | c: 3 | d: false 4 | b: 35 5 | a: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...' -------------------------------------------------------------------------------- /test/sorted.yml: -------------------------------------------------------------------------------- 1 | a: Lorem ipsum dolor sit amet, consectetur adipiscing elit... 2 | b: 3 | b: 35 4 | c: 5 | d: false 6 | -------------------------------------------------------------------------------- /test/test-multiple.yml: -------------------------------------------------------------------------------- 1 | --- 2 | c: 3 | d: true 4 | b: 1 5 | a: first document 6 | --- 7 | y: 8 | z: false 9 | x: second document -------------------------------------------------------------------------------- /test/test-duplicate-keys.yml: -------------------------------------------------------------------------------- 1 | a: first value 2 | b: value 3 | a: second value # Duplicate key 4 | c: 5 | d: value1 6 | d: value2 # Duplicate key -------------------------------------------------------------------------------- /test/test-multiple-sorted.yml: -------------------------------------------------------------------------------- 1 | --- 2 | a: first document 3 | b: 1 4 | c: 5 | d: true 6 | --- 7 | x: second document 8 | 'y': 9 | z: false 10 | -------------------------------------------------------------------------------- /test/test-multiple-unsorted.yml: -------------------------------------------------------------------------------- 1 | --- 2 | c: 3 | d: true 4 | b: 1 5 | a: first document 6 | --- 7 | y: 8 | z: false 9 | x: second document 10 | -------------------------------------------------------------------------------- /test/test-edges.yml: -------------------------------------------------------------------------------- 1 | b: 2 | c: 3 | d: false 4 | f: "'foo'" 5 | e: '"foo"' 6 | a: 'hello: "john"' 7 | b: 35 8 | a: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...' -------------------------------------------------------------------------------- /test/test-long-line.yml: -------------------------------------------------------------------------------- 1 | b: 2 | c: 3 | d: false 4 | b: 35 5 | a: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam nec volutpat mi, ac consectetur est. Proin venenatis tortor ut erat interdum finibus. -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: [push, pull_request] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node-version: [20, 22, 24] 14 | steps: 15 | - uses: actions/checkout@v5 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v6 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - run: npm install 21 | - run: npm run lint 22 | - run: npm test 23 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | permissions: 11 | id-token: write # Required for OIDC 12 | contents: read 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v5 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: latest 22 | - run: npm install 23 | - run: npm run lint 24 | - run: npm test 25 | 26 | publish-npm: 27 | needs: build 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v5 31 | - uses: actions/setup-node@v6 32 | with: 33 | node-version: latest 34 | registry-url: https://registry.npmjs.org/ 35 | - run: npm install 36 | - run: npm publish 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yaml-sort", 3 | "version": "3.0.0", 4 | "description": "Sort YAML files alphabetically", 5 | "main": "yaml-sort.js", 6 | "scripts": { 7 | "test": "test/test.js", 8 | "lint": "standard", 9 | "fix": "standard --fix" 10 | }, 11 | "bin": { 12 | "yaml-sort": "yaml-sort.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/ddebin/yaml-sort.git" 17 | }, 18 | "keywords": [ 19 | "cli", 20 | "yaml", 21 | "yml", 22 | "sort", 23 | "stream", 24 | "shell" 25 | ], 26 | "author": "Damien Debin ", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/ddebin/yaml-sort/issues" 30 | }, 31 | "homepage": "https://github.com/ddebin/yaml-sort#readme", 32 | "dependencies": { 33 | "js-yaml": "^4.0.0", 34 | "yargs": "^18.0.0" 35 | }, 36 | "devDependencies": { 37 | "standard": "^17.0.0", 38 | "tape": "^5.6.6", 39 | "tape-spawn": "^1.4.2" 40 | }, 41 | "engines": { 42 | "node": ">=20" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Damien Debin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Node.js CI](https://github.com/ddebin/yaml-sort/workflows/Node.js%20CI/badge.svg) 2 | [![npm version](https://badge.fury.io/js/yaml-sort.svg)](https://www.npmjs.com/package/yaml-sort) 3 | 4 | # About 5 | 6 | `yaml-sort` sorts [YAML](https://yaml.org/) files alphabetically. 7 | 8 | This tool is basically a tiny wrapper around [js-yaml](https://github.com/nodeca/js-yaml). 9 | 10 | (Inspired by [yml-sorter](https://github.com/42BV/yml-sorter)) 11 | 12 | # Installation 13 | 14 | `npm install -g yaml-sort` 15 | 16 | # Usage 17 | 18 | ``` 19 | Usage: yaml-sort [options] 20 | 21 | Options: 22 | -i, --input The YAML file(s) which needs to be sorted [array] [default: STDIN] 23 | -o, --output The YAML file to output sorted content to [string] [default: overwrite input file if specified or STDOUT] 24 | -s, --stdout Output the proposed sort to STDOUT only [boolean] 25 | -k, --check Check if the given file(s) is already sorted [boolean] 26 | --indent, --id Indentation width (in spaces) [number] [default: 2] 27 | -e, --encoding Input encoding [choices: "ascii", "utf8", "utf16le"] [default: "utf8"] 28 | -q, --quotingStyle Strings will be quoted using this quoting style [choices: "single", "double"] [default: "single"] 29 | -f, --forceQuotes Force quotes around all strings [boolean] 30 | -w, --lineWidth Wrap line width (-1 for unlimited width) [number] [default: 80] 31 | -h, --help Show help [boolean] 32 | --version Show version number [boolean] 33 | 34 | Examples: 35 | yaml-sort --input config.yml Sorts alphabetically and overwrites the file config.yml 36 | yaml-sort --input config.yml --lineWidth 100 --stdout Sorts the file config.yml and output result to STDOUT wrapped to 100 columns 37 | yaml-sort --input config.yml --indent 4 --output sorted.yml Indents with 4 spaces and outputs result to file sorted.yml 38 | cat config.yml | yaml-sort Sorts alphabetically from STDIN 39 | ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Dependency lock file 45 | package-lock.json 46 | 47 | # TypeScript v1 declaration files 48 | typings/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Microbundle cache 60 | .rpt2_cache/ 61 | .rts2_cache_cjs/ 62 | .rts2_cache_es/ 63 | .rts2_cache_umd/ 64 | 65 | # Optional REPL history 66 | .node_repl_history 67 | 68 | # Output of 'npm pack' 69 | *.tgz 70 | 71 | # Yarn Integrity file 72 | .yarn-integrity 73 | 74 | # dotenv environment variables file 75 | .env 76 | .env.test 77 | 78 | # parcel-bundler cache (https://parceljs.org/) 79 | .cache 80 | 81 | # Next.js build output 82 | .next 83 | 84 | # Nuxt.js build / generate output 85 | .nuxt 86 | dist 87 | 88 | # Gatsby files 89 | .cache/ 90 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 91 | # https://nextjs.org/blog/next-9-1#public-directory-support 92 | # public 93 | 94 | # vuepress build output 95 | .vuepress/dist 96 | 97 | # Serverless directories 98 | .serverless/ 99 | 100 | # FuseBox cache 101 | .fusebox/ 102 | 103 | # DynamoDB Local files 104 | .dynamodb/ 105 | 106 | # TernJS port file 107 | .tern-port 108 | 109 | # JetBrains files 110 | .idea 111 | -------------------------------------------------------------------------------- /yaml-sort.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict' 4 | 5 | const fs = require('fs') 6 | const yaml = require('js-yaml') 7 | const yargs = require('yargs') 8 | const { hideBin } = require('yargs/helpers') 9 | 10 | const argv = yargs(hideBin(process.argv)) 11 | .usage('Usage: $0 [options]') 12 | .example([ 13 | ['$0 --input config.yml', 14 | 'Sorts alphabetically and overwrites the file config.yml'], 15 | ['$0 --input config.yml --lineWidth 100 --stdout', 16 | 'Sorts the file config.yml and output result to STDOUT wrapped to 100 columns'], 17 | ['$0 --input config.yml --indent 4 --output sorted.yml', 18 | 'Indents with 4 spaces and outputs result to file sorted.yml'], 19 | ['cat config.yml | $0', 20 | 'Sorts alphabetically from STDIN'] 21 | ]) 22 | .option('input', { 23 | alias: 'i', 24 | describe: 'The YAML file(s) which needs to be sorted', 25 | default: '-', 26 | defaultDescription: 'STDIN', 27 | normalize: true, 28 | string: true, 29 | array: true 30 | }) 31 | .option('output', { 32 | alias: 'o', 33 | describe: 'The YAML file to output sorted content to', 34 | defaultDescription: 'overwrite input file if specified or STDOUT', 35 | normalize: true, 36 | string: true 37 | }) 38 | .option('stdout', { 39 | alias: 's', 40 | describe: 'Output the proposed sort to STDOUT only', 41 | conflicts: 'output', 42 | boolean: true 43 | }) 44 | .option('check', { 45 | alias: 'k', 46 | describe: 'Check if the given file(s) is already sorted', 47 | conflicts: ['output', 'stdout'], 48 | boolean: true 49 | }) 50 | .option('indent', { 51 | alias: 'id', 52 | default: 2, 53 | describe: 'Indentation width (in spaces)', 54 | number: true 55 | }) 56 | .option('encoding', { 57 | alias: 'e', 58 | default: 'utf8', 59 | describe: 'Input encoding', 60 | choices: ['ascii', 'utf8', 'utf16le'] 61 | }) 62 | .option('quotingStyle', { 63 | alias: 'q', 64 | default: 'single', 65 | describe: 'Strings will be quoted using this quoting style', 66 | choices: ['single', 'double'] 67 | }) 68 | .option('forceQuotes', { 69 | alias: 'f', 70 | describe: 'Force quotes around all strings', 71 | boolean: true 72 | }) 73 | .option('lineWidth', { 74 | alias: 'w', 75 | default: 80, 76 | describe: 'Wrap line width (-1 for unlimited width)', 77 | number: true 78 | }) 79 | .help('h') 80 | .alias('h', 'help') 81 | .version() 82 | .wrap(null) 83 | .parse() 84 | 85 | let success = true 86 | 87 | argv.input.forEach((file) => { 88 | try { 89 | const isStdin = file === '-' 90 | 91 | if (isStdin && process.stdin.isTTY) { 92 | console.error('Missing filename or input ("yaml-sort --help" for help)') 93 | process.exit(22) 94 | } 95 | 96 | const output = 97 | argv.stdout || (argv.output === '.') || (isStdin && !argv.output) 98 | ? process.stdout.fd 99 | : (argv.output ? argv.output : file) 100 | 101 | const content = fs.readFileSync(isStdin ? process.stdin.fd : file, argv.encoding) 102 | 103 | const documents = yaml.loadAll(content) 104 | 105 | const sortedDocuments = documents.map(doc => yaml.dump(doc, { 106 | sortKeys: true, 107 | indent: argv.indent, 108 | lineWidth: argv.lineWidth, 109 | quotingType: argv.quotingStyle === 'double' ? '"' : "'", 110 | forceQuotes: argv.forceQuotes 111 | })) 112 | 113 | const hasDocumentStart = content.toString().trimStart().startsWith('---') 114 | 115 | const sortedContent = (hasDocumentStart ? '---\n' : '') + sortedDocuments.join('---\n') 116 | 117 | if (argv.check) { 118 | if (sortedContent !== content.toString()) { 119 | success = false 120 | console.warn(`'${file}' is not sorted and/or formatted (indent, line width).`) 121 | } 122 | } else { 123 | fs.writeFile( 124 | output, 125 | sortedContent, 126 | (error) => { 127 | if (error) { 128 | success = false 129 | console.error(error) 130 | } 131 | }) 132 | } 133 | } catch (error) { 134 | success = false 135 | console.error(error) 136 | } 137 | }) 138 | 139 | if (!success) { 140 | process.exit(1) 141 | } 142 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict' 4 | 5 | const test = require('tape') 6 | const spawn = require('tape-spawn') 7 | const opts = { cwd: __dirname } 8 | 9 | test('CLI --help', (t) => { 10 | const proc = spawn(t, '../yaml-sort.js -h', opts) 11 | proc.stdout.match(/^Usage:/) 12 | proc.stderr.match('') 13 | proc.exitCode(0) 14 | proc.end() 15 | }) 16 | 17 | test('CLI w/o arg', (t) => { 18 | const proc = spawn(t, '../yaml-sort.js', opts) 19 | proc.stdout.match('') 20 | proc.exitCode(1) 21 | proc.end() 22 | }) 23 | 24 | test('CLI w/o arg (STDIN)', (t) => { 25 | const proc = spawn(t, 'cat test.yml | ../yaml-sort.js', opts) 26 | proc.exitCode(0) 27 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 28 | 'b:\n' + 29 | ' b: 35\n' + 30 | ' c:\n' + 31 | ' d: false\n') 32 | proc.stderr.match('') 33 | proc.end() 34 | }) 35 | 36 | test('CLI w/ arg', (t) => { 37 | const proc = spawn(t, '../yaml-sort.js --input test.yml --stdout', opts) 38 | proc.exitCode(0) 39 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 40 | 'b:\n' + 41 | ' b: 35\n' + 42 | ' c:\n' + 43 | ' d: false\n') 44 | proc.stderr.match('') 45 | proc.end() 46 | }) 47 | 48 | test('CLI quoting style single', (t) => { 49 | const proc = spawn(t, '../yaml-sort.js --input test-edges.yml --stdout --quotingStyle single', opts) 50 | proc.exitCode(0) 51 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 52 | 'b:\n' + 53 | ' b: 35\n' + 54 | ' c:\n' + 55 | ' a: \'hello: "john"\'\n' + 56 | ' d: false\n' + 57 | ' e: \'"foo"\'\n' + 58 | ' f: \'\'\'foo\'\'\'\n') 59 | proc.stderr.match('') 60 | proc.end() 61 | }) 62 | 63 | test('CLI quoting style double', (t) => { 64 | const proc = spawn(t, '../yaml-sort.js --input test-edges.yml --stdout --quotingStyle double', opts) 65 | proc.exitCode(0) 66 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 67 | 'b:\n' + 68 | ' b: 35\n' + 69 | ' c:\n' + 70 | ' a: "hello: \\"john\\""\n' + 71 | ' d: false\n' + 72 | ' e: "\\"foo\\""\n' + 73 | ' f: "\'foo\'"\n') 74 | proc.stderr.match('') 75 | proc.end() 76 | }) 77 | 78 | test('CLI --output', (t) => { 79 | const proc = spawn(t, 80 | '../yaml-sort.js --input test.yml --output output.yml' + 81 | ' && cat output.yml' + 82 | ' && rm -f output.yml', opts) 83 | proc.exitCode(0) 84 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 85 | 'b:\n' + 86 | ' b: 35\n' + 87 | ' c:\n' + 88 | ' d: false\n') 89 | proc.stderr.match('') 90 | proc.end() 91 | }) 92 | 93 | test('CLI --output -', (t) => { 94 | const proc = spawn(t, '../yaml-sort.js --input test.yml --output -', opts) 95 | proc.exitCode(0) 96 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 97 | 'b:\n' + 98 | ' b: 35\n' + 99 | ' c:\n' + 100 | ' d: false\n') 101 | proc.stderr.match('') 102 | proc.end() 103 | }) 104 | test('CLI --output (STDIN)', (t) => { 105 | const proc = spawn(t, 106 | 'cat test.yml | ../yaml-sort.js --input - --output output.yml' + 107 | ' && cat output.yml' + 108 | ' && rm -f output.yml', opts) 109 | proc.exitCode(0) 110 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 111 | 'b:\n' + 112 | ' b: 35\n' + 113 | ' c:\n' + 114 | ' d: false\n') 115 | proc.stderr.match('') 116 | proc.end() 117 | }) 118 | 119 | test('CLI (STDIN) (STDOUT)', (t) => { 120 | const proc = spawn(t, 'cat test.yml | ../yaml-sort.js', opts) 121 | proc.exitCode(0) 122 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 123 | 'b:\n' + 124 | ' b: 35\n' + 125 | ' c:\n' + 126 | ' d: false\n') 127 | proc.stderr.match('') 128 | proc.end() 129 | }) 130 | 131 | test('CLI --indent', (t) => { 132 | const proc = spawn(t, '../yaml-sort.js --input test.yml --stdout --indent 4', opts) 133 | proc.exitCode(0) 134 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' + 135 | 'b:\n' + 136 | ' b: 35\n' + 137 | ' c:\n' + 138 | ' d: false\n') 139 | proc.stderr.match('') 140 | proc.end() 141 | }) 142 | 143 | test('CLI --lineWidth', (t) => { 144 | const proc = spawn(t, '../yaml-sort.js --input test.yml --stdout --lineWidth 40', opts) 145 | proc.exitCode(0) 146 | proc.stdout.match('a: >-\n' + 147 | ' Lorem ipsum dolor sit amet, consectetur\n' + 148 | ' adipiscing elit...\n' + 149 | 'b:\n' + 150 | ' b: 35\n' + 151 | ' c:\n' + 152 | ' d: false\n') 153 | proc.stderr.match('') 154 | proc.end() 155 | }) 156 | 157 | test('CLI --lineWidth unlimited', (t) => { 158 | const proc = spawn(t, '../yaml-sort.js --input test-long-line.yml --stdout --lineWidth -1', opts) 159 | proc.exitCode(0) 160 | proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam nec volutpat mi, ac consectetur est. Proin venenatis tortor ut erat interdum finibus.\n' + 161 | 'b:\n' + 162 | ' b: 35\n' + 163 | ' c:\n' + 164 | ' d: false\n') 165 | proc.stderr.match('') 166 | proc.end() 167 | }) 168 | 169 | test('CLI --check FAIL', (t) => { 170 | const proc = spawn(t, 171 | '../yaml-sort.js --input test.yml --check', opts) 172 | proc.exitCode(1) 173 | proc.stdout.match('') 174 | proc.stderr.match('\'test.yml\' is not sorted and/or formatted (indent, line width).\n') 175 | proc.end() 176 | }) 177 | 178 | test('CLI --check SUCCESS', (t) => { 179 | const proc = spawn(t, 180 | '../yaml-sort.js --input sorted.yml --check', opts) 181 | proc.exitCode(0) 182 | proc.stdout.match('') 183 | proc.stderr.match('') 184 | proc.end() 185 | }) 186 | 187 | test('CLI --check invalid YAML (duplicate keys) FAIL', (t) => { 188 | const proc = spawn(t, '../yaml-sort.js --input test-duplicate-keys.yml --check', opts) 189 | proc.exitCode(1) 190 | proc.stdout.match('') 191 | proc.stderr.match(/duplicated mapping key/) 192 | 193 | proc.end() 194 | }) 195 | 196 | test('CLI --check valid YAML SUCCESS', (t) => { 197 | const proc = spawn(t, '../yaml-sort.js --input sorted.yml --check', opts) 198 | proc.exitCode(0) 199 | proc.stdout.match('') 200 | proc.stderr.match('') 201 | proc.end() 202 | }) 203 | 204 | test('CLI --encoding FAIL', (t) => { 205 | const proc = spawn(t, 206 | '../yaml-sort.js --input test-utf16le.yml --stdout', opts) 207 | proc.exitCode(1) 208 | proc.stdout.match('') 209 | proc.stderr.match(/null byte is not allowed in input/) 210 | proc.end() 211 | }) 212 | 213 | test('CLI --encoding SUCCESS', (t) => { 214 | const proc = spawn(t, 215 | '../yaml-sort.js --input test-utf16le.yml --stdout --encoding utf16le', opts) 216 | proc.exitCode(0) 217 | proc.stderr.match('') 218 | proc.end() 219 | }) 220 | 221 | test('CLI --lineWidth SUCCESS', (t) => { 222 | const proc = spawn(t, 223 | '../yaml-sort.js --input test.yml --output output.yml' + 224 | ' && ../yaml-sort.js --input output.yml --check' + 225 | ' && rm -f output.yml', opts) 226 | proc.exitCode(0) 227 | proc.stdout.match('') 228 | proc.stderr.match('') 229 | proc.end() 230 | }) 231 | 232 | test('CLI --output --stdout FAIL', (t) => { 233 | const proc = spawn(t, 234 | '../yaml-sort.js --input test.yml --stdout --output output.yml', opts) 235 | proc.exitCode(1) 236 | proc.stdout.match('') 237 | proc.stderr.match(/Arguments stdout and output are mutually exclusive/) 238 | proc.end() 239 | }) 240 | 241 | test('CLI --check --stdout FAIL', (t) => { 242 | const proc = spawn(t, 243 | '../yaml-sort.js --input test.yml --check --stdout', opts) 244 | proc.exitCode(1) 245 | proc.stdout.match('') 246 | proc.stderr.match(/Arguments check and stdout are mutually exclusive/) 247 | proc.end() 248 | }) 249 | 250 | test('CLI multiple YAML documents with single quotes', (t) => { 251 | const proc = spawn(t, '../yaml-sort.js --input test-multiple.yml --stdout --quotingStyle single --forceQuotes', opts) 252 | proc.exitCode(0) 253 | proc.stdout.match( 254 | '---\n' + 255 | 'a: \'first document\'\n' + 256 | 'b: 1\n' + 257 | 'c:\n' + 258 | ' d: true\n' + 259 | '---\n' + 260 | 'x: \'second document\'\n' + 261 | '\'y\':\n' + 262 | ' z: false\n' 263 | ) 264 | proc.stderr.match('') 265 | proc.end() 266 | }) 267 | 268 | test('CLI multiple YAML documents with double quotes', (t) => { 269 | const proc = spawn(t, '../yaml-sort.js --input test-multiple.yml --stdout --quotingStyle double --forceQuotes', opts) 270 | proc.exitCode(0) 271 | proc.stdout.match( 272 | '---\n' + 273 | 'a: "first document"\n' + 274 | 'b: 1\n' + 275 | 'c:\n' + 276 | ' d: true\n' + 277 | '---\n' + 278 | 'x: "second document"\n' + 279 | '"y":\n' + 280 | ' z: false\n' 281 | ) 282 | proc.stderr.match('') 283 | proc.end() 284 | }) 285 | 286 | test('CLI multiple YAML documents --check FAIL', (t) => { 287 | const proc = spawn(t, '../yaml-sort.js --input test-multiple-unsorted.yml --check --quotingStyle single --forceQuotes', opts) 288 | proc.exitCode(1) 289 | proc.stdout.match('') 290 | proc.stderr.match('\'test-multiple-unsorted.yml\' is not sorted and/or formatted (indent, line width).\n') 291 | proc.end() 292 | }) 293 | 294 | test('CLI multiple YAML documents --check SUCCESS', (t) => { 295 | const proc = spawn(t, '../yaml-sort.js --input test-multiple-sorted.yml --check', opts) 296 | proc.exitCode(0) 297 | proc.stdout.match('') 298 | proc.stderr.match('') 299 | proc.end() 300 | }) 301 | --------------------------------------------------------------------------------