-
Notifications
You must be signed in to change notification settings - Fork 4
Expand configuration options #115
Changes from 5 commits
340f098
0c6f1bb
a5adaaf
b6e544a
3402013
f1e78af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# EditorConfig helps developers define and maintain consistent | ||
# coding styles between different editors and IDEs | ||
# editorconfig.org | ||
|
||
root = true | ||
|
||
[*] | ||
|
||
# Change these settings to your own preference | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
# We recommend you to keep these unchanged | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
.idea | ||
node_modules | ||
.github_changelog_generator | ||
package-lock.json |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,70 @@ | ||
'use babel'; | ||
|
||
// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions | ||
// eslint-disable-next-line import/extensions, import/no-extraneous-dependencies | ||
import { CompositeDisposable } from 'atom'; | ||
import Path from 'path'; | ||
import * as helpers from 'atom-linter'; | ||
|
||
// Local vars | ||
const regex = /(.+):(\d+)\t*(.+)/g; | ||
let helpers; | ||
let path; | ||
|
||
// Settings | ||
let executablePath; | ||
let rulesets; | ||
function loadDeps() { | ||
if (!helpers) { | ||
helpers = require('atom-linter'); | ||
} | ||
if (!path) { | ||
path = require('path'); | ||
} | ||
} | ||
|
||
export default { | ||
activate() { | ||
require('atom-package-deps').install('linter-phpmd'); | ||
this.idleCallbacks = new Set(); | ||
let depsCallbackID; | ||
const installLinterPhpmdDeps = () => { | ||
this.idleCallbacks.delete(depsCallbackID); | ||
if (!atom.inSpecMode()) { | ||
require('atom-package-deps').install('linter-phpmd'); | ||
} | ||
loadDeps(); | ||
}; | ||
depsCallbackID = window.requestIdleCallback(installLinterPhpmdDeps); | ||
this.idleCallbacks.add(depsCallbackID); | ||
|
||
this.subscriptions = new CompositeDisposable(); | ||
|
||
// Backwards compatibility | ||
if (atom.config.get('linter-phpmd.rulesets') !== undefined) { | ||
this.rulesOrConfigFile = atom.config.get('linter-phpmd.rulesets'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We want to save their old setting, not grab it this one time and then lose it forever 😉. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doh, you're right 🙄 where's my head at? 😜 |
||
atom.config.unset('linter-phpmd.rulesets'); | ||
} | ||
|
||
this.subscriptions.add( | ||
atom.config.observe('linter-phpmd.executablePath', (value) => { | ||
executablePath = value; | ||
this.executablePath = value; | ||
}), | ||
atom.config.observe('linter-phpmd.autoExecutableSearch', (value) => { | ||
this.autoExecutableSearch = value; | ||
}), | ||
atom.config.observe('linter-phpmd.disableWhenNoConfigFile', (value) => { | ||
this.disableWhenNoConfigFile = value; | ||
}), | ||
atom.config.observe('linter-phpmd.rulesets', (value) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remember how I said to remove that check on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, working on multiple projects so I'll have to dig into that to see what you mean 😜 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes, to make it backwards compatbile! 👍 |
||
rulesets = value; | ||
atom.config.observe('linter-phpmd.rulesOrConfigFile', (value) => { | ||
this.rulesOrConfigFile = value; | ||
}), | ||
atom.config.observe('linter-phpmd.autoConfigSearch', (value) => { | ||
this.autoConfigSearch = value; | ||
}), | ||
atom.config.observe('linter-phpmd.minimumPriority', (value) => { | ||
this.minimumPriority = value; | ||
}), | ||
atom.config.observe('linter-phpmd.strictMode', (value) => { | ||
this.strictMode = value; | ||
}), | ||
); | ||
}, | ||
|
||
deactivate() { | ||
this.idleCallbacks.forEach(callbackID => window.cancelIdleCallback(callbackID)); | ||
this.idleCallbacks.clear(); | ||
this.subscriptions.dispose(); | ||
}, | ||
|
||
|
@@ -41,39 +78,102 @@ export default { | |
const filePath = textEditor.getPath(); | ||
const fileText = textEditor.getText(); | ||
|
||
let ruleset = rulesets; | ||
if (/^[a-z0-9]+\.xml$/gi.test(rulesets)) { | ||
const rulesetPath = await helpers.findAsync(filePath, rulesets); | ||
if (rulesetPath !== null) { | ||
ruleset = rulesetPath; | ||
if (fileText === '' || !filePath) { | ||
// Empty file, empty results | ||
return []; | ||
} | ||
|
||
loadDeps(); | ||
const fileDir = path.dirname(filePath); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You'll need a check that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, this needs to be fixed in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, many of the providers still need the guard added to them, for some reason it's rarely an issue for most providers (I think it's a race condition in the |
||
|
||
let executable = this.executablePath; | ||
|
||
// Check if a local PHPMD executable is available | ||
if (this.autoExecutableSearch === true) { | ||
const phpmdNames = ['vendor/bin/phpmd']; | ||
const projExecutable = await helpers.findCachedAsync(fileDir, phpmdNames); | ||
|
||
if (projExecutable !== null) { | ||
executable = projExecutable; | ||
} | ||
} | ||
|
||
// Rulesets | ||
let rulesets = this.rulesOrConfigFile.join(','); | ||
let confFile = null; | ||
|
||
// Check if a rulesets file exists and handle it | ||
if (this.autoConfigSearch === true) { | ||
confFile = await helpers.findAsync(fileDir, ['phpmd.xml', 'phpmd.xml.dist', 'phpmd.ruleset.xml']); | ||
|
||
// Check if we should stop linting when no config file could be found | ||
if (this.disableWhenNoConfigFile && !confFile) { | ||
return []; | ||
} | ||
|
||
// Override rulessets with found config file | ||
if (confFile) { | ||
rulesets = confFile; | ||
} | ||
} | ||
|
||
// PHPMD cli parameters | ||
const parameters = [ | ||
filePath, | ||
'text', | ||
ruleset, | ||
rulesets, | ||
]; | ||
|
||
const projectDir = atom.project.relativizePath(filePath)[0]; | ||
const options = { | ||
// Rule priority threshold; rules with lower priority than this will not be used | ||
if (this.minimumPriority >= 0) { | ||
parameters.push('--minimumpriority', this.minimumPriority); | ||
} | ||
|
||
// Strict mode | ||
if (this.strictMode === true) { | ||
parameters.push('--strict'); | ||
} | ||
|
||
// Current working dir | ||
let workDir = fileDir; | ||
|
||
// Determine project path | ||
const projectPath = atom.project.relativizePath(filePath)[0]; | ||
|
||
// Set current working dir based on config path or project path | ||
if (confFile) { | ||
workDir = path.dirname(confFile); | ||
} else if (projectPath) { | ||
workDir = projectPath; | ||
} | ||
|
||
// PHPMD exec options | ||
const execOptions = { | ||
cwd: workDir, | ||
ignoreExitCode: true, | ||
cwd: projectDir || Path.dirname(filePath), | ||
timeout: 1000 * 60 * 5, // ms * s * m: 5 minutes | ||
}; | ||
|
||
const output = await helpers.exec(executablePath, parameters, options); | ||
// Execute PHPMD | ||
const result = await helpers.exec(executable, parameters, execOptions); | ||
|
||
if (result === null) { | ||
// Our specific spawn was terminated by a newer call, tell Linter not | ||
// to update messages | ||
return null; | ||
} | ||
|
||
// Check if the file contents have changed since the lint was triggered | ||
if (textEditor.getText() !== fileText) { | ||
// eslint-disable-next-line no-console | ||
console.warn('linter-phpmd:: The file was modified since the ' + | ||
'request was sent to check it. Since any results would no longer ' + | ||
'be valid, they are not being updated. Please save the file ' + | ||
'again to update the results.'); | ||
// Contents have changed, tell Linter not to update results | ||
return null; | ||
} | ||
|
||
// Message regex | ||
const regex = /(.+):(\d+)\t*(.+)/g; | ||
|
||
const messages = []; | ||
let match = regex.exec(output); | ||
let match = regex.exec(result); | ||
while (match !== null) { | ||
const line = Number.parseInt(match[2], 10) - 1; | ||
messages.push({ | ||
|
@@ -83,8 +183,9 @@ export default { | |
text: match[3], | ||
}); | ||
|
||
match = regex.exec(output); | ||
match = regex.exec(result); | ||
} | ||
|
||
return messages; | ||
}, | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
/** | ||
* A | ||
* @SuppressWarnings(PHPMD) | ||
*/ | ||
function a() { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to the version used elsewhere? (this).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure no problem 👍