Skip to content

Commit b0d9ea1

Browse files
committed
Add the allofany matching type (actions#423)
This is true when all files match at any of the patterns.
1 parent b435530 commit b0d9ea1

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ For more control over matching, you can provide a match object instead of a simp
2626
```yml
2727
- any: ['list', 'of', 'globs']
2828
all: ['list', 'of', 'globs']
29+
allofany: ['list', 'of', 'globs']
2930
```
3031
31-
One or both fields can be provided for fine-grained matching. Unlike the top-level list, the list of path globs provided to `any` and `all` must ALL match against a path for the label to be applied.
32+
One two or three fields can be provided for fine-grained matching. Unlike the top-level list, the list of path globs provided to `any` and `all` must ALL match against a path for the label to be applied.
3233

3334
The fields are defined as follows:
3435
* `any`: match ALL globs against ANY changed path
3536
* `all`: match ALL globs against ALL changed paths
37+
* `allofany`: match ANY globs against ALL changed paths
3638

3739
A simple path glob is the equivalent to `any: ['glob']`. More specifically, the following two configurations are equivalent:
3840
```yml
@@ -87,6 +89,10 @@ source:
8789
frontend:
8890
- any: ['src/**/*.js']
8991
all: ['!src/main.js']
92+
93+
# Add 'documentation' label to any change consisting entirely of text files
94+
documentation:
95+
- allofany: ['**/*.md', '**/*.txt', '**/*.1']
9096
```
9197
9298
### Create Workflow

__tests__/labeler.test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ beforeAll(() => {
1111
});
1212

1313
const matchConfig = [{any: ['*.txt']}];
14+
const matchAllOfAnyConfig = [{allofany: ['*.txt', '*.md']}];
1415

1516
describe('checkGlobs', () => {
1617
it('returns true when our pattern does match changed files', () => {
@@ -26,4 +27,18 @@ describe('checkGlobs', () => {
2627

2728
expect(result).toBeFalsy();
2829
});
30+
31+
it('returns true when our allofany pattern does match changed files', () => {
32+
const changedFiles = ['foo.txt', 'bar.md'];
33+
const result = checkGlobs(changedFiles, matchAllOfAnyConfig);
34+
35+
expect(result).toBeTruthy();
36+
});
37+
38+
it('returns false when our allofany pattern does not match changed files', () => {
39+
const changedFiles = ['foo.md', 'foo.docx'];
40+
const result = checkGlobs(changedFiles, matchAllOfAnyConfig);
41+
42+
expect(result).toBeFalsy();
43+
});
2944
});

src/labeler.ts

+35
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {Minimatch, IMinimatch} from 'minimatch';
66
interface MatchConfig {
77
all?: string[];
88
any?: string[];
9+
allofany?: string[];
910
}
1011

1112
type StringOrMatchConfig = string | MatchConfig;
@@ -183,6 +184,20 @@ function isMatch(changedFile: string, matchers: IMinimatch[]): boolean {
183184
return true;
184185
}
185186

187+
function isMatchAny(changedFile: string, matchers: IMinimatch[]): boolean {
188+
core.debug(` matching patterns against file ${changedFile}`);
189+
for (const matcher of matchers) {
190+
core.debug(` - ${printPattern(matcher)}`);
191+
if (matcher.match(changedFile)) {
192+
core.debug(` ${printPattern(matcher)} matched`);
193+
return true;
194+
}
195+
}
196+
197+
core.debug(` no patterns matched`);
198+
return false;
199+
}
200+
186201
// equivalent to "Array.some()" but expanded for debugging and clarity
187202
function checkAny(changedFiles: string[], globs: string[]): boolean {
188203
const matchers = globs.map(g => new Minimatch(g));
@@ -213,6 +228,20 @@ function checkAll(changedFiles: string[], globs: string[]): boolean {
213228
return true;
214229
}
215230

231+
function checkAllOfAny(changedFiles: string[], globs: string[]): boolean {
232+
const matchers = globs.map(g => new Minimatch(g));
233+
core.debug(` checking "all" patterns`);
234+
for (const changedFile of changedFiles) {
235+
if (!isMatchAny(changedFile, matchers)) {
236+
core.debug(` "allofany" pattern did not match against ${changedFile}`);
237+
return false;
238+
}
239+
}
240+
241+
core.debug(` "allofany" patterns matched all files`);
242+
return true;
243+
}
244+
216245
function checkMatch(changedFiles: string[], matchConfig: MatchConfig): boolean {
217246
if (matchConfig.all !== undefined) {
218247
if (!checkAll(changedFiles, matchConfig.all)) {
@@ -226,6 +255,12 @@ function checkMatch(changedFiles: string[], matchConfig: MatchConfig): boolean {
226255
}
227256
}
228257

258+
if (matchConfig.allofany !== undefined) {
259+
if (!checkAllOfAny(changedFiles, matchConfig.allofany)) {
260+
return false;
261+
}
262+
}
263+
229264
return true;
230265
}
231266

0 commit comments

Comments
 (0)