diff --git a/cli-main.js b/cli-main.js index 2db2eaae..2087433b 100755 --- a/cli-main.js +++ b/cli-main.js @@ -1,10 +1,15 @@ #!/usr/bin/env node 'use strict'; +const path = require('path'); const updateNotifier = require('update-notifier'); const getStdin = require('get-stdin'); const meow = require('meow'); const formatterPretty = require('eslint-formatter-pretty'); const semver = require('semver'); +const globby = require('globby'); +const multimatch = require('multimatch'); +const pkgConf = require('pkg-conf'); +const optionsManager = require('./lib/options-manager'); const openReport = require('./lib/open-report'); const xo = require('.'); @@ -139,6 +144,41 @@ const log = report => { process.exit(report.errorCount === 0 ? 0 : 1); }; +const checkIfInputFileIsIgnored = () => { + let packageJsonIgnores = []; + let cliIgnores = []; + + const packageOpts = pkgConf.sync('xo', {skipOnFalse: true}); + if (packageOpts.ignores !== undefined && Array.isArray(packageOpts.ignores)) { + packageJsonIgnores = packageOpts.ignores; + } + + if (options.ignore && Array.isArray(options.ignore)) { + cliIgnores = options.ignore; + } else if (options.ignore) { + cliIgnores.push(options.ignore); + } + + const allIgnoredDirectories = optionsManager.DEFAULT_IGNORE.concat( + packageJsonIgnores, + cliIgnores + ); + + for (const file of input) { + const filename = path.relative(process.cwd(), file); + const inIgnoredDirectory = + multimatch(filename, allIgnoredDirectories).length > 0; + const isGitIgnored = globby.gitignore.sync({ + cwd: process.cwd(), + ignore: optionsManager.DEFAULT_IGNORE + })(filename); + if (inIgnoredDirectory || isGitIgnored) { + console.error(`You cannot run xo on an ignored file ${filename}`); + process.exit(1); + } + } +}; + // `xo -` => `xo --stdin` if (input[0] === '-') { options.stdin = true; @@ -171,6 +211,7 @@ if (options.init) { log(xo.lintText(stdin, options)); }); } else { + checkIfInputFileIsIgnored(); xo.lintFiles(input, options).then(report => { if (options.fix) { xo.outputFixes(report); diff --git a/test/cli-main.js b/test/cli-main.js index df400998..f166b8ea 100644 --- a/test/cli-main.js +++ b/test/cli-main.js @@ -61,9 +61,11 @@ test('ignore files in .gitignore', async t => { t.deepEqual(files, ['index.js', 'test/bar.js']); }); -test('ignore explicit files when in .gitgnore', async t => { +test('fail explicit files when in .gitgnore', async t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); - await t.notThrowsAsync(main(['test/foo.js', '--reporter=json'], {cwd})); + const {stderr} = await t.throwsAsync(main(['test/foo.js', '--reporter=json'], {cwd})); + const filename = path.normalize('test/foo.js'); + t.true(stderr.includes(`You cannot run xo on an ignored file ${filename}`)); }); test('negative gitignores', async t => { @@ -150,3 +152,23 @@ test('space option with boolean strings', async t => { t.true(trueResult.stdout.includes('Expected indentation of 2 spaces')); t.true(falseResult.stdout.includes('Expected indentation of 1 tab')); }); + +test('fail explicit files when in ignores array in package.json', async t => { + const cwd = path.join(__dirname, 'fixtures/explicit-file-ignores'); + const {stderr} = await t.throwsAsync(main(['tests/bar.js', '--reporter=json'], {cwd})); + const filename = path.normalize('tests/bar.js'); + t.true(stderr.includes(`You cannot run xo on an ignored file ${filename}`)); +}); + +test('fail explicit files when in default ignores', async t => { + const cwd = path.join(__dirname, 'fixtures/explicit-file-ignores'); + const {stderr} = await t.throwsAsync(main(['dist/foo.js', '--reporter=json'], {cwd})); + const filename = path.normalize('dist/foo.js'); + t.true(stderr.includes(`You cannot run xo on an ignored file ${filename}`)); +}); + +test('fail explicit files when in cli ignores', async t => { + const cwd = path.join(__dirname, 'fixtures/explicit-file-ignores'); + const {stderr} = await t.throwsAsync(main(['baz.js', '--ignore', 'baz.js', '--reporter=json'], {cwd})); + t.true(stderr.includes('You cannot run xo on an ignored file baz.js')); +}); diff --git a/test/fixtures/explicit-file-ignores/baz.js b/test/fixtures/explicit-file-ignores/baz.js new file mode 100644 index 00000000..100343e1 --- /dev/null +++ b/test/fixtures/explicit-file-ignores/baz.js @@ -0,0 +1,2 @@ +const name = "JabClari"; +console.log(name); \ No newline at end of file diff --git a/test/fixtures/explicit-file-ignores/dist/foo.js b/test/fixtures/explicit-file-ignores/dist/foo.js new file mode 100644 index 00000000..88036253 --- /dev/null +++ b/test/fixtures/explicit-file-ignores/dist/foo.js @@ -0,0 +1,2 @@ +const description = "JavaScript happiness style linter ❤️"; +console.log(description); \ No newline at end of file diff --git a/test/fixtures/explicit-file-ignores/package.json b/test/fixtures/explicit-file-ignores/package.json new file mode 100644 index 00000000..55a8d881 --- /dev/null +++ b/test/fixtures/explicit-file-ignores/package.json @@ -0,0 +1,5 @@ +{ + "xo":{ + "ignores": ["tests/**"] + } +} \ No newline at end of file diff --git a/test/fixtures/explicit-file-ignores/tests/bar.js b/test/fixtures/explicit-file-ignores/tests/bar.js new file mode 100644 index 00000000..214f323b --- /dev/null +++ b/test/fixtures/explicit-file-ignores/tests/bar.js @@ -0,0 +1,2 @@ +const age = 99; +console.log(age); \ No newline at end of file