forked from mrmlnc/fast-glob
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtasks.ts
97 lines (77 loc) · 3.57 KB
/
tasks.ts
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
import Settings from '../settings';
import { Pattern, PatternsGroup } from '../types';
import * as utils from '../utils';
export type Task = {
base: string;
dynamic: boolean;
patterns: Pattern[];
positive: Pattern[];
negative: Pattern[];
};
export function generate(patterns: Pattern[], settings: Settings): Task[] {
const positivePatterns = getPositivePatterns(patterns);
const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore);
const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings));
const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings));
const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false);
const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true);
return staticTasks.concat(dynamicTasks);
}
/**
* Returns tasks grouped by basic pattern directories.
*
* Patterns that can be found inside (`./`) and outside (`../`) the current directory are handled separately.
* This is necessary because directory traversal starts at the base directory and goes deeper.
*/
export function convertPatternsToTasks(positive: Pattern[], negative: Pattern[], dynamic: boolean): Task[] {
const tasks: Task[] = [];
const patternsOutsideCurrentDirectory = utils.pattern.getPatternsOutsideCurrentDirectory(positive);
const patternsInsideCurrentDirectory = utils.pattern.getPatternsInsideCurrentDirectory(positive);
const outsideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsOutsideCurrentDirectory);
const insideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsInsideCurrentDirectory);
tasks.push(...convertPatternGroupsToTasks(outsideCurrentDirectoryGroup, negative, dynamic));
/*
* For the sake of reducing future accesses to the file system, we merge all tasks within the current directory
* into a global task, if at least one pattern refers to the root (`.`). In this case, the global task covers the rest.
*/
if ('.' in insideCurrentDirectoryGroup) {
tasks.push(convertPatternGroupToTask('.', patternsInsideCurrentDirectory, negative, dynamic));
} else {
tasks.push(...convertPatternGroupsToTasks(insideCurrentDirectoryGroup, negative, dynamic));
}
return tasks;
}
export function getPositivePatterns(patterns: Pattern[]): Pattern[] {
return utils.pattern.getPositivePatterns(patterns);
}
export function getNegativePatternsAsPositive(patterns: Pattern[], ignore: Pattern[]): Pattern[] {
const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore);
const positive = negative.map(utils.pattern.convertToPositivePattern);
return positive;
}
export function groupPatternsByBaseDirectory(patterns: Pattern[]): PatternsGroup {
const group: PatternsGroup = {};
return patterns.reduce((collection, pattern) => {
const base = utils.pattern.getBaseDirectory(pattern);
if (base in collection) {
collection[base].push(pattern);
} else {
collection[base] = [pattern];
}
return collection;
}, group);
}
export function convertPatternGroupsToTasks(positive: PatternsGroup, negative: Pattern[], dynamic: boolean): Task[] {
return Object.keys(positive).map((base) => {
return convertPatternGroupToTask(base, positive[base], negative, dynamic);
});
}
export function convertPatternGroupToTask(base: string, positive: Pattern[], negative: Pattern[], dynamic: boolean): Task {
return {
dynamic,
positive,
negative,
base,
patterns: ([] as Pattern[]).concat(positive, negative.map(utils.pattern.convertToNegativePattern))
};
}