Skip to content

Commit

Permalink
Add input from STDIN
Browse files Browse the repository at this point in the history
Add option for input encoding
  • Loading branch information
ddebin committed Mar 9, 2022
1 parent b0241b9 commit e3ab9a1
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [10.x, 12.x, 14.x, 16.x]

steps:
- uses: actions/checkout@v2
Expand Down
3 changes: 1 addition & 2 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
test/
.github
.idea
.github/
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ This tool is basically a tiny wrapper around [js-yaml](https://github.com/nodeca
Usage: yaml-sort [options]
Options:
--input, -i The YAML file(s) which needs to be sorted [array] [required]
--output, -o The YAML file to output sorted content to [string]
--stdout, -s Output the proposed sort to STDOUT only [boolean] [default: false]
--check, -k Check if the given file(s) is already sorted [boolean] [default: false]
--indent, --id Indentation width to use (in spaces) [number] [default: 2]
--lineWidth, -w Wrap line width [number] [default: 80]
-h, --help Show help [boolean]
--version Show version number [boolean]
-i, --input The YAML file(s) which needs to be sorted [array] [default: "-"]
-o, --output The YAML file to output sorted content to [string]
-s, --stdout Output the proposed sort to STDOUT only [boolean] [default: false]
-k, --check Check if the given file(s) is already sorted [boolean] [default: false]
--indent, --id Indentation width to use (in spaces) [number] [default: 2]
-e, --encoding Input encoding [choices: "ascii", "utf8", "utf16le"] [default: "utf8"]
-w, --lineWidth Wrap line width [number] [default: 80]
-h, --help Show help [boolean]
--version Show version number [boolean]
Examples:
yaml-sort --input config.yml Sorts alphabetically and overwrites the file config.yml.
yaml-sort --input config.yml Sorts alphabetically and overwrites the file config.yml
yaml-sort --input config.yml --lineWidth 100 --stdout Sorts the file config.yml and output result to STDOUT wrapped to 100 columns
yaml-sort --input config.yml --indent 4 --output sorted.yml Indents with 4 spaces and outputs result to file sorted.yml.
yaml-sort --input config.yml --indent 4 --output sorted.yml Indents with 4 spaces and outputs result to file sorted.yml
cat config.yml | yaml-sort Sorts alphabetically from STDIN
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yaml-sort",
"version": "1.1.1",
"version": "1.2.0",
"description": "CLI tool to sort YAML files alphabetically",
"main": "yaml-sort.js",
"scripts": {
Expand Down
Binary file added test/test-utf16le.yml
Binary file not shown.
79 changes: 78 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,31 @@ const test = require('tape')
const spawn = require('tape-spawn')
const opts = { cwd: __dirname }

test('CLI --help', (t) => {
const proc = spawn(t, '../yaml-sort.js -h', opts)
proc.stdout.match(/^Usage:/)
proc.stderr.match('')
proc.exitCode(0)
proc.end()
})

test('CLI w/o arg', (t) => {
const proc = spawn(t, '../yaml-sort.js', opts)
proc.stdout.match('')
proc.exitCode(1)
proc.stderr.match(/Missing required argument: input/)
proc.end()
})

test('CLI w/o arg (STDIN)', (t) => {
const proc = spawn(t, 'cat test.yml | ../yaml-sort.js', opts)
proc.exitCode(0)
proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' +
'b:\n' +
' b: 35\n' +
' c:\n' +
' d: false\n' +
'\n')
proc.stderr.match('')
proc.end()
})

Expand All @@ -22,6 +43,7 @@ test('CLI w/ arg', (t) => {
' c:\n' +
' d: false\n' +
'\n')
proc.stderr.match('')
proc.end()
})

Expand All @@ -36,6 +58,22 @@ test('CLI --output', (t) => {
' b: 35\n' +
' c:\n' +
' d: false\n')
proc.stderr.match('')
proc.end()
})

test('CLI --output (STDIN)', (t) => {
const proc = spawn(t,
'cat test.yml | ../yaml-sort.js --input - --output output.yml' +
' && cat output.yml' +
' && rm -f output.yml', opts)
proc.exitCode(0)
proc.stdout.match('a: Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n' +
'b:\n' +
' b: 35\n' +
' c:\n' +
' d: false\n')
proc.stderr.match('')
proc.end()
})

Expand All @@ -48,6 +86,7 @@ test('CLI --indent', (t) => {
' c:\n' +
' d: false\n' +
'\n')
proc.stderr.match('')
proc.end()
})

Expand All @@ -62,6 +101,7 @@ test('CLI --lineWidth', (t) => {
' c:\n' +
' d: false\n' +
'\n')
proc.stderr.match('')
proc.end()
})

