UNPKG

4.06 kBJavaScriptView Raw
1/**
2 * @fileoverview Responsible for loading ignore config files and managing ignore patterns
3 * @author Jonathan Rajavuori
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Requirements
9//------------------------------------------------------------------------------
10
11var fs = require("fs"),
12 debug = require("debug"),
13 minimatch = require("minimatch"),
14 FileFinder = require("./file-finder");
15
16debug = debug("eslint:ignored-paths");
17
18
19//------------------------------------------------------------------------------
20// Constants
21//------------------------------------------------------------------------------
22
23var ESLINT_IGNORE_FILENAME = ".eslintignore";
24
25
26//------------------------------------------------------------------------------
27// Helpers
28//------------------------------------------------------------------------------
29
30/**
31 * Load and parse ignore patterns from the file at the given path
32 * @param {string} filepath Path to the ignore file.
33 * @returns {string[]} An array of ignore patterns or an empty array if no ignore file.
34 */
35function loadIgnoreFile(filepath) {
36 var ignorePatterns = [];
37
38 /**
39 * Check if string is not empty
40 * @param {string} line string to examine
41 * @returns {boolean} True is its not empty
42 * @private
43 */
44 function nonEmpty(line) {
45 return line.trim() !== "" && line[0] !== "#";
46 }
47
48 if (filepath) {
49 try {
50 ignorePatterns = fs.readFileSync(filepath, "utf8").split(/\r?\n/).filter(nonEmpty);
51 } catch (e) {
52 e.message = "Cannot read ignore file: " + filepath + "\nError: " + e.message;
53 throw e;
54 }
55 }
56
57 return ["node_modules/**"].concat(ignorePatterns);
58}
59
60var ignoreFileFinder;
61
62/**
63 * Find an ignore file in the current directory or a parent directory.
64 * @returns {string} Path of ignore file or an empty string.
65 */
66function findIgnoreFile() {
67 if (!ignoreFileFinder) {
68 ignoreFileFinder = new FileFinder(ESLINT_IGNORE_FILENAME);
69 }
70
71 return ignoreFileFinder.findInDirectoryOrParents();
72}
73
74
75//------------------------------------------------------------------------------
76// Public Interface
77//------------------------------------------------------------------------------
78
79/**
80 * IgnoredPaths
81 * @constructor
82 * @class IgnoredPaths
83 * @param {Array} patterns to be matched against file paths
84 */
85function IgnoredPaths(patterns) {
86 this.patterns = patterns;
87}
88
89/**
90 * IgnoredPaths initializer
91 * @param {Object} options object containing 'ignore' and 'ignorePath' properties
92 * @returns {IgnoredPaths} object, with patterns loaded from the ignore file
93 */
94IgnoredPaths.load = function(options) {
95 var patterns;
96
97 options = options || {};
98
99 if (options.ignore) {
100 patterns = loadIgnoreFile(options.ignorePath || findIgnoreFile());
101 } else {
102 patterns = [];
103 }
104
105 if (options.ignorePattern) {
106 patterns.push(options.ignorePattern);
107 }
108
109 return new IgnoredPaths(patterns);
110};
111
112/**
113 * Determine whether a file path is included in the configured ignore patterns
114 * @param {string} filepath Path to check
115 * @returns {boolean} true if the file path matches one or more patterns, false otherwise
116 */
117IgnoredPaths.prototype.contains = function(filepath) {
118 if (this.patterns === null) {
119 throw new Error("No ignore patterns loaded, call 'load' first");
120 }
121
122 filepath = filepath.replace("\\", "/");
123 filepath = filepath.replace(/^\.\//, "");
124 return this.patterns.reduce(function(ignored, pattern) {
125 var negated = pattern[0] === "!",
126 matches;
127
128 if (negated) {
129 pattern = pattern.slice(1);
130 }
131
132 // Remove leading "current folder" prefix
133 if (pattern.indexOf("./") === 0) {
134 pattern = pattern.slice(2);
135 }
136
137 matches = minimatch(filepath, pattern) || minimatch(filepath, pattern + "/**");
138
139 return matches ? !negated : ignored;
140 }, false);
141};
142
143module.exports = IgnoredPaths;