2
2
3
3
const log = require ( "@ui5/logger" ) . getLogger ( "lbt:resources:ResourceFilterList" ) ;
4
4
5
- function makeMatcher ( globPattern ) {
5
+ function makeFileTypePattern ( fileTypes ) {
6
+ if ( fileTypes == null ) {
7
+ return undefined ;
8
+ }
9
+ return "(?:" + fileTypes . map ( ( type ) => {
10
+ if ( ! type . startsWith ( "." ) ) {
11
+ type = "." + type ;
12
+ }
13
+ return type . replace ( / [ * + ? . ( ) | ^ $ ] / g, "\\$&" ) ;
14
+ } ) . join ( "|" ) + ")" ;
15
+ }
16
+
17
+ function makeMatcher ( globPattern , fileTypesPattern ) {
6
18
const result = {
7
19
pattern : globPattern ,
8
20
include : true
@@ -14,29 +26,53 @@ function makeMatcher(globPattern) {
14
26
globPattern = globPattern . slice ( 1 ) ;
15
27
}
16
28
17
- // check for wildcards
18
- if ( / \* | \/ $ / . test ( globPattern ) ) {
19
- if ( ! / \/ \* \* \/ $ / . test ( globPattern ) ) {
20
- globPattern = globPattern . replace ( / \/ $ / , "/**/" ) ;
29
+ // normalize some convenience shortcuts
30
+ // - a lonely 'any sub-path' pattern implies the 'any file' pattern:
31
+ // "**/" --> "**/*"
32
+ // - a trailing 'any sub-path' pattern also implies the 'any file' pattern:
33
+ // ".../foo/**/" --> "../foo/**/*"
34
+ // - any other trailing slash matches any files in any sub-folder:
35
+ // ".../foo/" --> ".../foo/**/*"
36
+ if ( globPattern . endsWith ( "/" ) ) {
37
+ if ( globPattern === "**/" || globPattern . endsWith ( "/**/" ) ) {
38
+ globPattern = globPattern + "*" ;
39
+ } else {
40
+ globPattern = globPattern + "**/*" ;
21
41
}
42
+ }
22
43
23
- const regexp = globPattern . replace ( / \* \* \/ | \* | [ [ \] { } ( ) + ? . \\ ^ $ | ] / g, function ( match ) {
44
+ // check for wildcards
45
+ if ( / \* / . test ( globPattern ) ) {
46
+ // Transform the globPattern into a regular expression pattern by converting
47
+ // the "all sub-directories" pattern "/**/" and the "any file name" pattern "*"
48
+ // to their respective regexp counterparts and escape all other regexp special
49
+ // characters.
50
+ let regexp = globPattern . replace ( / ^ \* \* \/ | \/ \* \* \/ | \* | [ [ \] { } ( ) + ? . \\ ^ $ | ] / g, ( match ) => {
24
51
switch ( match ) {
25
52
case "**/" : return "(?:[^/]+/)*" ;
53
+ case "/**/" : return "/(?:[^/]+/)*" ;
26
54
case "*" : return "[^/]*" ;
27
55
default : return "\\" + match ;
28
56
}
29
57
} ) ;
30
58
31
- log . verbose ( "%s -> %s,%s" , result . pattern , "^" + regexp , result . include ? "include" : "exclude" ) ;
32
- result . regexp = new RegExp ( "^" + regexp ) ;
59
+ // if the pattern ended with an asterisk and if a default file type pattern is defined,
60
+ // add that pattern. This limits the matches to the specified set of file types
61
+ if ( fileTypesPattern != null && regexp . endsWith ( "[^/]*" ) ) {
62
+ regexp = regexp + fileTypesPattern ;
63
+ }
64
+
65
+ result . regexp = new RegExp ( "^" + regexp + "$" ) ;
33
66
result . calcMatch = result . include ? function ( candidate , matchSoFar ) {
34
67
return matchSoFar || this . regexp . test ( candidate ) ;
35
68
} : function ( candidate , matchSoFar ) {
36
69
return matchSoFar && ! this . regexp . test ( candidate ) ;
37
70
} ;
71
+
72
+ log . verbose ( ` ${ result . pattern } --> ${ result . include ? "include" : "exclude" } : /${ result . regexp . source } /` ) ;
38
73
} else {
39
74
result . value = globPattern ;
75
+ log . verbose ( ` ${ result . pattern } --> ${ result . include ? "include" : "exclude" } : "${ globPattern } "` ) ;
40
76
result . calcMatch = result . include ? function ( candidate , matchSoFar ) {
41
77
return matchSoFar || candidate === this . value ;
42
78
} : function ( candidate , matchSoFar ) {
@@ -56,19 +92,20 @@ function makeMatcher(globPattern) {
56
92
* @author Frank Weigel
57
93
* @since 1.16.2
58
94
* @private
59
- * TODO Share with plugins, esp. coldWater, lightening, ...
60
95
*/
61
96
class ResourceFilterList {
62
- constructor ( filters ) {
97
+ constructor ( filters , fileTypes ) {
63
98
this . matchers = [ ] ;
64
99
this . matchByDefault = true ;
100
+ this . fileTypes = makeFileTypePattern ( fileTypes ) ;
101
+ log . verbose ( `filetypes: ${ fileTypes } ` ) ;
65
102
this . addFilters ( filters ) ;
66
103
}
67
104
68
105
addFilters ( filters ) {
69
106
if ( Array . isArray ( filters ) ) {
70
107
filters . forEach ( ( filter ) => {
71
- const matcher = makeMatcher ( filter ) ;
108
+ const matcher = makeMatcher ( filter , this . fileTypes ) ;
72
109
this . matchers . push ( matcher ) ;
73
110
this . matchByDefault = this . matchByDefault && ! matcher . include ;
74
111
} ) ;
@@ -78,59 +115,6 @@ class ResourceFilterList {
78
115
return this ;
79
116
}
80
117
81
- /* NODE-TODO
82
- public ResourceFilterList addIncludes(String[] includes){
83
- if ( includes != null ) {
84
- for(String include : includes) {
85
- add(include, false);
86
- }
87
- }
88
- return this;
89
- }
90
-
91
- public ResourceFilterList addExcludes(String[] excludes) {
92
- if ( excludes != null ) {
93
- for(String exclude : excludes) {
94
- add(exclude, true);
95
- }
96
- }
97
- return this;
98
- }
99
-
100
- /**
101
- * old style resource pattern (from old Optimizer)
102
- * @param excludePattern
103
- * @deprecated Use the more flexible add or addFilters instead.
104
- *
105
- public void addExcludePattern(Pattern excludePattern) {
106
- isExclude.set(patterns.size(), true);
107
- patterns.add(excludePattern);
108
- }
109
-
110
- public ResourceFilterList add(String patternList, boolean exclude) {
111
- for(String pattern : patternList.trim().split("\\s*,\\s*")) {
112
- if ( !pattern.isEmpty() ) {
113
- isExclude.set(patterns.size(), exclude);
114
- patterns.add(ModuleNamePattern.createRegEx(pattern, ignoreCase));
115
- hasInclude = hasInclude || !exclude;
116
- }
117
- }
118
- return this;
119
- }
120
-
121
- public ResourceFilterList add(String patternList) {
122
- for(String pattern : patternList.trim().split("\\s*,\\s*")) {
123
- if ( !pattern.isEmpty() ) {
124
- boolean exclude = pattern.startsWith("!") || pattern.startsWith("-");
125
- isExclude.set(patterns.size(), exclude);
126
- patterns.add(ModuleNamePattern.createRegEx(exclude || pattern.startsWith("+")
127
- ? pattern.substring(1) : pattern, ignoreCase));
128
- hasInclude = hasInclude || !exclude;
129
- }
130
- }
131
- return this;
132
- } */
133
-
134
118
matches ( candidate , initialMatch ) {
135
119
return this . matchers . reduce (
136
120
( acc , cur ) => cur . calcMatch ( candidate , acc ) ,
@@ -146,7 +130,7 @@ class ResourceFilterList {
146
130
ResourceFilterList . fromString = function ( filterStr ) {
147
131
const result = new ResourceFilterList ( ) ;
148
132
if ( filterStr != null ) {
149
- result . addFilters ( filterStr . trim ( ) . split ( / \s * , \s * / ) ) ;
133
+ result . addFilters ( filterStr . trim ( ) . split ( / \s * , \s * / ) . filter ( Boolean ) ) ;
150
134
}
151
135
return result ;
152
136
} ;
0 commit comments