Skip to content
This repository has been archived by the owner on Aug 7, 2023. It is now read-only.

Commit

Permalink
Allow user to specify a local node_modules path. Continues #585
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Ratcliffe authored and Arcanemagus committed Oct 6, 2016
1 parent 6cd62e8 commit fb7436c
Show file tree
Hide file tree
Showing 17 changed files with 85 additions and 21 deletions.
10 changes: 10 additions & 0 deletions README.md
Expand Up @@ -57,6 +57,16 @@ idea to have a look at the [Get Started With ESLint](http://devnull.guru/get-sta
blog post by [IanVS](https://github.com/IanVS) and [the ESLint documentation](http://eslint.org/docs/user-guide/configuring),
including the [list of rules](http://eslint.org/docs/rules/).

## A Note About Settings

If Use Global is on, Atom will use the global ESLint. The path to it is figured out by running `npm get prefix`. If this fails for any reason, you can set the global path manually in Global Node Installation Path.

If Use Global is off, Atom will try to find a local installation in the project folder, look if there's ESLint in `${PROJECT_ROOT}/node_modules` and use it if found.

The path to the local node_modules folder can be a path relative to the project or an absolute path and should end in /node_modules/. This path is used if the other methods of discovery have failed.

If there is no local installation Atom will use the built-in ESLint in the linter-eslint package itself.

## Contributing

See the [contributing guidelines](./CONTRIBUTING.md) to get started
4 changes: 2 additions & 2 deletions lib/helpers.js
Expand Up @@ -49,7 +49,7 @@ function spawnWorker() {
}

function showError(givenMessage) {
var givenDetail = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
var givenDetail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;

var detail = void 0;
var message = void 0;
Expand All @@ -67,7 +67,7 @@ function showError(givenMessage) {
}

function idsToIgnoredRules() {
var ruleIds = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
var ruleIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

return ruleIds.reduce(function (ids, id) {
ids[id] = RULE_OFF_SEVERITY;
Expand Down
15 changes: 11 additions & 4 deletions lib/main.js
Expand Up @@ -52,10 +52,14 @@ module.exports = {
this.subscriptions.add(atom.workspace.observeTextEditors(function (editor) {
editor.onDidSave(function () {
if (scopes.indexOf(editor.getGrammar().scopeName) !== -1 && atom.config.get('linter-eslint.fixOnSave')) {
var filePath = editor.getPath();
var projectPath = atom.project.relativizePath(filePath)[0];

_this.worker.request('job', {
type: 'fix',
config: atom.config.get('linter-eslint'),
filePath: editor.getPath()
filePath: filePath,
projectPath: projectPath
}).catch(function (response) {
return atom.notifications.addWarning(response);
});
Expand All @@ -67,6 +71,7 @@ module.exports = {
'linter-eslint:fix-file': function linterEslintFixFile() {
var textEditor = atom.workspace.getActiveTextEditor();
var filePath = textEditor.getPath();
var projectPath = atom.project.relativizePath(filePath)[0];

if (!textEditor || textEditor.isModified()) {
// Abort for invalid or unsaved text editors
Expand All @@ -77,7 +82,8 @@ module.exports = {
_this.worker.request('job', {
type: 'fix',
config: atom.config.get('linter-eslint'),
filePath: filePath
filePath: filePath,
projectPath: projectPath
}).then(function (response) {
return atom.notifications.addSuccess(response);
}).catch(function (response) {
Expand Down Expand Up @@ -138,11 +144,12 @@ module.exports = {
}

return _this2.worker.request('job', {
contents: text,
type: 'lint',
contents: text,
config: atom.config.get('linter-eslint'),
rules: rules,
filePath: filePath
filePath: filePath,
projectPath: atom.project.relativizePath(filePath)[0] || ''
}).then(function (response) {
if (textEditor.getText() !== text) {
/*
Expand Down
12 changes: 8 additions & 4 deletions lib/worker-helpers.js
Expand Up @@ -52,7 +52,7 @@ function getNodePrefixPath() {
return Cache.NODE_PREFIX_PATH;
}

function getESLintFromDirectory(modulesDir, config) {
function getESLintFromDirectory(modulesDir, config, projectPath) {
var ESLintDirectory = null;

if (config.useGlobalEslint) {
Expand All @@ -62,8 +62,12 @@ function getESLintFromDirectory(modulesDir, config) {
} else {
ESLintDirectory = _path2.default.join(prefixPath, 'lib', 'node_modules', 'eslint');
}
} else {
} else if (!config.advancedLocalNodeModules) {
ESLintDirectory = _path2.default.join(modulesDir || '', 'eslint');
} else if (_path2.default.isAbsolute(config.advancedLocalNodeModules)) {
ESLintDirectory = _path2.default.join(config.advancedLocalNodeModules || '', 'eslint');
} else {
ESLintDirectory = _path2.default.join(projectPath, config.advancedLocalNodeModules, 'eslint');
}
try {
// eslint-disable-next-line import/no-dynamic-require
Expand All @@ -85,10 +89,10 @@ function refreshModulesPath(modulesDir) {
}
}

function getESLintInstance(fileDir, config) {
function getESLintInstance(fileDir, config, projectPath) {
var modulesDir = _path2.default.dirname((0, _atomLinter.findCached)(fileDir, 'node_modules/eslint') || '');
refreshModulesPath(modulesDir);
return getESLintFromDirectory(modulesDir, config);
return getESLintFromDirectory(modulesDir, config, projectPath || '');
}

function getConfigPath(fileDir) {
Expand Down
3 changes: 2 additions & 1 deletion lib/worker.js
Expand Up @@ -55,6 +55,7 @@ function fixJob(argv, eslint) {
var type = _ref.type;
var config = _ref.config;
var filePath = _ref.filePath;
var projectPath = _ref.projectPath;
var rules = _ref.rules;

global.__LINTER_ESLINT_RESPONSE = [];
Expand All @@ -64,7 +65,7 @@ function fixJob(argv, eslint) {
}

var fileDir = _path2.default.dirname(filePath);
var eslint = Helpers.getESLintInstance(fileDir, config);
var eslint = Helpers.getESLintInstance(fileDir, config, projectPath);
var configPath = Helpers.getConfigPath(fileDir);
var relativeFilePath = Helpers.getRelativePath(fileDir, filePath, config);

Expand Down
6 changes: 6 additions & 0 deletions package.json
Expand Up @@ -43,6 +43,12 @@
"type": "string",
"default": ""
},
"advancedLocalNodeModules": {
"title": "Path to the local node_modules folder",
"description": "Optionally specify the path to the local node_modules folder",
"type": "string",
"default": ""
},
"eslintRulesDir": {
"title": "ESLint Rules Dir",
"description": "Specify a directory for ESLint to load rules from",
Expand Down
2 changes: 2 additions & 0 deletions spec/fixtures/indirect-local-eslint/testing/eslint/.gitignore
@@ -0,0 +1,2 @@
# Keep node_modules test fixtures
!node_modules
@@ -0,0 +1 @@
var foo = 42;
Empty file.
Empty file.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
21 changes: 21 additions & 0 deletions spec/worker-helpers-spec.js
Expand Up @@ -6,6 +6,27 @@ import { getFixturesPath } from './common'

describe('Worker Helpers', () => {
describe('getESLintInstance && getESLintFromDirectory', () => {
it('tries to find an indirect local eslint using an absolute path', () => {
const path = Path.join(
getFixturesPath('indirect-local-eslint'), 'testing', 'eslint', 'node_modules')
const eslint = Helpers.getESLintInstance('', {
useGlobalEslint: false,
advancedLocalNodeModules: path
})
expect(eslint).toBe('located')
})
it('tries to find an indirect local eslint using a relative path', () => {
const path = Path.join(
getFixturesPath('indirect-local-eslint'), 'testing', 'eslint', 'node_modules')
const [projectPath, relativePath] = atom.project.relativizePath(path)

const eslint = Helpers.getESLintInstance('', {
useGlobalEslint: false,
advancedLocalNodeModules: relativePath
}, projectPath)

expect(eslint).toBe('located')
})
it('tries to find a local eslint', () => {
const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), {})
expect(eslint).toBe('located')
Expand Down
15 changes: 11 additions & 4 deletions src/main.js
Expand Up @@ -45,10 +45,14 @@ module.exports = {
editor.onDidSave(() => {
if (scopes.indexOf(editor.getGrammar().scopeName) !== -1 &&
atom.config.get('linter-eslint.fixOnSave')) {
const filePath = editor.getPath()
const projectPath = atom.project.relativizePath(filePath)[0]

this.worker.request('job', {
type: 'fix',
config: atom.config.get('linter-eslint'),
filePath: editor.getPath()
filePath,
projectPath
}).catch(response =>
atom.notifications.addWarning(response)
)
Expand All @@ -60,6 +64,7 @@ module.exports = {
'linter-eslint:fix-file': () => {
const textEditor = atom.workspace.getActiveTextEditor()
const filePath = textEditor.getPath()
const projectPath = atom.project.relativizePath(filePath)[0]

if (!textEditor || textEditor.isModified()) {
// Abort for invalid or unsaved text editors
Expand All @@ -70,7 +75,8 @@ module.exports = {
this.worker.request('job', {
type: 'fix',
config: atom.config.get('linter-eslint'),
filePath
filePath,
projectPath
}).then(response =>
atom.notifications.addSuccess(response)
).catch(response =>
Expand Down Expand Up @@ -128,11 +134,12 @@ module.exports = {
}

return this.worker.request('job', {
contents: text,
type: 'lint',
contents: text,
config: atom.config.get('linter-eslint'),
rules,
filePath
filePath,
projectPath: atom.project.relativizePath(filePath)[0] || ''
}).then((response) => {
if (textEditor.getText() !== text) {
/*
Expand Down
12 changes: 8 additions & 4 deletions src/worker-helpers.js
Expand Up @@ -29,7 +29,7 @@ export function getNodePrefixPath() {
return Cache.NODE_PREFIX_PATH
}

export function getESLintFromDirectory(modulesDir, config) {
export function getESLintFromDirectory(modulesDir, config, projectPath) {
let ESLintDirectory = null

if (config.useGlobalEslint) {
Expand All @@ -39,8 +39,12 @@ export function getESLintFromDirectory(modulesDir, config) {
} else {
ESLintDirectory = Path.join(prefixPath, 'lib', 'node_modules', 'eslint')
}
} else {
} else if (!config.advancedLocalNodeModules) {
ESLintDirectory = Path.join(modulesDir || '', 'eslint')
} else if (Path.isAbsolute(config.advancedLocalNodeModules)) {
ESLintDirectory = Path.join(config.advancedLocalNodeModules || '', 'eslint')
} else {
ESLintDirectory = Path.join(projectPath, config.advancedLocalNodeModules, 'eslint')
}
try {
// eslint-disable-next-line import/no-dynamic-require
Expand All @@ -64,10 +68,10 @@ export function refreshModulesPath(modulesDir) {
}
}

export function getESLintInstance(fileDir, config) {
export function getESLintInstance(fileDir, config, projectPath) {
const modulesDir = Path.dirname(findCached(fileDir, 'node_modules/eslint') || '')
refreshModulesPath(modulesDir)
return getESLintFromDirectory(modulesDir, config)
return getESLintFromDirectory(modulesDir, config, projectPath || '')
}

export function getConfigPath(fileDir) {
Expand Down
4 changes: 2 additions & 2 deletions src/worker.js
Expand Up @@ -41,15 +41,15 @@ function fixJob(argv, eslint) {
}
}

create().onRequest('job', ({ contents, type, config, filePath, rules }, job) => {
create().onRequest('job', ({ contents, type, config, filePath, projectPath, rules }, job) => {
global.__LINTER_ESLINT_RESPONSE = []

if (config.disableFSCache) {
FindCache.clear()
}

const fileDir = Path.dirname(filePath)
const eslint = Helpers.getESLintInstance(fileDir, config)
const eslint = Helpers.getESLintInstance(fileDir, config, projectPath)
const configPath = Helpers.getConfigPath(fileDir)
const relativeFilePath = Helpers.getRelativePath(fileDir, filePath, config)

Expand Down

0 comments on commit fb7436c

Please sign in to comment.