ignore.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // give it a pattern, and it'll be able to tell you if
  2. // a given path should be ignored.
  3. // Ignoring a path ignores its children if the pattern ends in /**
  4. // Ignores are always parsed in dot:true mode
  5. import { Minimatch } from 'minimatch';
  6. import { Pattern } from './pattern.js';
  7. const defaultPlatform = (typeof process === 'object' &&
  8. process &&
  9. typeof process.platform === 'string') ?
  10. process.platform
  11. : 'linux';
  12. /**
  13. * Class used to process ignored patterns
  14. */
  15. export class Ignore {
  16. relative;
  17. relativeChildren;
  18. absolute;
  19. absoluteChildren;
  20. platform;
  21. mmopts;
  22. constructor(ignored, { nobrace, nocase, noext, noglobstar, platform = defaultPlatform, }) {
  23. this.relative = [];
  24. this.absolute = [];
  25. this.relativeChildren = [];
  26. this.absoluteChildren = [];
  27. this.platform = platform;
  28. this.mmopts = {
  29. dot: true,
  30. nobrace,
  31. nocase,
  32. noext,
  33. noglobstar,
  34. optimizationLevel: 2,
  35. platform,
  36. nocomment: true,
  37. nonegate: true,
  38. };
  39. for (const ign of ignored)
  40. this.add(ign);
  41. }
  42. add(ign) {
  43. // this is a little weird, but it gives us a clean set of optimized
  44. // minimatch matchers, without getting tripped up if one of them
  45. // ends in /** inside a brace section, and it's only inefficient at
  46. // the start of the walk, not along it.
  47. // It'd be nice if the Pattern class just had a .test() method, but
  48. // handling globstars is a bit of a pita, and that code already lives
  49. // in minimatch anyway.
  50. // Another way would be if maybe Minimatch could take its set/globParts
  51. // as an option, and then we could at least just use Pattern to test
  52. // for absolute-ness.
  53. // Yet another way, Minimatch could take an array of glob strings, and
  54. // a cwd option, and do the right thing.
  55. const mm = new Minimatch(ign, this.mmopts);
  56. for (let i = 0; i < mm.set.length; i++) {
  57. const parsed = mm.set[i];
  58. const globParts = mm.globParts[i];
  59. /* c8 ignore start */
  60. if (!parsed || !globParts) {
  61. throw new Error('invalid pattern object');
  62. }
  63. // strip off leading ./ portions
  64. // https://github.com/isaacs/node-glob/issues/570
  65. while (parsed[0] === '.' && globParts[0] === '.') {
  66. parsed.shift();
  67. globParts.shift();
  68. }
  69. /* c8 ignore stop */
  70. const p = new Pattern(parsed, globParts, 0, this.platform);
  71. const m = new Minimatch(p.globString(), this.mmopts);
  72. const children = globParts[globParts.length - 1] === '**';
  73. const absolute = p.isAbsolute();
  74. if (absolute)
  75. this.absolute.push(m);
  76. else
  77. this.relative.push(m);
  78. if (children) {
  79. if (absolute)
  80. this.absoluteChildren.push(m);
  81. else
  82. this.relativeChildren.push(m);
  83. }
  84. }
  85. }
  86. ignored(p) {
  87. const fullpath = p.fullpath();
  88. const fullpaths = `${fullpath}/`;
  89. const relative = p.relative() || '.';
  90. const relatives = `${relative}/`;
  91. for (const m of this.relative) {
  92. if (m.match(relative) || m.match(relatives))
  93. return true;
  94. }
  95. for (const m of this.absolute) {
  96. if (m.match(fullpath) || m.match(fullpaths))
  97. return true;
  98. }
  99. return false;
  100. }
  101. childrenIgnored(p) {
  102. const fullpath = p.fullpath() + '/';
  103. const relative = (p.relative() || '.') + '/';
  104. for (const m of this.relativeChildren) {
  105. if (m.match(relative))
  106. return true;
  107. }
  108. for (const m of this.absoluteChildren) {
  109. if (m.match(fullpath))
  110. return true;
  111. }
  112. return false;
  113. }
  114. }
  115. //# sourceMappingURL=ignore.js.map