Rework how FilterFilesChanged works

---
type: change
description: |-
  Rework how FilterFilesChanged works

  Previously the filter would only match if _all_ files changed matched a pattern
  within it. This ends up not being very useful, as usually the filter is being
  used to guard a specific set of content within the project, and so it's a lot
  more useful to have the filter match if _any_ files changed matched a pattern.
fingerprint: AFSaaPVOBsFYc0D3JQd0M7yJKDiS8/VjAsppPXTngGPb
credentials:
- type: pgp_signature
  pub_key_id: 95C46FA6A41148AC
  body: iQIzBAABAgAdFiEEJ6tQKp6olvZKJ0lwlcRvpqQRSKwFAl63Q/oACgkQlcRvpqQRSKxHew//QO74joMfwg+mCiSKjXRbTidYW/ILr3mspFSLMYS5RKcf2YQNpYOP24a7BINe5LQYXGAOEH7PxEWOTTJTzwv90/T/jmYwJJMuNRa3NHXfCRS63i7L2b4nWSEATPQlGZRaMLOOsYdg2m/mcEQuHgf+fmfd4iRGFJHDzxj4etcfD/cHi9fg8Assr7E8K9xoYp3vs/8cPWGP16p94LHmsu5m8pt990Bn4XzxUzHAseyjPgs3OElH67SqW9D9F2PHZvdmCo58bvt13otzn137jwf/EZQOkcOWXxaOxNG8bqZFWgFGUEQajgXYLwfPULC4J3c1Rj+umAT0R1QPzj0h2MIoE/gM1wbw5fwtIfCpM9pA526TFJfdujvYY4x8oPMve9hTQ0FZ9Vv1cTCrOWo5vVNjum0jY58GGr9/I+PXupstDmGnKHnwivz459YNq0Uuyir3KgyM8fY7rTf+FQslrv7Hafnrju3KqCvCoHT0nNj0dWVen5RFK6dee4fsYvGK8ujKYCJpwm+3/0ggJOCC3XsMOCCh/F/YMvq4Xtwo7AbNIrVPOSIAnu2khkybInmZGmIVEP4E6MWfVzjb4wVVocqYhhuHg09IDeBv9WS5s3KBUVL4RNYadrUXMOs4W7wXvHILSYx87j0UJfy9bUfALwclXaFuhBYzghbBQVN3L00ASaw=
  account: mediocregopher
This commit is contained in:
mediocregopher 2020-05-09 18:00:00 -06:00
parent 38d396e90c
commit f52ea2a708
4 changed files with 75 additions and 9 deletions

View File

@ -337,10 +337,7 @@ changed between the tree of the commit's parent and the commit's tree. Matching
is performed on the paths of the changed files, relative to the repo root. is performed on the paths of the changed files, relative to the repo root.
A files changed filter can have one or multiple patterns defined. The filter A files changed filter can have one or multiple patterns defined. The filter
will match if at least one defined pattern matches for every file changed. will match if any of the changed files matches at least one defined pattern.
(TODO this may change to be: `The filter will match if any of the changed files
matches at least one defined pattern.`)
A files changed filter with only one pattern can be defined like this: A files changed filter with only one pattern can be defined like this:

View File

@ -84,9 +84,13 @@ var _ Filter = FilterFilesChanged{}
// MatchCommit implements the method for FilterInterface. // MatchCommit implements the method for FilterInterface.
func (f FilterFilesChanged) MatchCommit(req CommitRequest) error { func (f FilterFilesChanged) MatchCommit(req CommitRequest) error {
for _, path := range req.FilesChanged { for _, path := range req.FilesChanged {
if err := f.StringMatcher.Match(path); err != nil { if err := f.StringMatcher.Match(path); errors.As(err, new(ErrFilterNoMatch)) {
continue
} else if err != nil {
return err return err
} }
}
return nil return nil
}
return ErrFilterNoMatch{Err: errors.New("no paths matched")}
} }

View File

@ -132,3 +132,68 @@ func TestStringMatcher(t *testing.T) {
}) })
} }
} }
func TestFilterFilesChanged(t *testing.T) {
mkReq := func(paths ...string) CommitRequest {
return CommitRequest{FilesChanged: paths}
}
runCommitMatchTests(t, []filterCommitMatchTest{
{
descr: "no paths",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Pattern: "foo"},
},
req: mkReq(),
match: false,
},
{
descr: "all paths against one pattern",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Pattern: "foo/*"},
},
req: mkReq("foo/bar", "foo/baz"),
match: true,
},
{
descr: "all paths against multiple patterns",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Patterns: []string{"foo", "bar"}},
},
req: mkReq("foo", "bar"),
match: true,
},
{
descr: "some paths against one pattern",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Pattern: "foo"},
},
req: mkReq("foo", "bar"),
match: true,
},
{
descr: "some paths against many patterns",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Patterns: []string{"foo", "bar"}},
},
req: mkReq("foo", "baz"),
match: true,
},
{
descr: "no paths against one pattern",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Pattern: "foo"},
},
req: mkReq("baz", "buz"),
match: false,
},
{
descr: "no paths against many patterns",
filter: FilterFilesChanged{
StringMatcher: StringMatcher{Patterns: []string{"foo", "bar"}},
},
req: mkReq("baz", "buz"),
match: false,
},
})
}

View File

@ -12,8 +12,8 @@ type filterCommitMatchTest struct {
req CommitRequest req CommitRequest
match bool match bool
// assumes match == true, and will ensure that the returned wrapped error is // assumes match == false, and will ensure that the returned wrapped error
// this one. // is this one.
matchErr error matchErr error
} }
@ -29,7 +29,7 @@ func runCommitMatchTests(t *testing.T, tests []filterCommitMatchTest) {
return return
} else if fErr := new(ErrFilterNoMatch); !errors.As(err, fErr) { } else if fErr := new(ErrFilterNoMatch); !errors.As(err, fErr) {
t.Fatalf("expected ErrFilterNoMatch, got %#v", err) t.Fatalf("expected ErrFilterNoMatch, got: %#v", err)
} else if test.matchErr != nil && !reflect.DeepEqual(fErr.Err, test.matchErr) { } else if test.matchErr != nil && !reflect.DeepEqual(fErr.Err, test.matchErr) {
t.Fatalf("expected err %#v, not %#v", test.matchErr, fErr.Err) t.Fatalf("expected err %#v, not %#v", test.matchErr, fErr.Err)