Skip to content

Commit 7f8a219

Browse files
committed
Introduce records to keep track of git change data, and leverage them to make clearer reporting.
1 parent 6f88a94 commit 7f8a219

File tree

3 files changed

+83
-16
lines changed

3 files changed

+83
-16
lines changed

src/tooling/docs-builder/Cli/DiffCommands.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public async Task<int> ValidateRedirects([Argument] string? path = null, Cancel
3232
ConsoleApp.Log = msg => log.LogInformation(msg);
3333
ConsoleApp.LogError = msg => log.LogError(msg);
3434

35-
path ??= "docs";
35+
path ??= "";
3636

3737
await using var collector = new ConsoleDiagnosticsCollector(logger, githubActionsService).StartAsync(ctx);
3838

@@ -57,8 +57,20 @@ public async Task<int> ValidateRedirects([Argument] string? path = null, Cancel
5757
var tracker = new LocalGitRepositoryTracker(collector, root);
5858
var changed = tracker.GetChangedFiles(path);
5959

60-
foreach (var notFound in changed.Where(c => !redirects.ContainsKey(c)))
61-
collector.EmitError(notFound, $"{notFound} does not have a redirect rule set. Please add a redirect rule in this project's {redirectFileInfo.Name}.");
60+
foreach (var notFound in changed.Where(c => c.ChangeType is GitChangeType.Deleted or GitChangeType.Renamed
61+
&& !redirects.ContainsKey(c is RenamedGitChange renamed ? renamed.OldFilePath : c.FilePath)))
62+
{
63+
if (notFound is RenamedGitChange renamed)
64+
{
65+
collector.EmitError(redirectFileInfo.Name,
66+
$"File '{renamed.OldFilePath}' was renamed to '{renamed.NewFilePath}' but it has no redirect configuration set.");
67+
}
68+
else if (notFound.ChangeType is GitChangeType.Deleted)
69+
{
70+
collector.EmitError(redirectFileInfo.Name,
71+
$"File '{notFound.FilePath}' was deleted but it has no redirect targets. This will lead to broken links.");
72+
}
73+
}
6274

6375
await collector.StopAsync(ctx);
6476
return collector.Errors;

src/tooling/docs-builder/Tracking/IRepositoryTracker.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,17 @@
44

55
namespace Documentation.Builder.Tracking;
66

7+
public enum GitChangeType
8+
{
9+
Added,
10+
Modified,
11+
Deleted,
12+
Renamed,
13+
Untracked,
14+
Other
15+
}
16+
717
public interface IRepositoryTracker
818
{
9-
IEnumerable<string> GetChangedFiles(string lookupPath);
19+
IEnumerable<GitChange> GetChangedFiles(string lookupPath);
1020
}

src/tooling/docs-builder/Tracking/LocalGitRepositoryTracker.cs

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,21 @@
55
using System.IO.Abstractions;
66
using Elastic.Documentation.Diagnostics;
77
using Elastic.Documentation.Tooling.ExternalCommands;
8+
89
namespace Documentation.Builder.Tracking;
910

10-
public partial class LocalGitRepositoryTracker(DiagnosticsCollector collector, IDirectoryInfo workingDirectory) : ExternalCommandExecutor(collector, workingDirectory), IRepositoryTracker
11+
public record GitChange(string FilePath, GitChangeType ChangeType);
12+
public record RenamedGitChange(string OldFilePath, string NewFilePath, GitChangeType ChangeType) : GitChange(OldFilePath, ChangeType);
13+
14+
public class LocalGitRepositoryTracker(DiagnosticsCollector collector, IDirectoryInfo workingDirectory) : ExternalCommandExecutor(collector, workingDirectory), IRepositoryTracker
1115
{
12-
public IEnumerable<string> GetChangedFiles(string lookupPath)
16+
public IEnumerable<GitChange> GetChangedFiles(string lookupPath)
1317
{
1418
var defaultBranch = GetDefaultBranch();
1519
var commitChanges = CaptureMultiple("git", "diff", "--name-status", $"{defaultBranch}...HEAD", "--", $"./{lookupPath}");
1620
var localChanges = CaptureMultiple("git", "status", "--porcelain");
17-
List<string> output = [
18-
.. commitChanges
19-
.Where(line => line.StartsWith('R') || line.StartsWith('D') || line.StartsWith('A'))
20-
.Select(line => line.Split('\t')[1]),
21-
.. localChanges
22-
.Select(x => x.TrimStart())
23-
.Where(line => line.StartsWith('R') || line.StartsWith('D') || line.StartsWith("A ", StringComparison.Ordinal) || line.StartsWith("??"))
24-
.Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[1])
25-
];
26-
return output.Where(line => line.StartsWith(lookupPath));
21+
22+
return [.. GetCommitChanges(commitChanges), .. GetLocalChanges(localChanges)];
2723
}
2824

2925
private string GetDefaultBranch()
@@ -34,4 +30,53 @@ private string GetDefaultBranch()
3430
return "master";
3531
return Capture("git", "symbolic-ref", "refs/remotes/origin/HEAD").Split('/').Last();
3632
}
33+
34+
private static IEnumerable<GitChange> GetCommitChanges(string[] changes)
35+
{
36+
foreach (var change in changes)
37+
{
38+
var parts = change.AsSpan().TrimStart();
39+
if (parts.Length < 2)
40+
continue;
41+
42+
var changeType = parts[0] switch
43+
{
44+
'A' => GitChangeType.Added,
45+
'M' => GitChangeType.Modified,
46+
'D' => GitChangeType.Deleted,
47+
'R' => GitChangeType.Renamed,
48+
_ => GitChangeType.Other
49+
};
50+
51+
yield return new GitChange(change.Split('\t')[1], changeType);
52+
}
53+
}
54+
55+
private static IEnumerable<GitChange> GetLocalChanges(string[] changes)
56+
{
57+
foreach (var change in changes)
58+
{
59+
var changeStatusCode = change.AsSpan();
60+
if (changeStatusCode.Length < 2)
61+
continue;
62+
63+
var changeType = (changeStatusCode[0], changeStatusCode[1]) switch
64+
{
65+
('R', _) or (_, 'R') => GitChangeType.Renamed,
66+
('D', _) or (_, 'D') when changeStatusCode[0] != 'A' => GitChangeType.Deleted,
67+
('?', '?') => GitChangeType.Untracked,
68+
('A', _) or (_, 'A') => GitChangeType.Added,
69+
('M', _) or (_, 'M') => GitChangeType.Modified,
70+
_ => GitChangeType.Other
71+
};
72+
73+
var changeParts = change.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
74+
75+
yield return changeType switch
76+
{
77+
GitChangeType.Renamed => new RenamedGitChange(changeParts[1], changeParts[3], changeType),
78+
_ => new GitChange(changeParts[1], changeType)
79+
};
80+
}
81+
}
3782
}

0 commit comments

Comments
 (0)