.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / cli.js
1 /* @flow */
2 "use strict";
3 const dynamicRequire = require("./dynamicRequire");
4 const getModulePath = require("./utils/getModulePath");
5 const getStdin = require("get-stdin");
6 const meow = require("meow");
7 const needlessDisablesStringFormatter = require("./formatters/needlessDisablesStringFormatter");
8 const path = require("path");
9 const resolveFrom = require("resolve-from");
10 const standalone = require("./standalone");
11
12 /*:: type meowOptionsType = {
13   autoHelp: boolean,
14   autoVersion: boolean,
15   help: string,
16   flags: {
17     "allow-empty-input": {
18       alias: string,
19       type: string
20     },
21     cache: {
22       type: string
23     },
24     "cache-location": {
25       type: string
26     },
27     config: {
28       default: boolean,
29       type: string
30     },
31     "config-basedir": {
32       type: string
33     },
34     color: {
35       type: string
36     },
37     "custom-formatter": {
38       type: string
39     },
40     "custom-syntax": {
41       type: string
42     },
43     "disable-default-ignores": {
44       alias: string,
45       type: string
46     },
47     fix: {
48       type: string
49     },
50     formatter: {
51       alias: string,
52       default: "string",
53       type: string
54     },
55     help: {
56       alias: string,
57       type: string
58     },
59     "ignore-disables": {
60       alias: string,
61       type: string
62     },
63     "ignore-path": {
64       alias: string
65     },
66     "ignore-pattern": {
67       alias: string
68     },
69     "no-color": {
70       type: string
71     },
72     "report-needless-disables": {
73       alias: string
74     },
75     "stdin-filename": {
76       type: string
77     },
78     quiet: {
79       alias: string,
80       type: string,
81       default: boolean
82     },
83     syntax: {
84       alias: string
85     },
86     version: {
87       alias: string,
88       type: string
89     }
90   },
91   pkg: string,
92 } */
93
94 /*:: type cliType = {
95   flags: {
96     allowEmptyInput: any,
97     cache: any,
98     cacheLocation: any,
99     config: any,
100     configBasedir: any,
101     customFormatter: any,
102     customSyntax: any,
103     fix: any,
104     formatter: any,
105     ignoreDisables: any,
106     ignorePath: string,
107     quiet: any,
108     reportNeedlessDisables: any,
109     stdinFilename: any,
110     syntax: any,
111   },
112   input: any,
113   help: any,
114   pkg: any,
115   showHelp: Function,
116   showVersion: Function
117 }*/
118
119 /*:: type optionBaseType = {
120   allowEmptyInput?: any,
121   formater?: any,
122   cache?: boolean,
123   cacheLocation?: any,
124   codeFilename?: any,
125   configBasedir?: any,
126   configFile?: any,
127   configOverrides: {
128     quiet?: any,
129   },
130   customSyntax?: any,
131   fix?: any,
132   ignoreDisables?: any,
133   ignorePath?: any,
134   reportNeedlessDisables?: any,
135   syntax?: any,
136   disableDefaultIgnores?: any,
137   ignorePattern?: any
138 }*/
139
140 const meowOptions /*: meowOptionsType*/ = {
141   autoHelp: false,
142   autoVersion: false,
143   help: `
144     Usage: stylelint [input] [options]
145
146     Input: Files(s), glob(s), or nothing to use stdin.
147
148       If an input argument is wrapped in quotation marks, it will be passed to
149       node-glob for cross-platform glob support. node_modules and
150       bower_components are always ignored. You can also pass no input and use
151       stdin, instead.
152
153     Options:
154
155       --config
156
157         Path to a specific configuration file (JSON, YAML, or CommonJS), or the
158         name of a module in node_modules that points to one. If no --config
159         argument is provided, stylelint will search for configuration files in
160         the following places, in this order:
161           - a stylelint property in package.json
162           - a .stylelintrc file (with or without filename extension:
163             .json, .yaml, .yml, and .js are available)
164           - a stylelint.config.js file exporting a JS object
165         The search will begin in the working directory and move up the directory
166         tree until a configuration file is found.
167
168       --config-basedir
169
170         An absolute path to the directory that relative paths defining "extends"
171         and "plugins" are *relative to*. Only necessary if these values are
172         relative paths.
173
174       --ignore-path, -i
175
176         Path to a file containing patterns that describe files to ignore. The
177         path can be absolute or relative to process.cwd(). By default, stylelint
178         looks for .stylelintignore in process.cwd().
179
180       --ignore-pattern, -ip
181
182         Pattern of files to ignore (in addition to those in .stylelintignore)
183
184       --syntax, -s
185
186         Specify a non-standard syntax. Options: "scss", "less", "sugarss".
187         If you do not specify a syntax, non-standard syntaxes will be
188         automatically inferred by the file extensions .scss, .less, and .sss.
189
190       --fix
191
192         Automatically fix violations of certain rules.
193
194       --custom-syntax
195
196         Module name or path to a JS file exporting a PostCSS-compatible syntax.
197
198       --stdin-filename
199
200         A filename to assign stdin input.
201
202       --ignore-disables, --id
203
204         Ignore styleline-disable comments.
205
206       --disable-default-ignores, --di
207
208         Allow linting of node_modules and bower_components.
209
210       --cache                       [default: false]
211
212         Store the info about processed files in order to only operate on the
213         changed ones the next time you run stylelint. By default, the cache
214         is stored in "./.stylelintcache". To adjust this, use --cache-location.
215
216       --cache-location              [default: '.stylelintcache']
217
218         Path to a file or directory to be used for the cache location.
219         Default is "./.stylelintcache". If a directory is specified, a cache
220         file will be created inside the specified folder, with a name derived
221         from a hash of the current working directory.
222
223         If the directory for the cache does not exist, make sure you add a trailing "/"
224         on *nix systems or "\\" on Windows. Otherwise the path will be assumed to be a file.
225
226       --formatter, -f               [default: "string"]
227
228         The output formatter: "json", "string" or "verbose".
229
230       --custom-formatter
231
232         Path to a JS file exporting a custom formatting function.
233
234       --quiet, -q
235
236         Only register warnings for rules with an "error"-level severity (ignore
237         "warning"-level).
238
239       --color
240       --no-color
241
242         Force enabling/disabling of color.
243
244       --allow-empty-input, --aei
245
246         If no files match glob pattern, exits without throwing an error.
247
248       --report-needless-disables, --rd
249
250         Report stylelint-disable comments that are not blocking a lint warning.
251         If you provide the argument "error", the process will exit with code 2
252         if needless disables are found.
253
254       --version, -v
255
256         Show the currently installed version of stylelint.
257   `,
258   flags: {
259     "allow-empty-input": {
260       alias: "aei",
261       type: "boolean"
262     },
263     cache: {
264       type: "boolean"
265     },
266     "cache-location": {
267       type: "string"
268     },
269     config: {
270       default: false,
271       type: "string"
272     },
273     "config-basedir": {
274       type: "string"
275     },
276     color: {
277       type: "boolean"
278     },
279     "custom-formatter": {
280       type: "string"
281     },
282     "custom-syntax": {
283       type: "string"
284     },
285     "disable-default-ignores": {
286       alias: "di",
287       type: "boolean"
288     },
289     fix: {
290       type: "boolean"
291     },
292     formatter: {
293       alias: "f",
294       default: "string",
295       type: "string"
296     },
297     help: {
298       alias: "h",
299       type: "boolean"
300     },
301     "ignore-disables": {
302       alias: "id",
303       type: "boolean"
304     },
305     "ignore-path": {
306       alias: "i"
307     },
308     "ignore-pattern": {
309       alias: "ip"
310     },
311     "no-color": {
312       type: "boolean"
313     },
314     "report-needless-disables": {
315       alias: "rd"
316     },
317     "stdin-filename": {
318       type: "string"
319     },
320     quiet: {
321       alias: "q",
322       type: "boolean",
323       default: false
324     },
325     syntax: {
326       alias: "s"
327     },
328     version: {
329       alias: "v",
330       type: "boolean"
331     }
332   },
333   pkg: require("../package.json")
334 };
335
336 const cli /*: cliType*/ = meow(meowOptions);
337
338 let formatter = cli.flags.formatter;
339 if (cli.flags.customFormatter) {
340   const customFormatter = path.isAbsolute(cli.flags.customFormatter)
341     ? cli.flags.customFormatter
342     : path.join(process.cwd(), cli.flags.customFormatter);
343   formatter = dynamicRequire(customFormatter);
344 }
345
346 const optionsBase /*: optionBaseType*/ = {
347   formatter,
348   configOverrides: {}
349 };
350
351 if (cli.flags.quiet) {
352   optionsBase.configOverrides.quiet = cli.flags.quiet;
353 }
354
355 if (cli.flags.syntax) {
356   optionsBase.syntax = cli.flags.syntax;
357 }
358
359 if (cli.flags.customSyntax) {
360   optionsBase.customSyntax = getModulePath(
361     process.cwd(),
362     cli.flags.customSyntax
363   );
364 }
365
366 if (cli.flags.config) {
367   // Should check these possibilities:
368   //   a. name of a node_module
369   //   b. absolute path
370   //   c. relative path relative to `process.cwd()`.
371   // If none of the above work, we'll try a relative path starting
372   // in `process.cwd()`.
373   optionsBase.configFile =
374     resolveFrom.silent(process.cwd(), cli.flags.config) ||
375     path.join(process.cwd(), cli.flags.config);
376 }
377
378 if (cli.flags.configBasedir) {
379   optionsBase.configBasedir = path.isAbsolute(cli.flags.configBasedir)
380     ? cli.flags.configBasedir
381     : path.resolve(process.cwd(), cli.flags.configBasedir);
382 }
383
384 if (cli.flags.stdinFilename) {
385   optionsBase.codeFilename = cli.flags.stdinFilename;
386 }
387
388 if (cli.flags.ignorePath) {
389   optionsBase.ignorePath = cli.flags.ignorePath;
390 }
391
392 if (cli.flags.ignorePattern) {
393   optionsBase.ignorePattern = cli.flags.ignorePattern;
394 }
395
396 if (cli.flags.ignoreDisables) {
397   optionsBase.ignoreDisables = cli.flags.ignoreDisables;
398 }
399
400 if (cli.flags.disableDefaultIgnores) {
401   optionsBase.disableDefaultIgnores = cli.flags.disableDefaultIgnores;
402 }
403
404 if (cli.flags.cache) {
405   optionsBase.cache = true;
406 }
407
408 if (cli.flags.cacheLocation) {
409   optionsBase.cacheLocation = cli.flags.cacheLocation;
410 }
411
412 if (cli.flags.fix) {
413   optionsBase.fix = cli.flags.fix;
414 }
415
416 const reportNeedlessDisables = cli.flags.reportNeedlessDisables;
417
418 if (reportNeedlessDisables) {
419   optionsBase.reportNeedlessDisables = reportNeedlessDisables;
420 }
421
422 if (cli.flags.help || cli.flags.h) {
423   cli.showHelp();
424 }
425
426 if (cli.flags.version || cli.flags.v) {
427   cli.showVersion();
428 }
429
430 Promise.resolve()
431   .then(() => {
432     // Add input/code into options
433     if (cli.input.length) {
434       return Object.assign({}, optionsBase, {
435         files: cli.input
436       });
437     }
438     return getStdin().then(stdin =>
439       Object.assign({}, optionsBase, {
440         code: stdin
441       })
442     );
443   })
444   .then(options => {
445     if (!options.files && !options.code) {
446       cli.showHelp();
447     }
448
449     return standalone(options);
450   })
451   .then(linted => {
452     if (reportNeedlessDisables) {
453       const hasReportNeedlessDisable =
454         !!linted.needlessDisables &&
455         linted.needlessDisables.some(sourceReport => {
456           if (!sourceReport.ranges || sourceReport.ranges.length === 0) {
457             return false;
458           }
459
460           return true;
461         });
462
463       if (hasReportNeedlessDisable) {
464         process.stdout.write(
465           needlessDisablesStringFormatter(linted.needlessDisables)
466         );
467         process.exitCode = 2;
468       }
469
470       return;
471     }
472
473     if (!linted.output) {
474       return;
475     }
476     process.stdout.write(linted.output);
477     if (linted.errored) {
478       process.exitCode = 2;
479     }
480     return;
481   })
482   .catch((err /*: { stack: any, code: any }*/) => {
483     console.log(err.stack); // eslint-disable-line no-console
484     const exitCode = typeof err.code === "number" ? err.code : 1;
485     process.exit(exitCode); // eslint-disable-line no-process-exit
486   });