diff --git a/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeOwnersFileTests.cs b/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeOwnersFileTests.cs index ce22e4a2897..6013207bf5d 100644 --- a/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeOwnersFileTests.cs +++ b/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeOwnersFileTests.cs @@ -8,18 +8,18 @@ public class CodeOwnersFileTests { /// /// A battery of test cases specifying behavior of new logic matching target - /// path to CODEOWNERS entries , and comparing it to existing, legacy logic. + /// path to CODEOWNERS entries, and comparing it to existing, legacy logic. /// - /// The logic that has changed lives in CodeOwnersFile.FindOwnersForClosestMatch. - /// - /// The new logic supports matching against wildcards, while the old one doesn't. + /// The logic that has changed is located in CodeOwnersFile.FindOwnersForClosestMatch. /// /// In the test case table below, any discrepancy between legacy and new - /// parser expected matches that doesn't pertain to wildcard matching denotes - /// a potential backward compatibility and/or existing defect in the legacy parser. - /// + /// matcher expected matches that doesn't pertain to wildcard matching denotes + /// a potential backward compatibility and/or existing defect in the legacy matcher. + /// /// For further details, please see: - /// https://github.com/Azure/azure-sdk-tools/issues/2770 + /// - Class comment for Azure.Sdk.Tools.CodeOwnersParser.MatchedCodeOwnerEntry + /// - https://github.com/Azure/azure-sdk-tools/issues/2770 + /// - https://github.com/Azure/azure-sdk-tools/issues/4859 /// private static readonly TestCase[] testCases = { @@ -96,6 +96,7 @@ public class CodeOwnersFileTests new( "/a/*/b/" , "a/x/b/c" , false , true ), new( "/a/*/b/" , "a/x/c" , false , false ), new( "/a/*/b/" , "a/x/y/b" , false , false ), + new( "/a**b/" , "a/x/y/b" , false , true ), new( "/a/**/b/" , "a/b" , false , true ), new( "/a/**/b/" , "a/x/b" , false , true ), new( "/a/**/b/" , "a/x/y/b" , false , true ), diff --git a/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs b/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs index 6afbd446ec5..ac47f380050 100644 --- a/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs +++ b/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs @@ -8,6 +8,12 @@ namespace Azure.Sdk.Tools.CodeOwnersParser /// Represents a CODEOWNERS file entry that matched to targetPath from /// the list of entries, assumed to have been parsed from CODEOWNERS file. /// + /// This is a new matcher, compared to the old one, located in: + /// CodeOwnersFile.FindOwnersForClosestMatchLegacyImpl() + /// This new matcher supports matching against wildcards, while the old one doesn't. + /// This new matcher is designed to work with CODEOWNERS file validation: + /// https://github.com/Azure/azure-sdk-tools/issues/4859 + /// /// To use this class, construct it. /// /// To obtain the value of the matched entry, reference "Value" member. @@ -157,8 +163,11 @@ private static Regex ConvertToRegex(string codeownersPath) pattern += "$"; } + // Note that the "/**/" case is implicitly covered by "**/". pattern = pattern.Replace("_DOUBLE_STAR_/", "(.*)"); + // This case is necessary to cover suffix, e.g. "/foo/bar/**". pattern = pattern.Replace("/_DOUBLE_STAR_", "(.*)"); + // This case is necessary to cover inline **, e.g. "/a**b/" pattern = pattern.Replace("_DOUBLE_STAR_", "(.*)"); pattern = pattern.Replace("_SINGLE_STAR_", "([^/]*)"); return new Regex(pattern);