Skip to content

Commit cc3f696

Browse files
committed
BREAKING: Revamp args parsing
- Remove extra aliases -x, -p, -s, -t, -e, -b, & -c - Better usage text - Split opts into groups in the --help message - Way stricter opts parsing to prevent stupid combinations of options Fixes #166; Fixes #126
1 parent f0af2e4 commit cc3f696

7 files changed

Lines changed: 98 additions & 83 deletions

File tree

README.md

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,56 +22,58 @@ npm i -g|-D postcss-cli
2222

2323
<h2 align="center">Usage</h2>
2424

25-
```bash
26-
postcss [input.css] [OPTIONS] [-o|--output output.css] [-w|--watch]
2725
```
26+
Usage:
27+
postcss [input.css] [OPTIONS] [-o|--output output.css] [--watch|-w]
28+
postcss <input.css>... [OPTIONS] --dir <output-directory> [--watch|-w]
29+
postcss <input.css>... [OPTIONS] --replace
30+
31+
Basic options:
32+
-o, --output Output file [string]
33+
-d, --dir Output directory [string]
34+
-r, --replace Replace (overwrite) the input file [boolean]
35+
--map, -m Create an external sourcemap
36+
--no-map Disable the default inline sourcemaps
37+
--watch, -w Watch files for changes and recompile as needed [boolean]
38+
--env A shortcut for setting NODE_ENV [string]
39+
40+
Options for when not using a config file:
41+
-u, --use List of postcss plugins to use [array]
42+
--parser Custom postcss parser [string]
43+
--stringifier Custom postcss stringifier [string]
44+
--syntax Custom postcss syntax [string]
45+
46+
Advanced options:
47+
--ext Override the output file extension; for use with --dir [string]
48+
--base Mirror the directory structure relative to this path in the output
49+
directory, for use with --dir [string]
50+
--poll Use polling for file watching. Can optionally pass polling interval;
51+
default 100 ms
52+
--config Set a custom path to look for a config file [string]
53+
54+
Options:
55+
-v, --version Show version number [boolean]
56+
-h, --help Show help [boolean]
57+
58+
Examples:
59+
postcss input.css -o output.css Basic usage
60+
cat input.css | postcss -u autoprefixer > output.css Piping input & output
61+
62+
If no input files are passed, it reads from stdin. If neither -o, --dir, or
63+
--replace is passed, it writes to stdout.
2864
29-
The input may also be a glob:
30-
31-
```bash
32-
postcss "src/*.css" [OPTIONS]
65+
If there are multiple input files, the --dir or --replace option must be passed.
66+
Input files may contain globs.
3367
```
3468

