diff --git a/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs b/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs
index 268b5868ff8..9a870666fb2 100644
--- a/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs
+++ b/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs
@@ -27,20 +27,9 @@ internal class MatchedCodeOwnerEntry
public readonly CodeOwnerEntry Value;
///
- /// The entry is valid if it obeys following conditions:
- /// - The Value was obtained with a call to Azure.Sdk.Tools.CodeOwnersParser.CodeOwnersFile.ParseContent().
- /// - As a consequence, in the case of no match, the entry is not valid.
- /// - the Value.PathExpression starts with "/".
- ///
- /// Once the validation described in the following issue is implemented:
- /// https://github.com/Azure/azure-sdk-tools/issues/4859
- /// To be valid, the entry will also have to obey following conditions:
- /// - if the Value.PathExpression ends with "/", at least one corresponding
- /// directory exists in the repository
- /// - if the Value.PathExpression does not end with "/", at least one corresponding
- /// file exists in the repository.
+ /// See comment on IsCodeOwnersPathValid
///
- public bool IsValid => this.Value.PathExpression.StartsWith("/");
+ public bool IsValid => IsCodeOwnersPathValid(this.Value.PathExpression);
///
/// Any CODEOWNERS path with these characters will be skipped.
@@ -132,12 +121,7 @@ private static string NormalizeTargetPath(string targetPath, string codeownersPa
private static Regex ConvertToRegex(string codeownersPath)
{
- // CODEOWNERS paths that do not start with "/" are relative and considered invalid.
- // However, here we handle such cases to accomodate for parsing CODEOWNERS file
- // paths that somehow slipped through validation. We do so by instead treating
- // such paths as if they were absolute to repository root, i.e. starting with "/".
- if (!codeownersPath.StartsWith("/"))
- codeownersPath = "/" + codeownersPath;
+ codeownersPath = ConvertPathIfInvalid(codeownersPath);
string pattern = codeownersPath;
@@ -148,29 +132,64 @@ private static Regex ConvertToRegex(string codeownersPath)
pattern = Regex.Escape(pattern);
- // Denote that all paths are absolute by prepending "beginning of string" symbol.
+ pattern = AddStringAnchors(pattern);
+
+ // Note that the "/**/" case is implicitly covered by "**/".
+ pattern = pattern.Replace("_DOUBLE_STAR_/", "(.*)");
+ // This case is necessary to cover suffix case, 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);
+ }
+
+ private static string ConvertPathIfInvalid(string codeownersPath)
+ {
+ // CODEOWNERS paths that do not start with "/" are relative and considered invalid.
+ // However, here we handle such cases to accomodate for parsing CODEOWNERS file
+ // paths that somehow slipped through validation. We do so by instead treating
+ // such paths as if they were absolute to repository root, i.e. starting with "/".
+ if (!IsCodeOwnersPathValid(codeownersPath))
+ codeownersPath = "/" + codeownersPath;
+ return codeownersPath;
+ }
+
+ private static string AddStringAnchors(string pattern)
+ {
+ // Denote that all paths are absolute by pre-pending "beginning of string" symbol.
pattern = "^" + pattern;
// Lack of slash at the end denotes the path is a path to a file,
// per our validation logic.
- // Note we assume this is the case even if the path is invalid,
- // even though in such case it might not necessarily be true.
- if (!(pattern.EndsWith("/")
- || pattern.EndsWith("_DOUBLE_STAR_")))
+ // Note we assume this is path to a file even if the path is invalid,
+ // even though in such case the path might be a path to a directory.
+ if (!pattern.EndsWith("/"))
{
// Append "end of string", symbol, denoting the match has to be exact,
// not a substring, as we are dealing with a file.
pattern += "$";
}
- // Note that the "/**/" case is implicitly covered by "**/".
- pattern = pattern.Replace("_DOUBLE_STAR_/", "(.*)");
- // This case is necessary to cover suffix case, 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);
+ return pattern;
}
+
+ ///
+ /// The entry is valid if it obeys following conditions:
+ /// - The Value was obtained with a call to
+ /// Azure.Sdk.Tools.CodeOwnersParser.CodeOwnersFile.ParseContent().
+ /// - As a consequence, in the case of no match, the entry is not valid.
+ /// - the Value.PathExpression starts with "/".
+ ///
+ /// Once the validation described in the following issue is implemented:
+ /// https://github.com/Azure/azure-sdk-tools/issues/4859
+ /// To be valid, the entry will also have to obey following conditions:
+ /// - if the Value.PathExpression ends with "/", at least one corresponding
+ /// directory exists in the repository
+ /// - if the Value.PathExpression does not end with "/", at least one corresponding
+ /// file exists in the repository.
+ ///
+ private static bool IsCodeOwnersPathValid(string codeownersPath)
+ => codeownersPath.StartsWith("/");
}
}