Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ignore-pattern.js 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /**
  2. * @fileoverview `IgnorePattern` class.
  3. *
  4. * `IgnorePattern` class has the set of glob patterns and the base path.
  5. *
  6. * It provides two static methods.
  7. *
  8. * - `IgnorePattern.createDefaultIgnore(cwd)`
  9. * Create the default predicate function.
  10. * - `IgnorePattern.createIgnore(ignorePatterns)`
  11. * Create the predicate function from multiple `IgnorePattern` objects.
  12. *
  13. * It provides two properties and a method.
  14. *
  15. * - `patterns`
  16. * The glob patterns that ignore to lint.
  17. * - `basePath`
  18. * The base path of the glob patterns. If absolute paths existed in the
  19. * glob patterns, those are handled as relative paths to the base path.
  20. * - `getPatternsRelativeTo(basePath)`
  21. * Get `patterns` as modified for a given base path. It modifies the
  22. * absolute paths in the patterns as prepending the difference of two base
  23. * paths.
  24. *
  25. * `ConfigArrayFactory` creates `IgnorePattern` objects when it processes
  26. * `ignorePatterns` properties.
  27. *
  28. * @author Toru Nagashima <https://github.com/mysticatea>
  29. */
  30. "use strict";
  31. //------------------------------------------------------------------------------
  32. // Requirements
  33. //------------------------------------------------------------------------------
  34. const assert = require("assert");
  35. const path = require("path");
  36. const ignore = require("ignore");
  37. const debug = require("debug")("eslintrc:ignore-pattern");
  38. /** @typedef {ReturnType<import("ignore").default>} Ignore */
  39. //------------------------------------------------------------------------------
  40. // Helpers
  41. //------------------------------------------------------------------------------
  42. /**
  43. * Get the path to the common ancestor directory of given paths.
  44. * @param {string[]} sourcePaths The paths to calculate the common ancestor.
  45. * @returns {string} The path to the common ancestor directory.
  46. */
  47. function getCommonAncestorPath(sourcePaths) {
  48. let result = sourcePaths[0];
  49. for (let i = 1; i < sourcePaths.length; ++i) {
  50. const a = result;
  51. const b = sourcePaths[i];
  52. // Set the shorter one (it's the common ancestor if one includes the other).
  53. result = a.length < b.length ? a : b;
  54. // Set the common ancestor.
  55. for (let j = 0, lastSepPos = 0; j < a.length && j < b.length; ++j) {
  56. if (a[j] !== b[j]) {
  57. result = a.slice(0, lastSepPos);
  58. break;
  59. }
  60. if (a[j] === path.sep) {
  61. lastSepPos = j;
  62. }
  63. }
  64. }
  65. let resolvedResult = result || path.sep;
  66. // if Windows common ancestor is root of drive must have trailing slash to be absolute.
  67. if (resolvedResult && resolvedResult.endsWith(":") && process.platform === "win32") {
  68. resolvedResult += path.sep;
  69. }
  70. return resolvedResult;
  71. }
  72. /**
  73. * Make relative path.
  74. * @param {string} from The source path to get relative path.
  75. * @param {string} to The destination path to get relative path.
  76. * @returns {string} The relative path.
  77. */
  78. function relative(from, to) {
  79. const relPath = path.relative(from, to);
  80. if (path.sep === "/") {
  81. return relPath;
  82. }
  83. return relPath.split(path.sep).join("/");
  84. }
  85. /**
  86. * Get the trailing slash if existed.
  87. * @param {string} filePath The path to check.
  88. * @returns {string} The trailing slash if existed.
  89. */
  90. function dirSuffix(filePath) {
  91. const isDir = (
  92. filePath.endsWith(path.sep) ||
  93. (process.platform === "win32" && filePath.endsWith("/"))
  94. );
  95. return isDir ? "/" : "";
  96. }
  97. const DefaultPatterns = Object.freeze(["/**/node_modules/*"]);
  98. const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]);
  99. //------------------------------------------------------------------------------
  100. // Public
  101. //------------------------------------------------------------------------------
  102. class IgnorePattern {
  103. /**
  104. * The default patterns.
  105. * @type {string[]}
  106. */
  107. static get DefaultPatterns() {
  108. return DefaultPatterns;
  109. }
  110. /**
  111. * Create the default predicate function.
  112. * @param {string} cwd The current working directory.
  113. * @returns {((filePath:string, dot:boolean) => boolean) & {basePath:string; patterns:string[]}}
  114. * The preficate function.
  115. * The first argument is an absolute path that is checked.
  116. * The second argument is the flag to not ignore dotfiles.
  117. * If the predicate function returned `true`, it means the path should be ignored.
  118. */
  119. static createDefaultIgnore(cwd) {
  120. return this.createIgnore([new IgnorePattern(DefaultPatterns, cwd)]);
  121. }
  122. /**
  123. * Create the predicate function from multiple `IgnorePattern` objects.
  124. * @param {IgnorePattern[]} ignorePatterns The list of ignore patterns.
  125. * @returns {((filePath:string, dot?:boolean) => boolean) & {basePath:string; patterns:string[]}}
  126. * The preficate function.
  127. * The first argument is an absolute path that is checked.
  128. * The second argument is the flag to not ignore dotfiles.
  129. * If the predicate function returned `true`, it means the path should be ignored.
  130. */
  131. static createIgnore(ignorePatterns) {
  132. debug("Create with: %o", ignorePatterns);
  133. const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath));
  134. const patterns = [].concat(
  135. ...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath))
  136. );
  137. const ig = ignore().add([...DotPatterns, ...patterns]);
  138. const dotIg = ignore().add(patterns);
  139. debug(" processed: %o", { basePath, patterns });
  140. return Object.assign(
  141. (filePath, dot = false) => {
  142. assert(path.isAbsolute(filePath), "'filePath' should be an absolute path.");
  143. const relPathRaw = relative(basePath, filePath);
  144. const relPath = relPathRaw && (relPathRaw + dirSuffix(filePath));
  145. const adoptedIg = dot ? dotIg : ig;
  146. const result = relPath !== "" && adoptedIg.ignores(relPath);
  147. debug("Check", { filePath, dot, relativePath: relPath, result });
  148. return result;
  149. },
  150. { basePath, patterns }
  151. );
  152. }
  153. /**
  154. * Initialize a new `IgnorePattern` instance.
  155. * @param {string[]} patterns The glob patterns that ignore to lint.
  156. * @param {string} basePath The base path of `patterns`.
  157. */
  158. constructor(patterns, basePath) {
  159. assert(path.isAbsolute(basePath), "'basePath' should be an absolute path.");
  160. /**
  161. * The glob patterns that ignore to lint.
  162. * @type {string[]}
  163. */
  164. this.patterns = patterns;
  165. /**
  166. * The base path of `patterns`.
  167. * @type {string}
  168. */
  169. this.basePath = basePath;
  170. /**
  171. * If `true` then patterns which don't start with `/` will match the paths to the outside of `basePath`. Defaults to `false`.
  172. *
  173. * It's set `true` for `.eslintignore`, `package.json`, and `--ignore-path` for backward compatibility.
  174. * It's `false` as-is for `ignorePatterns` property in config files.
  175. * @type {boolean}
  176. */
  177. this.loose = false;
  178. }
  179. /**
  180. * Get `patterns` as modified for a given base path. It modifies the
  181. * absolute paths in the patterns as prepending the difference of two base
  182. * paths.
  183. * @param {string} newBasePath The base path.
  184. * @returns {string[]} Modifired patterns.
  185. */
  186. getPatternsRelativeTo(newBasePath) {
  187. assert(path.isAbsolute(newBasePath), "'newBasePath' should be an absolute path.");
  188. const { basePath, loose, patterns } = this;
  189. if (newBasePath === basePath) {
  190. return patterns;
  191. }
  192. const prefix = `/${relative(newBasePath, basePath)}`;
  193. return patterns.map(pattern => {
  194. const negative = pattern.startsWith("!");
  195. const head = negative ? "!" : "";
  196. const body = negative ? pattern.slice(1) : pattern;
  197. if (body.startsWith("/") || body.startsWith("../")) {
  198. return `${head}${prefix}${body}`;
  199. }
  200. return loose ? pattern : `${head}${prefix}/**/${body}`;
  201. });
  202. }
  203. }
  204. module.exports = { IgnorePattern };