Skip to content

Commit

Permalink
Add the allofany matching type (actions#423)
Browse files Browse the repository at this point in the history
This is true when all files match any of the patterns.
  • Loading branch information
dfandrich committed Jan 20, 2023
1 parent b435530 commit e9e1d19
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ For more control over matching, you can provide a match object instead of a simp
```yml
- any: ['list', 'of', 'globs']
all: ['list', 'of', 'globs']
allofany: ['list', 'of', 'globs']
```
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.
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.

The fields are defined as follows:
* `any`: match ALL globs against ANY changed path
* `all`: match ALL globs against ALL changed paths
* `allofany`: match ANY globs against ALL changed paths

A simple path glob is the equivalent to `any: ['glob']`. More specifically, the following two configurations are equivalent:
```yml
Expand Down Expand Up @@ -87,6 +89,10 @@ source:
frontend:
- any: ['src/**/*.js']
all: ['!src/main.js']

# Add 'documentation' label to any change consisting entirely of text files
documentation:
- allofany: ['**/*.md', '**/*.txt', '**/*.1']
```
### Create Workflow
Expand Down
15 changes: 15 additions & 0 deletions __tests__/labeler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ beforeAll(() => {
});

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

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

expect(result).toBeFalsy();
});

it('returns true when our allofany pattern does match changed files', () => {
const changedFiles = ['foo.txt', 'bar.md'];
const result = checkGlobs(changedFiles, matchAllOfAnyConfig);

expect(result).toBeTruthy();
});

it('returns false when our allofany pattern does not match changed files', () => {
const changedFiles = ['foo.md', 'foo.docx'];
const result = checkGlobs(changedFiles, matchAllOfAnyConfig);

expect(result).toBeFalsy();
});
});
35 changes: 35 additions & 0 deletions src/labeler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {Minimatch, IMinimatch} from 'minimatch';
interface MatchConfig {
all?: string[];
any?: string[];
allofany?: string[];
}

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

function isMatchAny(changedFile: string, matchers: IMinimatch[]): boolean {
core.debug(` matching patterns against file ${changedFile}`);
for (const matcher of matchers) {
core.debug(` - ${printPattern(matcher)}`);
if (matcher.match(changedFile)) {
core.debug(` ${printPattern(matcher)} matched`);
return true;
}
}

core.debug(` no patterns matched`);
return false;
}

// equivalent to "Array.some()" but expanded for debugging and clarity
function checkAny(changedFiles: string[], globs: string[]): boolean {
const matchers = globs.map(g => new Minimatch(g));
Expand Down Expand Up @@ -213,6 +228,20 @@ function checkAll(changedFiles: string[], globs: string[]): boolean {
return true;
}

function checkAllOfAny(changedFiles: string[], globs: string[]): boolean {
const matchers = globs.map(g => new Minimatch(g));
core.debug(` checking "all" patterns`);
for (const changedFile of changedFiles) {
if (!isMatchAny(changedFile, matchers)) {
core.debug(` "allofany" pattern did not match against ${changedFile}`);
return false;
}
}

core.debug(` "allofany" patterns matched all files`);
return true;
}

function checkMatch(changedFiles: string[], matchConfig: MatchConfig): boolean {
if (matchConfig.all !== undefined) {
if (!checkAll(changedFiles, matchConfig.all)) {
Expand All @@ -226,6 +255,12 @@ function checkMatch(changedFiles: string[], matchConfig: MatchConfig): boolean {
}
}

if (matchConfig.allofany !== undefined) {
if (!checkAllOfAny(changedFiles, matchConfig.allofany)) {
return false;
}
}

return true;
}

Expand Down

0 comments on commit e9e1d19

Please sign in to comment.