main.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/env node
  2. 'use strict';
  3. const updateNotifier = require('update-notifier');
  4. const getStdin = require('get-stdin');
  5. const meow = require('meow');
  6. const formatterPretty = require('eslint-formatter-pretty');
  7. const semver = require('semver');
  8. const openReport = require('./lib/open-report');
  9. const xo = require('.');
  10. const cli = meow(`
  11. Usage
  12. $ xo [<file|glob> ...]
  13. Options
  14. --init Add XO to your project
  15. --fix Automagically fix issues
  16. --reporter Reporter to use
  17. --env Environment preset [Can be set multiple times]
  18. --global Global variable [Can be set multiple times]
  19. --ignore Additional paths to ignore [Can be set multiple times]
  20. --space Use space indent instead of tabs [Default: 2]
  21. --no-semicolon Prevent use of semicolons
  22. --prettier Conform to Prettier code style
  23. --node-version Range of Node.js version to support
  24. --plugin Include third-party plugins [Can be set multiple times]
  25. --extend Extend defaults with a custom config [Can be set multiple times]
  26. --open Open files with issues in your editor
  27. --quiet Show only errors and no warnings
  28. --extension Additional extension to lint [Can be set multiple times]
  29. --no-esnext Don't enforce ES2015+ rules
  30. --cwd=<dir> Working directory for files
  31. --stdin Validate/fix code from stdin
  32. --stdin-filename Specify a filename for the --stdin option
  33. Examples
  34. $ xo
  35. $ xo index.js
  36. $ xo *.js !foo.js
  37. $ xo --space
  38. $ xo --env=node --env=mocha
  39. $ xo --init --space
  40. $ xo --plugin=react
  41. $ xo --plugin=html --extension=html
  42. $ echo 'const x=true' | xo --stdin --fix
  43. Tips
  44. Put options in package.json instead of using flags so other tools can read it.
  45. `, {
  46. booleanDefault: undefined,
  47. flags: {
  48. init: {
  49. type: 'boolean'
  50. },
  51. fix: {
  52. type: 'boolean'
  53. },
  54. reporter: {
  55. type: 'string'
  56. },
  57. env: {
  58. type: 'string'
  59. },
  60. global: {
  61. type: 'string'
  62. },
  63. ignore: {
  64. type: 'string'
  65. },
  66. space: {
  67. type: 'string'
  68. },
  69. semicolon: {
  70. type: 'boolean'
  71. },
  72. prettier: {
  73. type: 'boolean'
  74. },
  75. nodeVersion: {
  76. type: 'string'
  77. },
  78. plugin: {
  79. type: 'string'
  80. },
  81. extend: {
  82. type: 'string'
  83. },
  84. open: {
  85. type: 'boolean'
  86. },
  87. quiet: {
  88. type: 'boolean'
  89. },
  90. extension: {
  91. type: 'string'
  92. },
  93. esnext: {
  94. type: 'boolean'
  95. },
  96. cwd: {
  97. type: 'string'
  98. },
  99. stdin: {
  100. type: 'boolean'
  101. },
  102. stdinFilename: {
  103. type: 'string',
  104. alias: 'filename'
  105. }
  106. }
  107. });
  108. updateNotifier({pkg: cli.pkg}).notify();
  109. const {input, flags: opts} = cli;
  110. const log = report => {
  111. const reporter = opts.reporter ? xo.getFormatter(opts.reporter) : formatterPretty;
  112. process.stdout.write(reporter(report.results));
  113. process.exit(report.errorCount === 0 ? 0 : 1);
  114. };
  115. // `xo -` => `xo --stdin`
  116. if (input[0] === '-') {
  117. opts.stdin = true;
  118. input.shift();
  119. }
  120. if (opts.nodeVersion) {
  121. if (opts.nodeVersion === 'false') {
  122. opts.engines = false;
  123. } else if (semver.validRange(opts.nodeVersion)) {
  124. opts.engines = {node: opts.nodeVersion};
  125. } else {
  126. console.error('The `node-engine` option must be a valid semver range (for example `>=6`)');
  127. process.exit(1);
  128. }
  129. }
  130. if (opts.init) {
  131. require('xo-init')();
  132. } else if (opts.stdin) {
  133. getStdin().then(str => {
  134. if (opts.fix) {
  135. console.log(xo.lintText(str, opts).results[0].output);
  136. return;
  137. }
  138. if (opts.open) {
  139. console.error('The `open` option is not supported on stdin');
  140. process.exit(1);
  141. }
  142. log(xo.lintText(str, opts));
  143. });
  144. } else {
  145. xo.lintFiles(input, opts).then(report => {
  146. if (opts.fix) {
  147. xo.outputFixes(report);
  148. }
  149. if (opts.open) {
  150. openReport(report);
  151. }
  152. log(report);
  153. });
  154. }