diff --git a/.editorconfig b/.editorconfig
index 4ea6d3bc8ac2..e992d7ca3b56 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -28,7 +28,7 @@ insert_final_newline = true
# Organize usings
dotnet_sort_system_directives_first = true
# this. preferences
-dotnet_style_qualification_for_field = true:suggestion
+dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent
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 46eac3803242..75abc455b779 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
@@ -4,13 +4,13 @@
namespace Azure.Sdk.Tools.CodeOwnersParser.Tests;
[TestFixture]
-public class CodeOwnersFileTests
+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.
///
- /// The logic that has changed is located in CodeOwnersFile.FindOwnersForClosestMatch.
+ /// The logic that has changed is located in CodeownersFile.GetMatchingCodeownersEntry.
///
/// In the test case table below, any discrepancy between legacy and new
/// matcher expected matches that doesn't pertain to wildcard matching denotes
@@ -135,14 +135,14 @@ public class CodeOwnersFileTests
};
///
- /// Exercises Azure.Sdk.Tools.CodeOwnersParser.Tests.CodeOwnersFileTests.testCases.
+ /// Exercises Azure.Sdk.Tools.CodeOwnersParser.Tests.CodeownersFileTests.testCases.
/// See comment on that member for details.
///
[TestCaseSource(nameof(testCases))]
public void TestParseAndFindOwnersForClosestMatch(TestCase testCase)
{
- List? codeownersEntries =
- CodeOwnersFile.ParseContent(testCase.CodeownersPath + "@owner");
+ List? codeownersEntries =
+ CodeownersFile.GetCodeownersEntries(testCase.CodeownersPath + "@owner");
VerifyFindOwnersForClosestMatch(testCase, codeownersEntries, useNewImpl: false, testCase.ExpectedLegacyMatch);
VerifyFindOwnersForClosestMatch(testCase, codeownersEntries, useNewImpl: true, testCase.ExpectedNewMatch);
@@ -150,18 +150,16 @@ public void TestParseAndFindOwnersForClosestMatch(TestCase testCase)
private static void VerifyFindOwnersForClosestMatch(
TestCase testCase,
- List codeownersEntries,
+ List codeownersEntries,
bool useNewImpl,
bool expectedMatch)
{
- CodeOwnerEntry? entryLegacy =
+ CodeownersEntry? entryLegacy =
// Act
- CodeOwnersFile.FindOwnersForClosestMatch(
- codeownersEntries,
- testCase.TargetPath,
- useNewFindOwnersForClosestMatchImpl: useNewImpl);
+ CodeownersFile.GetMatchingCodeownersEntry(testCase.TargetPath,
+ codeownersEntries, useNewImpl: useNewImpl);
- Assert.That(entryLegacy.Owners.Count, Is.EqualTo(expectedMatch ? 1 : 0));
+ Assert.That(entryLegacy.Owners, Has.Count.EqualTo(expectedMatch ? 1 : 0));
}
public record TestCase(
diff --git a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ConsoleOutput.cs b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ConsoleOutput.cs
index a4de98d76905..434129f87c42 100644
--- a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ConsoleOutput.cs
+++ b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ConsoleOutput.cs
@@ -38,6 +38,8 @@ public void Dispose()
Console.SetOut(this.originalOutput);
this.stringWriter.Dispose();
this.originalOutput.Dispose();
+ // https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1816
+ GC.SuppressFinalize(this);
}
///
diff --git a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/MainTests.cs b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ProgramTests.cs
similarity index 66%
rename from tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/MainTests.cs
rename to tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ProgramTests.cs
index 51701637e918..0755b7307b0e 100644
--- a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/MainTests.cs
+++ b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/ProgramTests.cs
@@ -9,9 +9,9 @@ namespace Azure.Sdk.Tools.RetrieveCodeOwners.Tests
/// This is test of console app Azure.Sdk.Tools.RetrieveCodeOwners.
///
[TestFixture]
- public class MainTests
+ public class ProgramTests
{
- private const string CodeOwnersFilePath = "CODEOWNERS";
+ private const string CodeownersFilePath = "CODEOWNERS";
private static readonly object[] sourceLists =
{
@@ -27,28 +27,26 @@ public class MainTests
[TestCaseSource(nameof(sourceLists))]
public void TestOnNormalOutput(string targetDirectory, bool includeUserAliasesOnly, List expectedReturn)
{
- using (var consoleOutput = new ConsoleOutput())
- {
- Program.Main(CodeOwnersFilePath, targetDirectory, includeUserAliasesOnly);
- var output = consoleOutput.GetOutput();
- TestExpectResult(expectedReturn, output);
- consoleOutput.Dispose();
- }
+ using var consoleOutput = new ConsoleOutput();
+ Program.Main(targetDirectory, CodeownersFilePath, includeUserAliasesOnly);
+ var output = consoleOutput.GetOutput();
+ TestExpectResult(expectedReturn, output);
+ consoleOutput.Dispose();
}
[TestCase("PathNotExist")]
[TestCase("http://testLink")]
[TestCase("https://testLink")]
- public void TestOnError(string codeOwnerPath)
+ public void TestOnError(string codeownersPath)
{
- Assert.That(Program.Main(codeOwnerPath, "sdk"), Is.EqualTo(1));
+ Assert.That(Program.Main("sdk", codeownersPath), Is.EqualTo(1));
}
private static void TestExpectResult(List expectReturn, string output)
{
- CodeOwnerEntry? codeOwnerEntry = JsonSerializer.Deserialize(output);
- List actualReturn = codeOwnerEntry!.Owners;
- Assert.That(actualReturn.Count, Is.EqualTo(expectReturn.Count));
+ CodeownersEntry? codeownersEntry = JsonSerializer.Deserialize(output);
+ List actualReturn = codeownersEntry!.Owners;
+ Assert.That(actualReturn, Has.Count.EqualTo(expectReturn.Count));
for (int i = 0; i < actualReturn.Count; i++)
{
Assert.That(actualReturn[i], Is.EqualTo(expectReturn[i]));
diff --git a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners/Program.cs b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners/Program.cs
index efc105654b7a..c385eb9d9bd5 100644
--- a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners/Program.cs
+++ b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners/Program.cs
@@ -5,36 +5,40 @@
namespace Azure.Sdk.Tools.RetrieveCodeOwners
{
///
- /// The tool command to retrieve code owners.
+ /// See Program.Main comment.
///
public static class Program
{
///
- /// Retrieves CODEOWNERS information for specific section of the repo
+ /// Given targetPath and CODEOWNERS file codeownersFilePath,
+ /// prints out to stdout owners of the targetPath as determined by the CODEOWNERS file.
///
- /// The path of CODEOWNERS file in repo
- /// The directory whose information is to be retrieved
- /// The option to filter out code owner team alias.
+ /// The path whose owners are to be determined.
+ /// The path to the CODEOWNERS file with ownership information.
+ /// Whether owners that aren't users should be excluded from the returned owners.
/// Exit code
-
public static int Main(
- string codeOwnerFilePath,
- string targetDirectory,
- bool filterOutNonUserAliases = false
- )
+ string targetPath,
+ string codeownersFilePath,
+ bool excludeNonUserAliases = false)
{
- var target = targetDirectory.Trim();
- try {
- var codeOwnerEntry = CodeOwnersFile.ParseAndFindOwnersForClosestMatch(codeOwnerFilePath, target);
- if (filterOutNonUserAliases)
+ targetPath = targetPath.Trim();
+ try
+ {
+ var codeownersEntry = CodeownersFile.GetMatchingCodeownersEntry(targetPath, codeownersFilePath);
+ if (excludeNonUserAliases)
{
- codeOwnerEntry.FilterOutNonUserAliases();
+ codeownersEntry.ExcludeNonUserAliases();
}
- var codeOwnerJson = JsonSerializer.Serialize(codeOwnerEntry, new JsonSerializerOptions { WriteIndented = true });
- Console.WriteLine(codeOwnerJson);
+
+ string codeownersJson = JsonSerializer.Serialize(codeownersEntry,
+ new JsonSerializerOptions { WriteIndented = true });
+
+ Console.WriteLine(codeownersJson);
return 0;
}
- catch (Exception e) {
+ catch (Exception e)
+ {
Console.Error.WriteLine(e.Message);
return 1;
}
diff --git a/tools/code-owners-parser/CodeOwnersParser/CodeOwnersFile.cs b/tools/code-owners-parser/CodeOwnersParser/CodeOwnersFile.cs
index 0e7d4285973d..16e4e3d531a5 100644
--- a/tools/code-owners-parser/CodeOwnersParser/CodeOwnersFile.cs
+++ b/tools/code-owners-parser/CodeOwnersParser/CodeOwnersFile.cs
@@ -1,84 +1,96 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
namespace Azure.Sdk.Tools.CodeOwnersParser
{
- public static class CodeOwnersFile
+ public static class CodeownersFile
{
- public static List ParseFile(string filePathOrUrl)
+ public static List GetCodeownersEntriesFromFileOrUrl(string codeownersFilePathOrUrl)
{
- string content = FileHelpers.GetFileContents(filePathOrUrl);
- return ParseContent(content);
+ string content = FileHelpers.GetFileOrUrlContents(codeownersFilePathOrUrl);
+ return GetCodeownersEntries(content);
}
- public static List ParseContent(string fileContent)
+ public static List GetCodeownersEntries(string codeownersContent)
{
- List entries = new List();
+ List entries = new List();
// An entry ends when we get to a path (a real path or a commented dummy path)
- using (StringReader sr = new StringReader(fileContent))
+ using (StringReader sr = new StringReader(codeownersContent))
{
- CodeOwnerEntry entry = new CodeOwnerEntry();
+ CodeownersEntry entry = new CodeownersEntry();
// we are going to read line by line until we find a line that is not a comment OR that is using the placeholder entry inside the comment.
// while we are trying to find the folder entry, we parse all comment lines to extract the labels from it.
// when we find the path or placeholder, we add the completed entry and create a new one.
while (sr.ReadLine() is { } line)
{
- line = NormalizeLine(line);
-
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (!line.StartsWith("#") || line.IndexOf(CodeOwnerEntry.MissingFolder, System.StringComparison.OrdinalIgnoreCase) >= 0)
- {
- // If this is not a comment line OR this is a placeholder entry
-
- entry.ParseOwnersAndPath(line);
-
- // only add it if it is a valid entry
- if (entry.IsValid)
- {
- entries.Add(entry);
- }
-
- // create a new entry.
- entry = new CodeOwnerEntry();
- }
- else if (line.StartsWith("#"))
- {
- // try to process the line in case there are markers that need to be extracted
- entry.ProcessLabelsOnLine(line);
- }
-
+ ProcessCodeownersLine(line, entry, entries);
}
}
return entries;
}
- public static CodeOwnerEntry ParseAndFindOwnersForClosestMatch(
- string codeOwnersFilePathOrUrl,
+ public static CodeownersEntry GetMatchingCodeownersEntry(
string targetPath,
- bool useNewFindOwnersForClosestMatchImpl = false)
+ string codeownersFilePathOrUrl,
+ bool useNewImpl = false)
{
- var codeOwnerEntries = ParseFile(codeOwnersFilePathOrUrl);
- return FindOwnersForClosestMatch(codeOwnerEntries, targetPath, useNewFindOwnersForClosestMatchImpl);
+ var codeownersEntries = GetCodeownersEntriesFromFileOrUrl(codeownersFilePathOrUrl);
+ return GetMatchingCodeownersEntry(targetPath, codeownersEntries, useNewImpl);
}
- public static CodeOwnerEntry FindOwnersForClosestMatch(
- List codeOwnerEntries,
+ public static CodeownersEntry GetMatchingCodeownersEntry(
string targetPath,
- bool useNewFindOwnersForClosestMatchImpl = false)
+ List codeownersEntries,
+ bool useNewImpl = false)
+ {
+ Debug.Assert(targetPath != null);
+ return useNewImpl
+ ? new MatchedCodeownersEntry(codeownersEntries, targetPath).Value
+ : GetMatchingCodeownersEntryLegacyImpl(codeownersEntries, targetPath);
+ }
+
+ private static void ProcessCodeownersLine(string line, CodeownersEntry entry, List entries)
{
- return useNewFindOwnersForClosestMatchImpl
- ? new MatchedCodeOwnerEntry(codeOwnerEntries, targetPath).Value
- : FindOwnersForClosestMatchLegacyImpl(codeOwnerEntries, targetPath);
+ line = NormalizeLine(line);
+
+ if (string.IsNullOrWhiteSpace(line))
+ {
+ return;
+ }
+
+ if (!IsCommentLine(line) || IsPlaceholderEntry(line))
+ {
+ entry.ParseOwnersAndPath(line);
+
+ // only add it if it is a valid entry
+ if (entry.IsValid)
+ entries.Add(entry);
+ }
+ else if (line.StartsWith("#"))
+ {
+ // try to process the line in case there are markers that need to be extracted
+ entry.ProcessLabelsOnLine(line);
+ }
}
- private static CodeOwnerEntry FindOwnersForClosestMatchLegacyImpl(List codeOwnerEntries,
+ private static bool IsPlaceholderEntry(string line)
+ => line.Contains(CodeownersEntry.MissingFolder, StringComparison.OrdinalIgnoreCase);
+
+ private static bool IsCommentLine(string line)
+ => line.StartsWith("#");
+
+ private static string NormalizeLine(string line)
+ => !string.IsNullOrEmpty(line)
+ // Remove tabs and trim extra whitespace
+ ? line.Replace('\t', ' ').Trim()
+ : line;
+
+ private static CodeownersEntry GetMatchingCodeownersEntryLegacyImpl(
+ List codeownersEntries,
string targetPath)
{
// Normalize the start and end of the paths by trimming slash
@@ -86,24 +98,18 @@ private static CodeOwnerEntry FindOwnersForClosestMatchLegacyImpl(List= 0; i--)
+ for (int i = codeownersEntries.Count - 1; i >= 0; i--)
{
- string codeOwnerPath = codeOwnerEntries[i].PathExpression.Trim('/');
+ string codeownersPath = codeownersEntries[i].PathExpression.Trim('/');
// Note that this only matches on paths without glob patterns which is good enough
// for our current scenarios but in the future might need to support globs
- if (targetPath.StartsWith(codeOwnerPath, StringComparison.OrdinalIgnoreCase))
+ if (targetPath.StartsWith(codeownersPath, StringComparison.OrdinalIgnoreCase))
{
- return codeOwnerEntries[i];
+ return codeownersEntries[i];
}
}
- return new CodeOwnerEntry();
+ return new CodeownersEntry();
}
-
- private static string NormalizeLine(string line)
- => !string.IsNullOrEmpty(line)
- // Remove tabs and trim extra whitespace
- ? line.Replace('\t', ' ').Trim()
- : line;
}
}
diff --git a/tools/code-owners-parser/CodeOwnersParser/CodeOwnerEntry.cs b/tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs
similarity index 77%
rename from tools/code-owners-parser/CodeOwnersParser/CodeOwnerEntry.cs
rename to tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs
index c2fa426734ac..f471c84fcd2a 100644
--- a/tools/code-owners-parser/CodeOwnersParser/CodeOwnerEntry.cs
+++ b/tools/code-owners-parser/CodeOwnersParser/CodeownersEntry.cs
@@ -10,7 +10,7 @@ namespace Azure.Sdk.Tools.CodeOwnersParser
/// # ServiceLabel: %Label
/// path @owner @owner
///
- public class CodeOwnerEntry
+ public class CodeownersEntry
{
const char LabelSeparator = '%';
const char OwnerSeparator = '@';
@@ -20,7 +20,7 @@ public class CodeOwnerEntry
public string PathExpression { get; set; } = "";
- public bool ContainsWildcard => PathExpression.Contains("*");
+ public bool ContainsWildcard => PathExpression.Contains('*');
public List Owners { get; set; } = new List();
@@ -28,18 +28,10 @@ public class CodeOwnerEntry
public List ServiceLabels { get; set; } = new List();
- public bool IsValid
- {
- get
- {
- return !string.IsNullOrEmpty(PathExpression);
- }
- }
+ public bool IsValid => !string.IsNullOrWhiteSpace(PathExpression);
private static string[] SplitLine(string line, char splitOn)
- {
- return line.Split(new char[] { splitOn }, StringSplitOptions.RemoveEmptyEntries);
- }
+ => line.Split(new char[] { splitOn }, StringSplitOptions.RemoveEmptyEntries);
public override string ToString()
{
@@ -48,12 +40,12 @@ public override string ToString()
public bool ProcessLabelsOnLine(string line)
{
- if (line.IndexOf(PRLabelMoniker, StringComparison.OrdinalIgnoreCase) >= 0)
+ if (line.Contains(PRLabelMoniker, StringComparison.OrdinalIgnoreCase))
{
PRLabels.AddRange(ParseLabels(line, PRLabelMoniker));
return true;
}
- else if (line.IndexOf(ServiceLabelMoniker, StringComparison.OrdinalIgnoreCase) >= 0)
+ else if (line.Contains(ServiceLabelMoniker, StringComparison.OrdinalIgnoreCase))
{
ServiceLabels.AddRange(ParseLabels(line, ServiceLabelMoniker));
return true;
@@ -61,10 +53,10 @@ public bool ProcessLabelsOnLine(string line)
return false;
}
- private IEnumerable ParseLabels(string line, string moniker)
+ private static IEnumerable ParseLabels(string line, string moniker)
{
// Parse a line that looks like # PRLabel: %Label, %Label
- if (line.IndexOf(moniker, StringComparison.OrdinalIgnoreCase) == -1)
+ if (!line.Contains(moniker, StringComparison.OrdinalIgnoreCase))
{
yield break;
}
@@ -76,7 +68,7 @@ private IEnumerable ParseLabels(string line, string moniker)
yield break;
}
- line = line.Substring(colonPosition + 1).Trim();
+ line = line[(colonPosition + 1)..].Trim();
foreach (string label in SplitLine(line, LabelSeparator).ToList())
{
if (!string.IsNullOrWhiteSpace(label))
@@ -89,31 +81,36 @@ private IEnumerable ParseLabels(string line, string moniker)
public void ParseOwnersAndPath(string line)
{
if (string.IsNullOrEmpty(line) ||
- (line.StartsWith("#") && !(line.IndexOf(CodeOwnerEntry.MissingFolder, StringComparison.OrdinalIgnoreCase) >= 0)))
+ (IsComment(line) && !(line.Contains(CodeownersEntry.MissingFolder, StringComparison.OrdinalIgnoreCase))))
{
return;
}
line = ParsePath(line);
-
- //remove any comments from the line, if any.
- // this is the case when we have something like @user #comment
- int commentIndex = line.IndexOf("#");
-
- if (commentIndex >= 0)
- {
- line = line.Substring(0, commentIndex).Trim();
- }
+ line = RemoveCommentIfAny(line);
foreach (string author in SplitLine(line, OwnerSeparator).ToList())
{
if (!string.IsNullOrWhiteSpace(author))
- {
Owners.Add(author.Trim());
- }
}
}
+ private static bool IsComment(string line)
+ => line.StartsWith("#");
+
+ private static string RemoveCommentIfAny(string line)
+ {
+ // this is the case when we have something like @user #comment
+
+ int commentIndex = line.IndexOf("#", StringComparison.OrdinalIgnoreCase);
+
+ if (commentIndex >= 0)
+ line = line[..commentIndex].Trim();
+
+ return line;
+ }
+
private string ParsePath(string line)
{
// Get the start of the owner in the string
@@ -123,18 +120,18 @@ private string ParsePath(string line)
return line;
}
- string path = line.Substring(0, ownerStartPosition).Trim();
+ string path = line[..ownerStartPosition].Trim();
// the first entry is the path/regex
PathExpression = path;
// remove the path from the string.
- return line.Substring(ownerStartPosition);
+ return line[ownerStartPosition..];
}
///
/// Remove all code owners which are not github alias.
///
- public void FilterOutNonUserAliases()
+ public void ExcludeNonUserAliases()
{
Owners.RemoveAll(r => !IsGitHubUserAlias(r));
}
diff --git a/tools/code-owners-parser/CodeOwnersParser/FileHelpers.cs b/tools/code-owners-parser/CodeOwnersParser/FileHelpers.cs
index 2c9b0ff58e24..91db19aa3e19 100644
--- a/tools/code-owners-parser/CodeOwnersParser/FileHelpers.cs
+++ b/tools/code-owners-parser/CodeOwnersParser/FileHelpers.cs
@@ -6,25 +6,26 @@ namespace Azure.Sdk.Tools.CodeOwnersParser
{
public static class FileHelpers
{
- public static string GetFileContents(string fileOrUri)
+ public static string GetFileOrUrlContents(string fileOrUrl)
{
- // try to parse it as an Uri
- if (fileOrUri.StartsWith("https"))
- {
- using (HttpClient client = new HttpClient())
- {
- HttpResponseMessage response = client.GetAsync(fileOrUri).ConfigureAwait(false).GetAwaiter().GetResult();
- return response.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
- }
- }
+ if (fileOrUrl.StartsWith("https"))
+ return GetUrlContents(fileOrUrl);
- string fullPath = Path.GetFullPath(fileOrUri);
+ string fullPath = Path.GetFullPath(fileOrUrl);
if (File.Exists(fullPath))
- {
return File.ReadAllText(fullPath);
- }
- throw new ArgumentException($"The path provided is neither local path nor https link. Please check your path: {fileOrUri} resolved to {fullPath}.");
+ throw new ArgumentException(
+ "The path provided is neither local path nor https link. " +
+ $"Please check your path: '{fileOrUrl}' resolved to '{fullPath}'.");
+ }
+
+ private static string GetUrlContents(string url)
+ {
+ using HttpClient client = new HttpClient();
+ HttpResponseMessage response =
+ client.GetAsync(url).ConfigureAwait(false).GetAwaiter().GetResult();
+ return response.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
}
}
diff --git a/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs b/tools/code-owners-parser/CodeOwnersParser/MatchedCodeownersEntry.cs
similarity index 91%
rename from tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs
rename to tools/code-owners-parser/CodeOwnersParser/MatchedCodeownersEntry.cs
index 76f3cd297eec..703f70363826 100644
--- a/tools/code-owners-parser/CodeOwnersParser/MatchedCodeOwnerEntry.cs
+++ b/tools/code-owners-parser/CodeOwnersParser/MatchedCodeownersEntry.cs
@@ -11,7 +11,7 @@ namespace Azure.Sdk.Tools.CodeOwnersParser
///
/// This is a new matcher, compared to the old one, located in:
///
- /// CodeOwnersFile.FindOwnersForClosestMatchLegacyImpl()
+ /// 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:
@@ -25,7 +25,7 @@ namespace Azure.Sdk.Tools.CodeOwnersParser
/// https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-syntax
/// https://git-scm.com/docs/gitignore#_pattern_format
///
- internal class MatchedCodeOwnerEntry
+ internal class MatchedCodeownersEntry
{
///
/// Token for temporarily substituting "**" in regex, to avoid it being escaped when
@@ -38,7 +38,7 @@ internal class MatchedCodeOwnerEntry
///
private const string SingleStar = "_SINGLE_STAR_";
- public readonly CodeOwnerEntry Value;
+ public readonly CodeownersEntry Value;
///
/// See comment on IsCodeOwnersPathValid
@@ -52,29 +52,29 @@ internal class MatchedCodeOwnerEntry
///
private static readonly char[] unsupportedChars = { '[', ']', '!', '?' };
- private readonly ILogger log;
+ private readonly ILogger log;
- public MatchedCodeOwnerEntry(List entries, string targetPath)
+ public MatchedCodeownersEntry(List entries, string targetPath)
{
this.log = CreateLog();
this.Value = FindOwnersForClosestMatch(entries, targetPath);
}
- private ILogger CreateLog()
+ private ILogger CreateLog()
{
var loggerFactory = LoggerFactory.Create(builder => { builder.AddSimpleConsole(); });
- return loggerFactory.CreateLogger();
+ return loggerFactory.CreateLogger();
}
///
- /// Returns a CodeOwnerEntry from codeOwnerEntries that matches targetPath
+ /// Returns a CodeownersEntry from codeOwnerEntries that matches targetPath
/// per algorithm described in the GitHub CODEOWNERS reference,
/// as linked to in this class comment.
///
- /// If there is no match, returns "new CodeOwnerEntry()".
+ /// If there is no match, returns "new CodeownersEntry()".
///
- private CodeOwnerEntry FindOwnersForClosestMatch(
- List codeownersEntries,
+ private CodeownersEntry FindOwnersForClosestMatch(
+ List codeownersEntries,
string targetPath)
{
// targetPath is assumed to be absolute w.r.t. repository root, hence we ensure
@@ -87,7 +87,7 @@ private CodeOwnerEntry FindOwnersForClosestMatch(
// so it can not match against a CODEOWNERS entry that is guaranteed to be a file,
// by the virtue of not ending with "/".
- CodeOwnerEntry matchedEntry = codeownersEntries
+ CodeownersEntry matchedEntry = codeownersEntries
.Where(entry => !ContainsUnsupportedCharacters(entry.PathExpression))
// Entries listed in CODEOWNERS file below take precedence, hence we read the file from the bottom up.
// By convention, entries in CODEOWNERS should be sorted top-down in the order of:
@@ -99,7 +99,7 @@ private CodeOwnerEntry FindOwnersForClosestMatch(
.FirstOrDefault(
entry => Matches(targetPath, entry),
// assert: none of the codeownersEntries matched targetPath
- new CodeOwnerEntry());
+ new CodeownersEntry());
return matchedEntry;
}
@@ -124,7 +124,7 @@ private bool ContainsUnsupportedCharacters(string codeownersPath)
/// Returns true if the regex expression representing the PathExpression
/// of CODEOWNERS entry matches a prefix of targetPath.
///
- private bool Matches(string targetPath, CodeOwnerEntry entry)
+ private bool Matches(string targetPath, CodeownersEntry entry)
{
string codeownersPath = entry.PathExpression;
@@ -226,7 +226,7 @@ private string NormalizePath(string codeownersPath)
///
/// The entry is valid if it obeys following conditions:
/// - The Value was obtained with a call to
- /// Azure.Sdk.Tools.CodeOwnersParser.CodeOwnersFile.ParseContent().
+ /// Azure.Sdk.Tools.CodeOwnersParser.CodeownersFile.GetCodeownersEntries().
/// - As a consequence, in the case of no match, the entry is not valid.
/// - It does not contain unsupported characters (see "unsupportedChars").
/// - the Value.PathExpression starts with "/".
diff --git a/tools/identity-resolution/Services/GitHubService.cs b/tools/identity-resolution/Services/GitHubService.cs
index bbd40d23e3f9..0e4bb73ab7d8 100644
--- a/tools/identity-resolution/Services/GitHubService.cs
+++ b/tools/identity-resolution/Services/GitHubService.cs
@@ -16,8 +16,8 @@ public class GitHubService
{
private static readonly HttpClient httpClient = new HttpClient();
- private static readonly ConcurrentDictionary>
- codeownersFileCache = new ConcurrentDictionary>();
+ private static readonly ConcurrentDictionary>
+ codeownersFileCache = new ConcurrentDictionary>();
private readonly ILogger logger;
@@ -35,9 +35,9 @@ public GitHubService(ILogger logger)
///
/// GitHub repository URL
/// Contents fo the located CODEOWNERS file
- public async Task> GetCodeownersFile(Uri repoUrl)
+ public async Task> GetCodeownersFile(Uri repoUrl)
{
- List result;
+ List result;
if (codeownersFileCache.TryGetValue(repoUrl.ToString(), out result))
{
return result;
@@ -53,7 +53,7 @@ public async Task> GetCodeownersFile(Uri repoUrl)
///
///
///
- private async Task> GetCodeownersFileImpl(Uri repoUrl)
+ private async Task> GetCodeownersFileImpl(Uri repoUrl)
{
// Gets the repo path from the URL
var relevantPathParts = repoUrl.Segments.Skip(1).Take(2);
@@ -64,7 +64,7 @@ private async Task> GetCodeownersFileImpl(Uri repoUrl)
if (result.IsSuccessStatusCode)
{
logger.LogInformation("Retrieved CODEOWNERS file URL = {0}", codeOwnersUrl);
- return CodeOwnersFile.ParseContent(await result.Content.ReadAsStringAsync());
+ return CodeownersFile.GetCodeownersEntries(await result.Content.ReadAsStringAsync());
}
logger.LogWarning("Could not retrieve CODEOWNERS file URL = {0} ResponseCode = {1}", codeOwnersUrl, result.StatusCode);
diff --git a/tools/notification-configuration/notification-configuration.sln.DotSettings b/tools/notification-configuration/notification-configuration.sln.DotSettings
index 1e20132c27cb..8c1c0ec65f15 100644
--- a/tools/notification-configuration/notification-configuration.sln.DotSettings
+++ b/tools/notification-configuration/notification-configuration.sln.DotSettings
@@ -1,3 +1,4 @@
+ AAD
PR
True
\ No newline at end of file
diff --git a/tools/notification-configuration/notification-creator/NotificationConfigurator.cs b/tools/notification-configuration/notification-creator/NotificationConfigurator.cs
index 386e56a3f282..adecdc32fcbd 100644
--- a/tools/notification-configuration/notification-creator/NotificationConfigurator.cs
+++ b/tools/notification-configuration/notification-creator/NotificationConfigurator.cs
@@ -209,8 +209,8 @@ private async Task SyncTeamWithCodeOwnerFile(BuildDefinition pipeline, WebApiTea
logger.LogInformation("Searching CODEOWNERS for matching path for {0}", process.YamlFilename);
- var codeOwnerEntry = CodeOwnersFile.FindOwnersForClosestMatch(codeOwnerEntries, process.YamlFilename);
- codeOwnerEntry.FilterOutNonUserAliases();
+ var codeOwnerEntry = CodeownersFile.GetMatchingCodeownersEntry(process.YamlFilename, codeOwnerEntries);
+ codeOwnerEntry.ExcludeNonUserAliases();
logger.LogInformation("Matching Contacts Path = {0}, NumContacts = {1}", process.YamlFilename, codeOwnerEntry.Owners.Count);
diff --git a/tools/notification-configuration/notification-creator/YamlHelper.cs b/tools/notification-configuration/notification-creator/YamlHelper.cs
index bdad08f876ca..a8bf28802da1 100644
--- a/tools/notification-configuration/notification-creator/YamlHelper.cs
+++ b/tools/notification-configuration/notification-creator/YamlHelper.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
@@ -6,10 +6,10 @@ namespace Azure.Sdk.Tools.NotificationConfiguration
{
static class YamlHelper
{
- private static ISerializer serializer =
+ private static readonly ISerializer serializer =
new SerializerBuilder().WithNamingConvention(new CamelCaseNamingConvention()).Build();
- private static IDeserializer deserializer =
+ private static readonly IDeserializer deserializer =
new DeserializerBuilder().WithNamingConvention(new CamelCaseNamingConvention()).Build();