Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: xojs/xo
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a3261c7389e6c10ba6be5a834203599114ba0565
Choose a base ref
...
head repository: xojs/xo
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 41f0484a337bb53d3075194223a1d69eae6c05b2
Choose a head ref
Loading
Showing with 4,512 additions and 753 deletions.
  1. +1 −4 .editorconfig
  2. +1 −1 .gitattributes
  3. +26 −0 .github/workflows/main.yml
  4. +5 −0 .gitignore
  5. +1 −0 .npmrc
  6. +0 −5 .travis.yml
  7. +222 −0 cli-main.js
  8. +9 −80 cli.js
  9. +73 −0 code-of-conduct.md
  10. +5 −0 config/overrides.js
  11. +371 −0 config/plugins.js
  12. +41 −0 contributing.md
  13. +154 −105 index.js
  14. +153 −0 lib/constants.js
  15. +44 −0 lib/open-report.js
  16. +620 −0 lib/options-manager.js
  17. +5 −17 license
  18. +300 −289 media/logo.ai
  19. +132 −82 package.json
  20. +326 −104 readme.md
  21. +0 −56 test/api.js
  22. +182 −0 test/cli-main.js
  23. +7 −10 test/cli.js
  24. +3 −0 test/fixtures/config-files/xo-config/.xo-config
  25. +5 −0 test/fixtures/config-files/xo-config/file.js
  26. +3 −0 test/fixtures/config-files/xo-config_cjs/.xo-config.cjs
  27. +5 −0 test/fixtures/config-files/xo-config_cjs/file.js
  28. +3 −0 test/fixtures/config-files/xo-config_js/.xo-config.js
  29. +5 −0 test/fixtures/config-files/xo-config_js/file.js
  30. +3 −0 test/fixtures/config-files/xo-config_json/.xo-config.json
  31. +5 −0 test/fixtures/config-files/xo-config_json/file.js
  32. +5 −0 test/fixtures/config-files/xo_config_cjs/file.js
  33. +3 −0 test/fixtures/config-files/xo_config_cjs/xo.config.cjs
  34. +5 −0 test/fixtures/config-files/xo_config_js/file.js
  35. +3 −0 test/fixtures/config-files/xo_config_js/xo.config.js
  36. +3 −0 test/fixtures/custom-extension/one-space.unknown
  37. +1 −0 test/fixtures/cwd/unicorn.js
  38. +5 −0 test/fixtures/default-options/package.json
  39. +15 −0 test/fixtures/engines-overrides/package.json
  40. +7 −0 test/fixtures/engines-overrides/promise-then-transpile.js
  41. +7 −0 test/fixtures/engines-overrides/promise-then.js
  42. +7 −0 test/fixtures/engines/package.json
  43. +1 −0 test/fixtures/eslintignore/.eslintignore
  44. +1 −0 test/fixtures/eslintignore/bar.js
  45. +1 −0 test/fixtures/eslintignore/foo.js
  46. +6 −0 test/fixtures/extends.js
  47. +1 −0 test/fixtures/gitignore-multiple-negation/!!!unicorn.js
  48. +1 −0 test/fixtures/gitignore-multiple-negation/!!unicorn.js
  49. +1 −0 test/fixtures/gitignore-multiple-negation/!unicorn.js
  50. +3 −0 test/fixtures/gitignore-multiple-negation/.gitignore
  51. +1 −0 test/fixtures/gitignore-multiple-negation/unicorn.js
  52. +5 −0 test/fixtures/gitignore/index.js
  53. +2 −0 test/fixtures/gitignore/test/.gitignore
  54. +6 −0 test/fixtures/gitignore/test/bar.js
  55. +6 −0 test/fixtures/gitignore/test/foo.js
  56. +9 −0 test/fixtures/ignores/dist/linter-error.js
  57. +5 −0 test/fixtures/ignores/index.js
  58. +13 −0 test/fixtures/ignores/package.json
  59. +2 −0 test/fixtures/negative-gitignore/.gitignore
  60. +1 −0 test/fixtures/negative-gitignore/bar.js
  61. +1 −0 test/fixtures/negative-gitignore/foo.js
  62. +3 −0 test/fixtures/nested-configs/child-override/.prettierrc
  63. +10 −0 test/fixtures/nested-configs/child-override/child-prettier-override/package.json
  64. +1 −0 test/fixtures/nested-configs/child-override/child-prettier-override/semicolon.js
  65. +10 −0 test/fixtures/nested-configs/child-override/package.json
  66. +3 −0 test/fixtures/nested-configs/child-override/two-spaces.js
  67. +5 −0 test/fixtures/nested-configs/child/package.json
  68. +1 −0 test/fixtures/nested-configs/child/semicolon.js
  69. +1 −0 test/fixtures/nested-configs/no-semicolon.js
  70. +5 −0 test/fixtures/nested-configs/package.json
  71. +3 −0 test/fixtures/nested/child-empty/package.json
  72. +1 −0 test/fixtures/nested/child-ignore/package.json
  73. +5 −0 test/fixtures/nested/child/package.json
  74. +2 −0 test/fixtures/nested/file.js
  75. +5 −0 test/fixtures/nested/package.json
  76. +1 −0 test/fixtures/nodir/nested/index.js
  77. +1 −0 test/fixtures/nodir/noextension
  78. +1 −0 test/fixtures/open-report/errors/one.js
  79. +1 −0 test/fixtures/open-report/errors/three.js
  80. +2 −0 test/fixtures/open-report/errors/two-with-warnings.js
  81. +1 −0 test/fixtures/open-report/successes/success.js
  82. +1 −0 test/fixtures/open-report/warnings/one.js
  83. +3 −0 test/fixtures/open-report/warnings/three.js
  84. +5 −0 test/fixtures/overrides/index.js
  85. +22 −0 test/fixtures/overrides/package.json
  86. +6 −0 test/fixtures/overrides/test/bar.js
  87. +6 −0 test/fixtures/overrides/test/foo.js
  88. +11 −0 test/fixtures/prettier/package.json
  89. +2 −0 test/fixtures/project/file.js
  90. +5 −0 test/fixtures/project/node_modules/eslint-config-custom/config.json
  91. +4 −0 test/fixtures/project/node_modules/eslint-config-custom/package.json
  92. +5 −0 test/fixtures/project/package.json
  93. +3 −0 test/fixtures/space/one-space.js
  94. +3 −0 test/fixtures/space/two-spaces.js
  95. +1 −0 test/fixtures/typescript/child/extra-semicolon.ts
  96. +1 −0 test/fixtures/typescript/child/no-semicolon.ts
  97. +5 −0 test/fixtures/typescript/child/package.json
  98. +3 −0 test/fixtures/typescript/child/sub-child/four-spaces.ts
  99. +5 −0 test/fixtures/typescript/child/sub-child/package.json
  100. +6 −0 test/fixtures/typescript/child/tsconfig.json
  101. +5 −0 test/fixtures/typescript/package.json
  102. +3 −0 test/fixtures/typescript/two-spaces.tsx
  103. +2 −0 test/fixtures/webpack/no-config/file1.js
  104. +2 −0 test/fixtures/webpack/no-config/file2.js
  105. +1 −0 test/fixtures/webpack/no-config/file3.js
  106. +2 −0 test/fixtures/webpack/with-config/file1.js
  107. +2 −0 test/fixtures/webpack/with-config/file2.js
  108. +9 −0 test/fixtures/webpack/with-config/webpack.config.js
  109. +285 −0 test/lint-files.js
  110. +331 −0 test/lint-text.js
  111. +93 −0 test/open-report.js
  112. +755 −0 test/options-manager.js
  113. +26 −0 test/print-config.js
