Skip to content

Commit

Permalink
fix: handle negative gitignore patterns correctly
Browse files Browse the repository at this point in the history
*  split out getGitIgnores from getIgnores
*  adapt test cases accordingly
*  extend gitignore test case with negative pattern
*  invert gitignore patterns and feed sotred as glob instead of opts.ignore

fix #154
  • Loading branch information
marionebl committed Mar 17, 2017
1 parent cb63c5f commit 98040a9
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 19 deletions.
18 changes: 12 additions & 6 deletions index.js
Expand Up @@ -26,10 +26,12 @@ exports.lintText = (str, opts) => {
throw new Error('The `ignores` option requires the `filename` option to be defined.');
}

if (opts.ignores && opts.ignores.length > 0 && opts.filename) {
if (opts.filename) {
const gitIgnores = optionsManager.getGitIgnores(opts);
const filename = path.relative(opts.cwd, opts.filename);
const glob = [filename].concat(gitIgnores);

if (multimatch([filename], opts.ignores).length > 0) {
if (multimatch(glob, opts.ignores).length > 0) {
return {
errorCount: 0,
warningCount: 0,
Expand All @@ -49,14 +51,18 @@ exports.lintText = (str, opts) => {
return processReport(report, opts);
};

exports.lintFiles = (patterns, opts) => {
exports.lintFiles = (pattern, opts) => {
opts = optionsManager.preprocess(opts);

if (patterns.length === 0) {
patterns = '**/*';
if (pattern.length === 0) {
pattern = '**/*';
}

return globby(patterns, {ignore: opts.ignores}).then(paths => {
const gitIgnores = optionsManager.getGitIgnores(opts);
const patterns = Array.isArray(pattern) ? pattern : [pattern];
const glob = patterns.concat(gitIgnores);

return globby(glob, {ignore: opts.ignores}).then(paths => {
// filter out unwanted file extensions
// for silly users that don't specify an extension in the glob pattern
paths = paths.filter(x => {
Expand Down
21 changes: 14 additions & 7 deletions options-manager.js
Expand Up @@ -222,24 +222,30 @@ function groupConfigs(paths, baseOptions, overrides) {

function getIgnores(opts) {
opts.ignores = DEFAULT_IGNORE.concat(opts.ignores || []);
return opts;
}

function getGitIgnores(opts) {
const gitignores = globby.sync('**/.gitignore', {
ignore: opts.ignores,
ignore: opts.ignores || [],
cwd: opts.cwd || process.cwd()
});

const ignores = gitignores
return gitignores
.map(pathToGitignore => {
const patterns = parseGitignore(pathToGitignore);
const base = path.dirname(pathToGitignore);

return patterns.map(file => path.join(base, file));
return patterns
.map(pattern => {
const negate = !pattern.startsWith('!');
const patternPath = negate ? pattern : pattern.substr(1);
return {negate, pattern: path.join(base, patternPath)};
})
.sort(pattern => pattern.negate ? 1 : -1)
.map(item => item.negate ? `!${item.pattern}` : item.pattern);
})
.reduce((a, b) => a.concat(b), []);

opts.ignores = opts.ignores.concat(ignores);

return opts;
}

function preprocess(opts) {
Expand All @@ -262,3 +268,4 @@ exports.groupConfigs = groupConfigs;
exports.preprocess = preprocess;
exports.emptyOptions = emptyOptions;
exports.getIgnores = getIgnores;
exports.getGitIgnores = getGitIgnores;
1 change: 1 addition & 0 deletions test/.gitignore
@@ -1,2 +1,3 @@
# This is a test .gitignore.
foo/
!bar.js
1 change: 1 addition & 0 deletions test/bar/.gitignore
@@ -1 +1,2 @@
foo.js
!bar.js
12 changes: 6 additions & 6 deletions test/options-manager.js
Expand Up @@ -173,9 +173,10 @@ test('groupConfigs', t => {
});

test('gitignore', t => {
const result = manager.getIgnores({});
t.not(result.ignores.indexOf(path.join('foo', '**')), -1);
t.not(result.ignores.indexOf(path.join('bar', 'foo.js')), -1);
const ignores = manager.getGitIgnores({});
t.not(ignores.indexOf('!' + path.join('foo', '**')), -1);
t.not(ignores.indexOf('!' + path.join('bar', 'foo.js')), -1);
t.not(ignores.indexOf(path.join('bar', 'bar.js')), -1);
});

test('ignore ignored .gitignore', t => {
Expand All @@ -185,9 +186,8 @@ test('ignore ignored .gitignore', t => {
]
};

const result = manager.getIgnores(opts);

t.is(result.ignores.indexOf(path.join('bar', 'foobar', 'bar.js')), -1);
const ignores = manager.getGitIgnores(opts);
t.is(ignores.indexOf('!' + path.join('bar', 'foobar', 'bar.js')), -1);
});

test('mergeWithPkgConf: use child if closest', t => {
Expand Down

0 comments on commit 98040a9

Please sign in to comment.