项目原始demo,不改动
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
Это архивный репозиторий. Вы можете его клонировать или просматривать файлы, но не вносить изменения или открывать задачи/запросы на слияние.
 
 
 
 

290 строки
9.2 KiB

  1. /**
  2. * @fileoverview Responsible for loading ignore config files and managing ignore patterns
  3. * @author Jonathan Rajavuori
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const fs = require("fs"),
  10. path = require("path"),
  11. ignore = require("ignore"),
  12. pathUtil = require("./util/path-util");
  13. const debug = require("debug")("eslint:ignored-paths");
  14. //------------------------------------------------------------------------------
  15. // Constants
  16. //------------------------------------------------------------------------------
  17. const ESLINT_IGNORE_FILENAME = ".eslintignore";
  18. /**
  19. * Adds `"*"` at the end of `"node_modules/"`,
  20. * so that subtle directories could be re-included by .gitignore patterns
  21. * such as `"!node_modules/should_not_ignored"`
  22. */
  23. const DEFAULT_IGNORE_DIRS = [
  24. "/node_modules/*",
  25. "/bower_components/*"
  26. ];
  27. const DEFAULT_OPTIONS = {
  28. dotfiles: false,
  29. cwd: process.cwd()
  30. };
  31. //------------------------------------------------------------------------------
  32. // Helpers
  33. //------------------------------------------------------------------------------
  34. /**
  35. * Find a file in the current directory.
  36. * @param {string} cwd Current working directory
  37. * @param {string} name File name
  38. * @returns {string} Path of ignore file or an empty string.
  39. */
  40. function findFile(cwd, name) {
  41. const ignoreFilePath = path.resolve(cwd, name);
  42. return fs.existsSync(ignoreFilePath) && fs.statSync(ignoreFilePath).isFile() ? ignoreFilePath : "";
  43. }
  44. /**
  45. * Find an ignore file in the current directory.
  46. * @param {string} cwd Current working directory
  47. * @returns {string} Path of ignore file or an empty string.
  48. */
  49. function findIgnoreFile(cwd) {
  50. return findFile(cwd, ESLINT_IGNORE_FILENAME);
  51. }
  52. /**
  53. * Find an package.json file in the current directory.
  54. * @param {string} cwd Current working directory
  55. * @returns {string} Path of package.json file or an empty string.
  56. */
  57. function findPackageJSONFile(cwd) {
  58. return findFile(cwd, "package.json");
  59. }
  60. /**
  61. * Merge options with defaults
  62. * @param {Object} options Options to merge with DEFAULT_OPTIONS constant
  63. * @returns {Object} Merged options
  64. */
  65. function mergeDefaultOptions(options) {
  66. return Object.assign({}, DEFAULT_OPTIONS, options);
  67. }
  68. //------------------------------------------------------------------------------
  69. // Public Interface
  70. //------------------------------------------------------------------------------
  71. /**
  72. * IgnoredPaths class
  73. */
  74. class IgnoredPaths {
  75. /**
  76. * @param {Object} providedOptions object containing 'ignore', 'ignorePath' and 'patterns' properties
  77. */
  78. constructor(providedOptions) {
  79. const options = mergeDefaultOptions(providedOptions);
  80. this.cache = {};
  81. /**
  82. * add pattern to node-ignore instance
  83. * @param {Object} ig, instance of node-ignore
  84. * @param {string} pattern, pattern do add to ig
  85. * @returns {array} raw ignore rules
  86. */
  87. function addPattern(ig, pattern) {
  88. return ig.addPattern(pattern);
  89. }
  90. this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []);
  91. this.baseDir = options.cwd;
  92. this.ig = {
  93. custom: ignore(),
  94. default: ignore()
  95. };
  96. /*
  97. * Add a way to keep track of ignored files. This was present in node-ignore
  98. * 2.x, but dropped for now as of 3.0.10.
  99. */
  100. this.ig.custom.ignoreFiles = [];
  101. this.ig.default.ignoreFiles = [];
  102. if (options.dotfiles !== true) {
  103. /*
  104. * ignore files beginning with a dot, but not files in a parent or
  105. * ancestor directory (which in relative format will begin with `../`).
  106. */
  107. addPattern(this.ig.default, [".*", "!../"]);
  108. }
  109. addPattern(this.ig.default, this.defaultPatterns);
  110. if (options.ignore !== false) {
  111. let ignorePath;
  112. if (options.ignorePath) {
  113. debug("Using specific ignore file");
  114. try {
  115. fs.statSync(options.ignorePath);
  116. ignorePath = options.ignorePath;
  117. } catch (e) {
  118. e.message = `Cannot read ignore file: ${options.ignorePath}\nError: ${e.message}`;
  119. throw e;
  120. }
  121. } else {
  122. debug(`Looking for ignore file in ${options.cwd}`);
  123. ignorePath = findIgnoreFile(options.cwd);
  124. try {
  125. fs.statSync(ignorePath);
  126. debug(`Loaded ignore file ${ignorePath}`);
  127. } catch (e) {
  128. debug("Could not find ignore file in cwd");
  129. this.options = options;
  130. }
  131. }
  132. if (ignorePath) {
  133. debug(`Adding ${ignorePath}`);
  134. this.baseDir = path.dirname(path.resolve(options.cwd, ignorePath));
  135. this.addIgnoreFile(this.ig.custom, ignorePath);
  136. this.addIgnoreFile(this.ig.default, ignorePath);
  137. } else {
  138. try {
  139. // if the ignoreFile does not exist, check package.json for eslintIgnore
  140. const packageJSONPath = findPackageJSONFile(options.cwd);
  141. if (packageJSONPath) {
  142. let packageJSONOptions;
  143. try {
  144. packageJSONOptions = JSON.parse(fs.readFileSync(packageJSONPath, "utf8"));
  145. } catch (e) {
  146. debug("Could not read package.json file to check eslintIgnore property");
  147. throw e;
  148. }
  149. if (packageJSONOptions.eslintIgnore) {
  150. if (Array.isArray(packageJSONOptions.eslintIgnore)) {
  151. packageJSONOptions.eslintIgnore.forEach(pattern => {
  152. addPattern(this.ig.custom, pattern);
  153. addPattern(this.ig.default, pattern);
  154. });
  155. } else {
  156. throw new TypeError("Package.json eslintIgnore property requires an array of paths");
  157. }
  158. }
  159. }
  160. } catch (e) {
  161. debug("Could not find package.json to check eslintIgnore property");
  162. throw e;
  163. }
  164. }
  165. if (options.ignorePattern) {
  166. addPattern(this.ig.custom, options.ignorePattern);
  167. addPattern(this.ig.default, options.ignorePattern);
  168. }
  169. }
  170. this.options = options;
  171. }
  172. /**
  173. * read ignore filepath
  174. * @param {string} filePath, file to add to ig
  175. * @returns {array} raw ignore rules
  176. */
  177. readIgnoreFile(filePath) {
  178. if (typeof this.cache[filePath] === "undefined") {
  179. this.cache[filePath] = fs.readFileSync(filePath, "utf8");
  180. }
  181. return this.cache[filePath];
  182. }
  183. /**
  184. * add ignore file to node-ignore instance
  185. * @param {Object} ig, instance of node-ignore
  186. * @param {string} filePath, file to add to ig
  187. * @returns {array} raw ignore rules
  188. */
  189. addIgnoreFile(ig, filePath) {
  190. ig.ignoreFiles.push(filePath);
  191. return ig.add(this.readIgnoreFile(filePath));
  192. }
  193. /**
  194. * Determine whether a file path is included in the default or custom ignore patterns
  195. * @param {string} filepath Path to check
  196. * @param {string} [category=null] check 'default', 'custom' or both (null)
  197. * @returns {boolean} true if the file path matches one or more patterns, false otherwise
  198. */
  199. contains(filepath, category) {
  200. let result = false;
  201. const absolutePath = path.resolve(this.options.cwd, filepath);
  202. const relativePath = pathUtil.getRelativePath(absolutePath, this.baseDir);
  203. if ((typeof category === "undefined") || (category === "default")) {
  204. result = result || (this.ig.default.filter([relativePath]).length === 0);
  205. }
  206. if ((typeof category === "undefined") || (category === "custom")) {
  207. result = result || (this.ig.custom.filter([relativePath]).length === 0);
  208. }
  209. return result;
  210. }
  211. /**
  212. * Returns a list of dir patterns for glob to ignore
  213. * @returns {function()} method to check whether a folder should be ignored by glob.
  214. */
  215. getIgnoredFoldersGlobChecker() {
  216. const ig = ignore().add(DEFAULT_IGNORE_DIRS);
  217. if (this.options.dotfiles !== true) {
  218. // Ignore hidden folders. (This cannot be ".*", or else it's not possible to unignore hidden files)
  219. ig.add([".*/*", "!../"]);
  220. }
  221. if (this.options.ignore) {
  222. ig.add(this.ig.custom);
  223. }
  224. const filter = ig.createFilter();
  225. const base = this.baseDir;
  226. return function(absolutePath) {
  227. const relative = pathUtil.getRelativePath(absolutePath, base);
  228. if (!relative) {
  229. return false;
  230. }
  231. return !filter(relative);
  232. };
  233. }
  234. }
  235. module.exports = IgnoredPaths;