5 changes: 1 addition & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -7,9 +7,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[{package.json,*.yml}]
[*.yml]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
* text=auto
* text=auto eol=lf
*.ai binary
26 changes: 26 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI
on:
- push
- pull_request
jobs:
test:
name: Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
- uses: codecov/codecov-action@v1
if: matrix.node-version == 14
with:
fail_ci_if_error: true
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
node_modules
yarn.lock
!test/fixtures/project/node_modules
test/fixtures/project/node_modules/.cache
.nyc_output
coverage
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
5 changes: 0 additions & 5 deletions .travis.yml

This file was deleted.

222 changes: 222 additions & 0 deletions cli-main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
#!/usr/bin/env node
'use strict';
const getStdin = require('get-stdin');
const meow = require('meow');
const formatterPretty = require('eslint-formatter-pretty');
const semver = require('semver');
const openReport = require('./lib/open-report.js');
const xo = require('./index.js');

const cli = meow(`
Usage
$ xo [<file|glob> ...]
Options
--fix Automagically fix issues
--reporter Reporter to use
--env Environment preset [Can be set multiple times]
--global Global variable [Can be set multiple times]
--ignore Additional paths to ignore [Can be set multiple times]
--space Use space indent instead of tabs [Default: 2]
--no-semicolon Prevent use of semicolons
--prettier Conform to Prettier code style
--node-version Range of Node.js version to support
--plugin Include third-party plugins [Can be set multiple times]
--extend Extend defaults with a custom config [Can be set multiple times]
--open Open files with issues in your editor
--quiet Show only errors and no warnings
--extension Additional extension to lint [Can be set multiple times]
--cwd=<dir> Working directory for files
--stdin Validate/fix code from stdin
--stdin-filename Specify a filename for the --stdin option
--print-config Print the effective ESLint config for the given file
Examples
$ xo
$ xo index.js
$ xo *.js !foo.js
$ xo --space
$ xo --env=node --env=mocha
$ xo --plugin=react
$ xo --plugin=html --extension=html
$ echo 'const x=true' | xo --stdin --fix
$ xo --print-config=index.js
Tips
- Add XO to your project with \`npm init xo\`.
- Put options in package.json instead of using flags so other tools can read it.
`, {
autoVersion: false,
booleanDefault: undefined,
flags: {
fix: {
type: 'boolean'
},
reporter: {
type: 'string'
},
env: {
type: 'string',
isMultiple: true
},
global: {
type: 'string',
isMultiple: true
},
ignore: {
type: 'string',
isMultiple: true
},
space: {
type: 'string'
},
semicolon: {
type: 'boolean'
},
prettier: {
type: 'boolean'
},
nodeVersion: {
type: 'string'
},
plugin: {
type: 'string',
isMultiple: true
},
extend: {
type: 'string',
isMultiple: true
},
open: {
type: 'boolean'
},
quiet: {
type: 'boolean'
},
extension: {
type: 'string',
isMultiple: true
},
cwd: {
type: 'string'
},
printConfig: {
type: 'string'
},
stdin: {
type: 'boolean'
},
stdinFilename: {
type: 'string'
}
}
});