35-
Recursively read a directory:
36-
37-
```bash
38-
postcss "src/**/*.css" [OPTIONS]
39-
```
69+
> ℹ️ More details on custom parsers, stringifiers and syntaxes, can be found [here](https://github.com/postcss/postcss#syntaxes).
4070
41-
> ⚠️ If there are multiple input files, the --dir or --replace option must be passed.
71+
To recursively read a directory, you'd do:
4272

4373
```bash
44-
cat input.css | postcss [OPTIONS] > output.css
74+
postcss "src/**/*.css" [OPTIONS]
4575
```
4676

47-
> ⚠️ If no input files are passed, it reads from stdin. If neither -o, --dir, or
48-
--replace is passed, it writes to stdout.
49-
50-
<h2 align="center">Options</h2>
51-
52-
|Name|Type|Default|Description|
53-
|:---|:--:|:-----:|:----------|
54-
|`-d, --dir`|`{String}`|`undefined`|Output Directory|
55-
|`-b, --base`|`{String}`|`undefined`|Use together with `--dir` for keeping directory structure.|
56-
|`-x, --ext`|`{String}`|`extname(output)`|Output File Extension|
57-
|`-o, --output`|`{String}`|`undefined`|Output File|
58-
|`-r, --replace`|`{String}`|`undefined`|Replace Input <=> Output|
59-
|`-p, --parser`|`{String}`|`undefined`|Custom PostCSS Parser|
60-
|`-s, --syntax`|`{String}`|`undefined`|Custom PostCSS Syntax|
61-
|`-t, --stringifier`|`{String}`|`undefined`|Custom PostCSS Stringifier|
62-
|`-w, --watch`|`{Boolean}`|`false`|Enable Watch Mode|
63-
|`--poll`|`{Boolean\|Number}`|`100`|Use polling for file watching. Can optionally pass polling interval; default 100 ms|
64-
|`-u, --use`|`{Array}`|`[]`|PostCSS Plugins|
65-
|`-m, --map`|`{Boolean}`|`{ inline: true }`|External Sourcemaps|
66-
|`--no-map`|`{Boolean}`|`false`|Disable Sourcemaps|
67-
|`-e, --env`|`{String}`|`process.env.NODE_ENV`|Sets `$NODE_ENV`|
68-
|`-c, --config`|`{String}`|`dirname(file)`|PostCSS Config Path `postcss.config.js`|
69-
|`-h, --help`|`{Boolean}`|`false`|CLI Help|
70-
|`-v, --version`|`{Boolean}`|`false`|CLI Version|
71-
72-
73-
> ℹ️ More details on custom parsers, stringifiers and syntaxes, can be found [here](https://github.com/postcss/postcss#syntaxes).
74-
7577
### [Config](https://github.com/michael-ciniawsky/postcss-load-config)
7678

7779
If you need to pass options to your plugins, or have a long plugin chain, you'll want to use a configuration file.

lib/args.js

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,81 +30,94 @@ module.exports = require('yargs')
3030
.usage(
3131
`${chalk.bold.red(logo)}
3232
Usage:
33-
34-
$0 [input.css] [OPTIONS] [--output|-o output.css] [--watch]`
33+
$0 [input.css] [OPTIONS] [-o|--output output.css] [--watch|-w]
34+
$0 <input.css>... [OPTIONS] --dir <output-directory> [--watch|-w]
35+
$0 <input.css>... [OPTIONS] --replace`
3536
)
37+
.group(['o', 'd', 'r', 'map', 'no-map', 'watch', 'env'], 'Basic options:')
3638
.option('o', {
3739
alias: 'output',
3840
desc: 'Output file',
39-
type: 'string'
41+
type: 'string',
42+
conflicts: ['dir', 'replace']
4043
})
4144
.option('d', {
4245
alias: 'dir',
4346
desc: 'Output directory',
44-
type: 'string'
47+
type: 'string',
48+
conflicts: ['output', 'replace']
4549
})
4650
.option('r', {
4751
alias: 'replace',
4852
desc: 'Replace (overwrite) the input file',
49-
type: 'boolean'
53+
type: 'boolean',
54+
// HACK: conflicts doesn't work with boolean opts correctly, so we do this
55+
// See https://github.com/yargs/yargs/issues/929
56+
coerce: v => v || undefined,
57+
conflicts: ['output', 'dir']
58+
})
59+
.alias('map', 'm')
60+
.describe('map', 'Create an external sourcemap')
61+
.describe('no-map', 'Disable the default inline sourcemaps')
62+
.option('watch', {
63+
alias: 'w',
64+
desc: 'Watch files for changes and recompile as needed',
65+
type: 'boolean',
66+
// HACK: conflicts doesn't work with boolean opts correctly, so we do this
67+
// See https://github.com/yargs/yargs/issues/929
68+
coerce: v => v || undefined,
69+
conflicts: 'replace'
70+
})
71+
.option('env', {
72+
desc: 'A shortcut for setting NODE_ENV',
73+
type: 'string'
5074
})
75+
.group(
76+
['u', 'parser', 'stringifier', 'syntax'],
77+
'Options for when not using a config file:'
78+
)
5179
.option('u', {
5280
alias: 'use',
5381
desc: 'List of postcss plugins to use',
5482
type: 'array'
5583
})
56-
.option('p', {
57-
alias: 'parser',
84+
.option('parser', {
5885
desc: 'Custom postcss parser',
5986
type: 'string'
6087
})
61-
.option('t', {
62-
alias: 'stringifier',
88+
.option('stringifier', {
6389
desc: 'Custom postcss stringifier',
6490
type: 'string'
6591
})
66-
.option('s', {
67-
alias: 'syntax',
92+
.option('syntax', {
6893
desc: 'Custom postcss syntax',
6994
type: 'string'
7095
})
71-
.option('w', {
72-
alias: 'watch',
73-
desc: 'Watch files for changes and recompile as needed',
74-
type: 'boolean'
75-
})
76-
.option('poll', {
77-
desc:
78-
'Use polling for file watching. Can optionally pass polling interval; default 100 ms'
79-
})
80-
.option('x', {
81-
alias: 'ext',
82-
desc: 'Override the output file extension',
96+
.group(['ext', 'base', 'poll', 'config'], 'Advanced options:')
97+
.option('ext', {
98+
desc: 'Override the output file extension; for use with --dir',
8399
type: 'string',
100+
implies: 'dir',
84101
coerce(ext) {
85102
if (ext.indexOf('.') !== 0) return `.${ext}`
86103
return ext
87104
}
88105
})
89-
.option('e', {
90-
alias: 'env',
91-
desc: 'A shortcut for setting NODE_ENV',
92-
type: 'string'
106+
.option('base', {
107+
desc:
108+
'Mirror the directory structure relative to this path in the output directory, for use with --dir',
109+
type: 'string',
110+
implies: 'dir'
93111
})
94-
.option('b', {
95-
alias: 'base',
112+
.option('poll', {
96113
desc:
97-
'Mirror the directory structure relative to this path in the output directory, this only works together with --dir',
98-
type: 'string'
114+
'Use polling for file watching. Can optionally pass polling interval; default 100 ms',
115+
implies: 'watch'
99116
})
100-
.option('c', {
101-
alias: 'config',
117+
.option('config', {
102118
desc: 'Set a custom path to look for a config file',
103119
type: 'string'
104120
})
105-
.alias('m', 'map')
106-
.describe('m', 'Create an external sourcemap')
107-
.describe('no-map', 'Disable the default inline sourcemaps')
108121
.version(version)
109122
.alias('v', 'version')
110123
.alias('h', 'help')
@@ -116,7 +129,7 @@ Usage:
116129
.epilog(
117130
`If no input files are passed, it reads from stdin. If neither -o, --dir, or --replace is passed, it writes to stdout.
118131
119-
If there are multiple input files, the --dir or --replace option must be passed.
132+
If there are multiple input files, the --dir or --replace option must be passed. Input files may contain globs.
120133
121134
For more details, please see https://github.com/postcss/postcss-cli`
122135
).argv

test/error.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ test('PluginError', t => {
5353
})
5454

5555
test('CssSyntaxError', t => {
56-
return cli(['test/fixtures/a.css', '-p', 'sugarss', '-o', tmp()]).then(
56+
return cli(['test/fixtures/a.css', '--parser', 'sugarss', '-o', tmp()]).then(
5757
({ err, code }) => {
5858
t.is(code, 1, 'expected non-zero error code')
5959
t.regex(err.toString(), /\[1:4] Unnecessary curly bracket/)

test/parser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('--parser works', async t => {
99

1010
const { error, stderr } = await cli([
1111
'test/fixtures/a.sss',
12-
'-p',
12+
'--parser',
1313
'sugarss',
1414
'-o',
1515
output,

test/stdout.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import read from './helpers/read.js'
99
test.cb('writes to stdout', t => {
1010
const cp = execFile(
1111
path.resolve('bin/postcss'),
12-
['-p', 'sugarss', '-u', 'postcss-import', '--no-map'],
12+
['--parser', 'sugarss', '-u', 'postcss-import', '--no-map'],
1313
(error, stdout, stderr) => {
1414
if (error) t.end(error, stderr)
1515

test/stringifier.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('--stringifier works', async t => {
99

1010
const { error, stderr } = await cli([
1111
'test/fixtures/a.css',
12-
'-t',
12+
'--stringifier',
1313
'sugarss',
1414
'-o',
1515
output,

test/syntax.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('--syntax works', async t => {
99

1010
const { error, stderr } = await cli([
1111
'test/fixtures/a.sss',
12-
'-s',
12+
'--syntax',
1313
'sugarss',
1414
'-o',
1515
output,

0 commit comments

Comments
 (0)