From 291dc5c17d445ea94ec2fef2e44cea986aa814f1 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sun, 8 Jan 2017 21:38:37 -0500 Subject: [PATCH] Ignore home config from disableWhenNoEslintConfig --- lib/helpers.js | 19 ++++++- lib/main.js | 3 +- lib/worker.js | 5 +- package.json | 3 +- spec/fixtures/files/badInline.js | 3 ++ spec/linter-eslint-spec.js | 91 ++++++++++++++++++++++++++++++++ src/helpers.js | 16 +++++- src/main.js | 5 +- src/worker.js | 4 +- 9 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 spec/fixtures/files/badInline.js diff --git a/lib/helpers.js b/lib/helpers.js index 87c2d18c..54473f0a 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -159,9 +159,20 @@ let processESLintMessages = exports.processESLintMessages = (() => { }; })(); +/** + * Check if a config is directly inside a user's home directory. + * Such config files are used by ESLint as a fallback, only for situations + * when there is no other config file between a file being linted and root. + * + * @param {string} configPath - The path of the config file being checked + * @return {Boolean} [description] + */ + + exports.spawnWorker = spawnWorker; exports.showError = showError; exports.idsToIgnoredRules = idsToIgnoredRules; +exports.isConfigAtHomeRoot = isConfigAtHomeRoot; var _child_process = require('child_process'); @@ -181,6 +192,10 @@ var _eslintRuleDocumentation2 = _interopRequireDefault(_eslintRuleDocumentation) var _atomLinter = require('atom-linter'); +var _userHome = require('user-home'); + +var _userHome2 = _interopRequireDefault(_userHome); + var _atom = require('atom'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -287,4 +302,6 @@ const generateInvalidTrace = (() => { return function generateInvalidTrace(_x5, _x6, _x7, _x8, _x9, _x10, _x11, _x12, _x13, _x14) { return _ref3.apply(this, arguments); }; -})(); \ No newline at end of file +})();function isConfigAtHomeRoot(configPath) { + return (0, _path.dirname)(configPath) === _userHome2.default; +} \ No newline at end of file diff --git a/lib/main.js b/lib/main.js index 25e1cfaa..fa28a328 100644 --- a/lib/main.js +++ b/lib/main.js @@ -58,7 +58,8 @@ module.exports = { // Do not try to fix if linting should be disabled const fileDir = _path2.default.dirname(filePath); const configPath = (0, _workerHelpers.getConfigPath)(fileDir); - if (configPath === null && disableWhenNoEslintConfig) return; + const noProjectConfig = configPath === null || (0, _helpers.isConfigAtHomeRoot)(configPath); + if (noProjectConfig && disableWhenNoEslintConfig) return; this.worker.request('job', { type: 'fix', diff --git a/lib/worker.js b/lib/worker.js index 0083c555..cfad32a0 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -15,6 +15,8 @@ var _workerHelpers = require('./worker-helpers'); var Helpers = _interopRequireWildcard(_workerHelpers); +var _helpers = require('./helpers'); + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -32,7 +34,8 @@ const ignoredMessages = [ 'File ignored by default. Use a negated ignore pattern (like "--ignore-pattern \'!\'") to override.', 'File ignored by default. Use "--ignore-pattern \'!node_modules/*\'" to override.', 'File ignored by default. Use "--ignore-pattern \'!bower_components/*\'" to override.']; function lintJob(argv, contents, eslint, configPath, config) { - if (configPath === null && config.disableWhenNoEslintConfig) { + const noProjectConfig = configPath === null || (0, _helpers.isConfigAtHomeRoot)(configPath); + if (noProjectConfig && config.disableWhenNoEslintConfig) { return []; } eslint.execute(argv, contents); diff --git a/package.json b/package.json index 489e4475..ff37e879 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,8 @@ "eslint": "^3.6.0", "eslint-rule-documentation": "^1.0.0", "process-communication": "^1.1.0", - "resolve-env": "^1.0.0" + "resolve-env": "^1.0.0", + "user-home": "^2.0.0" }, "devDependencies": { "babel-cli": "^6.18.0", diff --git a/spec/fixtures/files/badInline.js b/spec/fixtures/files/badInline.js new file mode 100644 index 00000000..1c67f73a --- /dev/null +++ b/spec/fixtures/files/badInline.js @@ -0,0 +1,3 @@ +/* eslint no-undef: error */ + +foo = 42; diff --git a/spec/linter-eslint-spec.js b/spec/linter-eslint-spec.js index 3c6be10e..98dad3c4 100644 --- a/spec/linter-eslint-spec.js +++ b/spec/linter-eslint-spec.js @@ -10,6 +10,7 @@ const fixturesDir = path.join(__dirname, 'fixtures') const goodPath = path.join(fixturesDir, 'files', 'good.js') const badPath = path.join(fixturesDir, 'files', 'bad.js') +const badInlinePath = path.join(fixturesDir, 'files', 'badInline.js') const emptyPath = path.join(fixturesDir, 'files', 'empty.js') const fixPath = path.join(fixturesDir, 'files', 'fix.js') const configPath = path.join(fixturesDir, 'configs', '.eslintrc.yml') @@ -361,4 +362,94 @@ describe('The eslint provider for Linter', () => { ) ) ) + + describe('when setting `disableWhenNoEslintConfig` is false', () => { + let editor + let didError + let gotLintingErrors + let tempFixtureDir + let tempFixturePath + beforeEach(() => { + atom.config.set('linter-eslint.disableWhenNoEslintConfig', false) + + waitsForPromise(() => + new Promise((resolve) => { + tempFixtureDir = fs.mkdtempSync(tmpdir() + path.sep) + tempFixturePath = path.join(tempFixtureDir, 'badInline.js') + const wr = fs.createWriteStream(tempFixturePath) + wr.on('close', () => + atom.workspace.open(tempFixturePath).then((openEditor) => { + editor = openEditor + resolve() + }) + ) + fs.createReadStream(badInlinePath).pipe(wr) + }) + ) + }) + + afterEach(() => { + rimraf.sync(tempFixtureDir) + }) + + it('errors when no config file is found', () => { + lint(editor) + .then((messages) => { + // Older versions of ESLint will report an error + // (or if current user running tests has a config in their home directory) + const expectedHtml = 'no-undef 'foo' is not defined.' + expect(messages.length).toBe(1) + expect(messages[0].html).toBe(expectedHtml) + gotLintingErrors = true + }) + .catch((err) => { + // Newer versions of ESLint will throw an exception + expect(err.message).toBe('No ESLint configuration found.') + didError = true + }) + + waitsFor( + () => didError || gotLintingErrors, + 'An error should have been thrown or linting performed' + ) + }) + }) + + describe('when `disableWhenNoEslintConfig` is true', () => { + let editor + let tempFixtureDir + let tempFixturePath + beforeEach(() => { + atom.config.set('linter-eslint.disableWhenNoEslintConfig', true) + + waitsForPromise(() => + new Promise((resolve) => { + tempFixtureDir = fs.mkdtempSync(tmpdir() + path.sep) + tempFixturePath = path.join(tempFixtureDir, 'badInline.js') + const wr = fs.createWriteStream(tempFixturePath) + wr.on('close', () => + atom.workspace.open(tempFixturePath).then((openEditor) => { + editor = openEditor + resolve() + }) + ) + fs.createReadStream(badInlinePath).pipe(wr) + }) + ) + }) + + afterEach(() => { + rimraf.sync(tempFixtureDir) + }) + + it('does not report errors when no config file is found', () => + waitsForPromise(() => + lint(editor) + .then((messages) => { + expect(messages.length).toBe(0) + }) + ) + ) + }) }) diff --git a/src/helpers.js b/src/helpers.js index 96fb01be..23b73e1e 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -2,10 +2,11 @@ import ChildProcess from 'child_process' import { createFromProcess } from 'process-communication' -import { join } from 'path' +import { join, dirname } from 'path' import escapeHTML from 'escape-html' import ruleURI from 'eslint-rule-documentation' import { rangeFromLineNumber } from 'atom-linter' +import userHome from 'user-home' // eslint-disable-next-line import/no-extraneous-dependencies, import/extensions import { Disposable, Range } from 'atom' @@ -255,3 +256,16 @@ export async function processESLintMessages(response, textEditor, showRule, work return ret })) } + +/** + * Check if a config is directly inside a user's home directory. + * Such config files are used by ESLint as a fallback, only for situations + * when there is no other config file between a file being linted and root. + * + * @param {string} configPath - The path of the config file being checked + * @return {Boolean} [description] + */ +export function isConfigAtHomeRoot(configPath) { + console.log(userHome, dirname(configPath); + return (dirname(configPath) === userHome) +} diff --git a/src/main.js b/src/main.js index f3269fc3..28cd1913 100644 --- a/src/main.js +++ b/src/main.js @@ -6,7 +6,7 @@ import { CompositeDisposable, } from 'atom' import { spawnWorker, showError, idsToIgnoredRules, processESLintMessages, - generateDebugString + generateDebugString, isConfigAtHomeRoot } from './helpers' import { getConfigPath } from './worker-helpers' @@ -54,7 +54,8 @@ module.exports = { // Do not try to fix if linting should be disabled const fileDir = Path.dirname(filePath) const configPath = getConfigPath(fileDir) - if (configPath === null && disableWhenNoEslintConfig) return + const noProjectConfig = (configPath === null || isConfigAtHomeRoot(configPath)) + if (noProjectConfig && disableWhenNoEslintConfig) return this.worker.request('job', { type: 'fix', diff --git a/src/worker.js b/src/worker.js index fe6f7107..35607711 100644 --- a/src/worker.js +++ b/src/worker.js @@ -6,6 +6,7 @@ import Path from 'path' import { create } from 'process-communication' import { FindCache, findCached } from 'atom-linter' import * as Helpers from './worker-helpers' +import { isConfigAtHomeRoot } from './helpers' process.title = 'linter-eslint helper' @@ -24,7 +25,8 @@ const ignoredMessages = [ ] function lintJob(argv, contents, eslint, configPath, config) { - if (configPath === null && config.disableWhenNoEslintConfig) { + const noProjectConfig = (configPath === null || isConfigAtHomeRoot(configPath)) + if (noProjectConfig && config.disableWhenNoEslintConfig) { return [] } eslint.execute(argv, contents)