const {input, flags: options, showVersion} = cli;

// TODO: Fix this properly instead of the below workaround.
// Revert behavior of meow >8 to pre-8 (7.1.1) for flags using `isMultiple: true`.
// Otherwise, options defined in package.json can't be merged by lib/options-manager.js `mergeOptions()`.
for (const key in options) {
if (Array.isArray(options[key]) && options[key].length === 0) {
delete options[key];
}
}

// Make data types for `options.space` match those of the API
// Check for string type because `xo --no-space` sets `options.space` to `false`
if (typeof options.space === 'string') {
if (/^\d+$/u.test(options.space)) {
options.space = Number.parseInt(options.space, 10);
} else if (options.space === 'true') {
options.space = true;
} else if (options.space === 'false') {
options.space = false;
} else {
if (options.space !== '') {
// Assume `options.space` was set to a filename when run as `xo --space file.js`
input.push(options.space);
}

options.space = true;
}
}

if (process.env.GITHUB_ACTIONS && !options.fix && !options.reporter) {
options.quiet = true;
}

const log = async report => {
const reporter = options.reporter || process.env.GITHUB_ACTIONS ? await xo.getFormatter(options.reporter || 'compact') : formatterPretty;
process.stdout.write(reporter(report.results));
process.exitCode = report.errorCount === 0 ? 0 : 1;
};

