public async Task Can_match_file(string pattern, string file) { Helpers.WriteCodeOwnersEntry( Path.Combine(_workingDirectory.Directory, "CODEOWNERS"), pattern, "user1", "user2"); var result = await _codeOwnersBuilder.GetOwners(_fileProvider, file); result.ShouldBeEqualTo(new List <string> { "user1", "user2" }); }
public async Task <List <string> > GetUsersBetweenCommits(Commit from, Commit to) { var repo = ((IBelongToARepository)from).Repository; var users = new HashSet <string>(); var changes = repo.Diff.Compare <TreeChanges>(from.Tree, to.Tree); var files = new List <string>(); files.AddRange(changes.Added.Select(x => x.Path)); files.AddRange(changes.Copied.Select(x => x.Path)); files.AddRange(changes.Deleted.Select(x => x.Path)); files.AddRange(changes.Modified.Select(x => x.Path)); files.AddRange(changes.TypeChanged.Select(x => x.Path)); files.AddRange(changes.Conflicted.Select(x => x.Path)); files.AddRange(changes.Renamed.Select(x => x.Path)); // Since we have a list of all the files changed between these two commits, // We want to inspect the files on both the old commit and new commit. // This ensures we capture users who may have been removed from files // as a result of the commit. var oldUsers = await _walker.GetOwners(new RepositoryFileSystemProvider(from), files.ToArray()); var newUsers = await _walker.GetOwners(new RepositoryFileSystemProvider(to), files.ToArray()); foreach (var oldUser in oldUsers) { if (!users.Contains(oldUser)) { users.Add(oldUser); } } foreach (var newUser in newUsers) { if (!users.Contains(newUser)) { users.Add(newUser); } } async Task CheckForCodeOwnerUsers(TreeEntryChanges entryChanges) { if (Path.GetFileName(entryChanges.Path) == "CODEOWNERS") { var diff = repo.Diff.Compare(repo.Lookup <Blob>(entryChanges.OldOid), repo.Lookup <Blob>(entryChanges.Oid), new CompareOptions { ContextLines = 0, IncludeUnmodified = false }); if (!diff.IsBinaryComparison) { var unifiedConfig = await GetCodeOwnerConfigFromChanges(diff); foreach (var user in unifiedConfig.Entries.SelectMany(x => x.Users)) { var realUser = user.StartsWith("!") ? user.Substring(1) : user; if (!users.Contains(realUser)) { users.Add(realUser); } } } } } // In addition to matching users based on path alone, let's look to see if any // CODEOWNERS file was changed, and if so, call out the users that were added/removed. foreach (var added in changes.Added) { await CheckForCodeOwnerUsers(added); } foreach (var copied in changes.Copied) { await CheckForCodeOwnerUsers(copied); } foreach (var deleted in changes.Deleted) { await CheckForCodeOwnerUsers(deleted); } foreach (var modified in changes.Modified) { await CheckForCodeOwnerUsers(modified); } foreach (var typeChanged in changes.TypeChanged) { await CheckForCodeOwnerUsers(typeChanged); } foreach (var renamed in changes.Renamed) { await CheckForCodeOwnerUsers(renamed); } return(users.ToList()); }