UNPKG

2.86 kBPlain TextView Raw
1import { toPosixPath } from "furi";
2import minimatch from "minimatch";
3import { parseSys as parseNodeScriptUrl } from "node-script-url";
4import sysPath from "path";
5import url from "url";
6
7export interface ModuleInfo {
8 url: string;
9 isModule?: boolean;
10}
11
12export type CoverageFilter = (info: ModuleInfo) => boolean;
13
14export interface FromGlobOptions {
15 patterns: ReadonlyArray<string>;
16
17 /**
18 * Base file URL for relative patterns.
19 */
20 base?: url.URL;
21}
22
23interface FuriMatch {
24 type: "negative" | "positive";
25 regexp: RegExp;
26}
27
28export function fromGlob(options: FromGlobOptions): CoverageFilter {
29 let basePath: string | undefined;
30 if (options.base !== undefined) {
31 basePath = toPosixPath(options.base.href);
32 }
33
34 const matches: FuriMatch[] = [];
35 const patterns: ReadonlyArray<string> = [...options.patterns];
36 for (const pattern of patterns) {
37 let absPattern: string;
38 let type: "negative" | "positive";
39 if (pattern.startsWith("!")) {
40 absPattern = pattern.substr(1);
41 type = "negative";
42 } else {
43 absPattern = pattern;
44 type = "positive";
45 }
46 const resolvedPattern: string = basePath !== undefined ? sysPath.resolve(basePath, absPattern) : absPattern;
47 matches.push({
48 type,
49 regexp: minimatch.makeRe(resolvedPattern, {dot: true}),
50 });
51 // Fix bad wildstar conversion to RegExp
52 if (absPattern.startsWith("**/")) {
53 const patternTail: string = absPattern.substr("**/".length);
54 const resolvedPattern: string = basePath !== undefined ? sysPath.resolve(basePath, patternTail) : patternTail;
55 matches.push({
56 type,
57 regexp: minimatch.makeRe(resolvedPattern, {dot: true}),
58 });
59 }
60 }
61
62 return function filter(info: ModuleInfo): boolean {
63 if (!isRegularFile(info)) {
64 return false;
65 }
66 const posixPath: string = toPosixPath(info.url);
67 for (const match of matches) {
68 if (match.regexp.test(posixPath)) {
69 return match.type === "positive";
70 }
71 }
72 return false;
73 };
74}
75
76export function isRegularFile(info: ModuleInfo): boolean {
77 return parseNodeScriptUrl(info.url).isFileUrl;
78}
79
80// function inCwd(info: ModuleInfo): boolean {
81// const scriptUrl: ParsedScriptUrl = parseNodeScriptUrl(info.url);
82// if (!scriptUrl.isFileUrl) {
83// return false;
84// }
85// const cwdFuri: string = fromSysPath(sysPath.resolve(process.cwd())).href;
86// return isDescendantOf(scriptUrl.url, cwdFuri);
87// }
88
89// function isDescendantOf(curUrl: string, ancestorUrl: string): boolean {
90// const cur: ReadonlyArray<string> = new url.URL(curUrl).pathname.split("/");
91// const ancestor: ReadonlyArray<string> = new url.URL(ancestorUrl).pathname.split("/");
92// for (const [i, segment] of ancestor.entries()) {
93// if (cur[i] !== segment) {
94// return false;
95// }
96// }
97// return true;
98// }