// `xo -` => `xo --stdin`
if (input[0] === '-') {
options.stdin = true;
input.shift();
}

if (options.version) {
showVersion();
}

if (options.nodeVersion) {
if (options.nodeVersion === 'false') {
options.nodeVersion = false;
} else if (!semver.validRange(options.nodeVersion)) {
console.error('The `--node-engine` flag must be a valid semver range (for example `>=6`)');
process.exit(1);
}
}

(async () => {
if (options.printConfig) {
if (input.length > 0) {
console.error('The `--print-config` flag must be used with exactly one filename');
process.exit(1);
}

if (options.stdin) {
console.error('The `--print-config` flag is not supported on stdin');
process.exit(1);
}

options.filePath = options.printConfig;
const config = await xo.getConfig(options);
console.log(JSON.stringify(config, undefined, '\t'));
} else if (options.stdin) {
const stdin = await getStdin();

if (options.stdinFilename) {
options.filePath = options.stdinFilename;
}

if (options.fix) {
const {results: [result]} = await xo.lintText(stdin, options);
// If there is no output, pass the stdin back out
process.stdout.write((result && result.output) || stdin);
return;
}

if (options.open) {
console.error('The `--open` flag is not supported on stdin');
process.exit(1);
}

await log(await xo.lintText(stdin, options));
} else {
const report = await xo.lintFiles(input, options);

if (options.fix) {
await xo.outputFixes(report);
}

if (options.open) {
openReport(report);
}

await log(report);
}
})();
89 changes: 9 additions & 80 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,15 @@
#!/usr/bin/env node
'use strict';
var updateNotifier = require('update-notifier');
var getStdin = require('get-stdin');
var meow = require('meow');
var xo = require('./');
const resolveCwd = require('resolve-cwd');
const hasFlag = require('has-flag');

var cli = meow({
help: [
'Usage',
' $ xo [<file|glob> ...]',
'',
'Options',
' --init Add XO to your project',
' --fix Automagically fix issues',
' --compact Compact output',
' --stdin Validate code from stdin',
' --esnext Enable ES2015+ rules',
' --env Environment preset [Can be set multiple times]',
' --global Global variable [Can be set multiple times]',
' --ignore Additional paths to ignore [Can be set multiple times]',
' --space Use space indent instead of tabs [Default: 2]',
' --no-semicolon Prevent use of semicolons',
' --plugin Include third-party plugins [Can be set multiple times]',
' --extend Extend defaults with a custom config [Can be set multiple times]',
'',
'Examples',
' $ xo',
' $ xo index.js',
' $ xo *.js !foo.js',
' $ xo --esnext --space',
' $ xo --env=node --env=mocha',
' $ xo --init --esnext',
' $ xo --plugin=react',
'',
'Tips',
' Put options in package.json instead of using flags so other tools can read it.'
]
}, {
string: [
'_'
],
boolean: [
'init',
'compact',
'stdin',
'fix'
]
});
const localCLI = resolveCwd.silent('xo/cli');

updateNotifier({pkg: cli.pkg}).notify();

var input = cli.input;
var opts = cli.flags;

function log(report) {
process.stdout.write(xo.getFormatter(opts.compact && 'compact')(report.results));
process.exit(report.errorCount === 0 ? 0 : 1);
}

// `xo -` => `xo --stdin`
if (input[0] === '-') {
opts.stdin = true;
input.shift();
}

if (opts.init) {
require('xo-init')();
} else if (opts.stdin) {
getStdin().then(function (str) {
if (opts.fix) {
console.error('The `fix` option is not supported on stdin');
process.exit(1);
}

log(xo.lintText(str, opts));
});
// Prefer the local installation of XO
if (!hasFlag('no-local') && localCLI && localCLI !== __filename) {
const debug = require('debug')('xo');
debug('Using local install of XO');
require(localCLI);
} else {
xo.lintFiles(input, opts).then(function (report) {
if (opts.fix) {
xo.outputFixes(report);
}

log(report);
});
require('./cli-main');
}
Loading