Expand All @@ -79,6 +119,24 @@ test('CLI --check SUCCESS', (t) => {
'../yaml-sort.js --input sorted.yml --check', opts)
proc.exitCode(0)
proc.stdout.match('')
proc.stderr.match('')
proc.end()
})

test('CLI --encoding FAIL', (t) => {
const proc = spawn(t,
'../yaml-sort.js --input test-utf16le.yml --stdout', opts)
proc.exitCode(1)
proc.stdout.match('')
proc.stderr.match(/null byte is not allowed in input/)
proc.end()
})

test('CLI --encoding SUCCESS', (t) => {
const proc = spawn(t,
'../yaml-sort.js --input test-utf16le.yml --stdout --encoding utf16le', opts)
proc.exitCode(0)
proc.stderr.match('')
proc.end()
})

Expand All @@ -89,5 +147,24 @@ test('CLI --lineWidth SUCCESS', (t) => {
' && rm -f output.yml', opts)
proc.exitCode(0)
proc.stdout.match('')
proc.stderr.match('')
proc.end()
})

test('CLI --output --stdout FAIL', (t) => {
const proc = spawn(t,
'../yaml-sort.js --input test.yml --stdout --output output.yml', opts)
proc.exitCode(1)
proc.stdout.match('')
proc.stderr.match(/Arguments stdout and output are mutually exclusive/)
proc.end()
})

test('CLI --check --stdout FAIL', (t) => {
const proc = spawn(t,
'../yaml-sort.js --input test.yml --check --stdout', opts)
proc.exitCode(1)
proc.stdout.match('')
proc.stderr.match(/Arguments check and stdout are mutually exclusive/)
proc.end()
})
58 changes: 35 additions & 23 deletions yaml-sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@

'use strict'

const argv = require('yargs')
const fs = require('fs')
const yaml = require('js-yaml')
const yargs = require('yargs')

const argv = yargs
.usage('Usage: $0 [options]')
.example(
'$0 --input config.yml',
'Sorts alphabetically and overwrites the file config.yml'
)
.example(
'$0 --input config.yml --lineWidth 100 --stdout',
'Sorts the file config.yml and output result to STDOUT wrapped to 100 columns'
)
.example(
'$0 --input config.yml --indent 4 --output sorted.yml',
'Indents with 4 spaces and outputs result to file sorted.yml'
)
.example([
['$0 --input config.yml',
'Sorts alphabetically and overwrites the file config.yml'],
['$0 --input config.yml --lineWidth 100 --stdout',
'Sorts the file config.yml and output result to STDOUT wrapped to 100 columns'],
['$0 --input config.yml --indent 4 --output sorted.yml',
'Indents with 4 spaces and outputs result to file sorted.yml'],
['cat config.yml | $0',
'Sorts alphabetically from STDIN']
])
.option('input', {
alias: 'i',
describe: 'The YAML file(s) which needs to be sorted',
demandOption: 'Please provide an input file',
default: '-',
string: true,
array: true
})
Expand All @@ -30,14 +32,14 @@ const argv = require('yargs')
})
.option('stdout', {
alias: 's',
default: false,
describe: 'Output the proposed sort to STDOUT only',
conflicts: 'output',
boolean: true
})
.option('check', {
alias: 'k',
default: false,
describe: 'Check if the given file(s) is already sorted',
conflicts: ['output', 'stdout'],
boolean: true
})
.option('indent', {
Expand All @@ -46,27 +48,36 @@ const argv = require('yargs')
describe: 'Indentation width to use (in spaces)',
number: true
})
.option('encoding', {
alias: 'e',
default: 'utf8',
describe: 'Input encoding',
choices: ['ascii', 'utf8', 'utf16le']
})
.option('lineWidth', {
alias: 'w',
default: 80,
describe: 'Wrap line width',
number: true
})
.demandOption(['input'])
.help('h')
.alias('h', 'help')
.version()
.wrap(null)
.argv

const yaml = require('js-yaml')
const fs = require('fs')

let success = true

argv.input.forEach((file) => {
try {
const content = fs.readFileSync(file, 'utf8')
const isStdin = file === '-'

if (isStdin && process.stdin.isTTY) {
yargs.showHelp()
process.exit(22)
}

const content = fs.readFileSync(isStdin ? process.stdin.fd : file, argv.encoding)

const sorted = yaml.dump(yaml.load(content), {
sortKeys: true,
Expand All @@ -79,15 +90,16 @@ argv.input.forEach((file) => {
success = false
console.warn(`'${file}' is not sorted and/or formatted (indent, line width).`)
}
} else if (argv.stdout) {
} else if (argv.stdout || (isStdin && !argv.output)) {
console.log(sorted)
} else {
fs.writeFile(
argv.output ? argv.output : file,
sorted,
(error) => {
if (error) {
return console.error(error)
success = false
console.error(error)
}
})
}
Expand Down

0 comments on commit e3ab9a1

Please sign in to comment.