|
|
|
/**
|
|
|
|
* @fileoverview Responsible for loading ignore config files and managing ignore patterns
|
|
|
|
* @author Jonathan Rajavuori
|
|
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Requirements
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
var fs = require("fs"),
|
|
|
|
debug = require("debug"),
|
|
|
|
minimatch = require("minimatch"),
|
|
|
|
FileFinder = require("./file-finder");
|
|
|
|
|
|
|
|
debug = debug("eslint:ignored-paths");
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Constants
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
var ESLINT_IGNORE_FILENAME = ".eslintignore";
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Helpers
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load and parse ignore patterns from the file at the given path
|
|
|
|
* @param {string} filepath Path to the ignore file.
|
|
|
|
* @returns {string[]} An array of ignore patterns or an empty array if no ignore file.
|
|
|
|
*/
|
|
|
|
function loadIgnoreFile(filepath) {
|
|
|
|
var ignorePatterns = [];
|
|
|
|
|
|
|
|
function nonEmpty(line) {
|
|
|
|
return line.trim() !== "" && line[0] !== "#";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filepath) {
|
|
|
|
try {
|
|
|
|
ignorePatterns = fs.readFileSync(filepath, "utf8").split(/\r?\n/).filter(nonEmpty);
|
|
|
|
} catch (e) {
|
|
|
|
e.message = "Cannot read ignore file: " + filepath + "\nError: " + e.message;
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ["node_modules/**"].concat(ignorePatterns);
|
|
|
|
}
|
|
|
|
|
|
|
|
var ignoreFileFinder;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find an ignore file in the current directory or a parent directory.
|
|
|
|
* @returns {string} Path of ignore file or an empty string.
|
|
|
|
*/
|
|
|
|
function findIgnoreFile() {
|
|
|
|
if (!ignoreFileFinder) {
|
|
|
|
ignoreFileFinder = new FileFinder(ESLINT_IGNORE_FILENAME);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ignoreFileFinder.findInDirectoryOrParents();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Public Interface
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/**
|
|
|
|
* IgnoredPaths
|
|
|
|
* @constructor
|
|
|
|
* @class IgnoredPaths
|
|
|
|
* @param {Array} patterns to be matched against file paths
|
|
|
|
*/
|
|
|
|
function IgnoredPaths(patterns) {
|
|
|
|
this.patterns = patterns;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* IgnoredPaths initializer
|
|
|
|
* @param {Object} options object containing 'ignore' and 'ignorePath' properties
|
|
|
|
* @returns {IgnoredPaths} object, with patterns loaded from the ignore file
|
|
|
|
*/
|
|
|
|
IgnoredPaths.load = function (options) {
|
|
|
|
var patterns;
|
|
|
|
|
|
|
|
options = options || {};
|
|
|
|
|
|
|
|
if (options.ignore) {
|
|
|
|
patterns = loadIgnoreFile(options.ignorePath || findIgnoreFile());
|
|
|
|
} else {
|
|
|
|
patterns = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.ignorePattern) {
|
|
|
|
patterns.push(options.ignorePattern);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new IgnoredPaths(patterns);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine whether a file path is included in the configured ignore patterns
|
|
|
|
* @param {string} filepath Path to check
|
|
|
|
* @returns {boolean} true if the file path matches one or more patterns, false otherwise
|
|
|
|
*/
|
|
|
|
IgnoredPaths.prototype.contains = function (filepath) {
|
|
|
|
if (this.patterns === null) {
|
|
|
|
throw new Error("No ignore patterns loaded, call 'load' first");
|
|
|
|
}
|
|
|
|
|
|
|
|
filepath = filepath.replace("\\", "/");
|
|
|
|
filepath = filepath.replace(/^\.\//, "");
|
|
|
|
return this.patterns.reduce(function(ignored, pattern) {
|
|
|
|
var negated = pattern[0] === "!",
|
|
|
|
matches;
|
|
|
|
|
|
|
|
if (negated) {
|
|
|
|
pattern = pattern.slice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove leading "current folder" prefix
|
|
|
|
if (pattern.indexOf("./") === 0) {
|
|
|
|
pattern = pattern.slice(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
matches = minimatch(filepath, pattern) || minimatch(filepath, pattern + "/**");
|
|
|
|
|
|
|
|
return matches ? !negated : ignored;
|
|
|
|
}, false);
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = IgnoredPaths;
|