This repository has been archived by the owner on Apr 6, 2021. It is now read-only.
forked from gjtorikian/nak
/
path-filter.js
124 lines (107 loc) · 3 KB
/
path-filter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
function PathFilter(inclusions, exclusions, showHidden) {
if (!Array.isArray(inclusions)) {
this.inclusionRe = inclusions || /^/;
this.exclusionRe = exclusions || /^/;
return;
}
var pos = [], neg = [];
if (showHidden !== true)
neg.push(".*");
var hasDirectoryMatcher = false;
var hasFileMatcher = false;
inclusions.forEach(function(p) {
p = p.trim(); // TODO this isn't gitignore compatible
if (!p || p[0] === "#")
return;
if (/\/\*?$/.test(p) || !/[.*]/.test(p)) {
hasDirectoryMatcher = true;
p = p.replace(/\/\*?$/, "");
pos.push(p, p + "/*");
} else {
hasFileMatcher = true;
pos.push(p);
}
});
if (pos.length) {
if (!hasDirectoryMatcher)
pos.push("/");
}
exclusions.forEach(function(p) {
p = p.trim();
if (!p || p[0] === "#")
return;
neg.push(p);
});
var inc = this.createMatcherRe(pos);
var exc = this.createMatcherRe(neg);
if (!inc && !exc) {
this.isPathAccepted = function(filepath) { return true; };
} if (!inc && exc && !exc.hasNegative) {
var re = exc.re;
this.isPathAccepted = function(filepath) {
return !re.test(filepath);
};
} else if (!inc && exc && exc.hasNegative) {
var re1 = exc.re;
this.isPathAccepted = function(filepath) {
var m = re1.exec(filepath);
return !(m && m[0]);
};
} else if (inc && exc) {
var excRe = exc.re, incRe = inc.re;
this.isPathAccepted = function(filepath) {
var m = excRe.exec(filepath);
if (m && m[0]) return false;
m = incRe.exec(filepath);
return !!(m && m[0]);
};
}
this.inclusionRe = inc && inc.re || /^/;
this.exclusionRe = exc && exc.re || /^/;
}
PathFilter.prototype.isPathAccepted = function(filepath) {
return !this.exclusionRe.test(filepath) || this.inclusionRe.test(filepath);
};
PathFilter.prototype.createMatcherRe = function(patterns) {
var source = "";
var hasNegative = false;
source = patterns.map(function(p) {
var contents = p;
var isNegated = p[0] === "!";
if (isNegated) {
contents = contents.slice(1);
hasNegative = true;
}
var reg = contents.replace(/(\\.)|(\*{1,2})|(\+)|([\/'*+?|()\[\]{}.\^$])/g, function(_, esc, star, plus, reg) {
if (esc)
return esc[1];
if (plus)
return ".+";
if (star)
return star[1] ? ".*?" : "[^\\/]*";
if (reg)
return "\\" + reg;
});
if (reg[1] !== "/")
reg = "\\/" + reg;
if (reg[reg.length - 1] === "\\")
reg = reg.slice(0, -1);
else if (reg[reg.length - 1] !== "/")
reg += "\\/?";
if (isNegated)
reg = "(?=" + reg + "$)";
else
reg = "(?:" + reg + "$)";
return reg;
}).filter(Boolean).join("|");
if (!source)
return;
return {
re: new RegExp(source, ""),
hasNegative: hasNegative
};
};
PathFilter.escapeRegExp = function(str) {
return str.replace(/([\/'*+?|()\[\]{}.\^$])/g, '\\$1');
};
module.exports = PathFilter;