diff --git a/src/tooling/docs-builder/Cli/DiffCommands.cs b/src/tooling/docs-builder/Cli/DiffCommands.cs index 94f2bc3ec..fad052e6b 100644 --- a/src/tooling/docs-builder/Cli/DiffCommands.cs +++ b/src/tooling/docs-builder/Cli/DiffCommands.cs @@ -77,31 +77,33 @@ public async Task ValidateRedirects(string? path = null, Cancel ctx = defau if (changed.Length != 0) _log.LogInformation("Found {Count} changes to files related to documentation in the current branch.", changed.Length); - var missingRedirects = changed - .Where(c => - c.ChangeType is GitChangeType.Deleted or GitChangeType.Renamed - && !redirects.ContainsKey(c is RenamedGitChange renamed ? renamed.OldFilePath : c.FilePath) - ) - .ToArray(); - - if (missingRedirects.Length != 0) - { - var relativeRedirectFile = Path.GetRelativePath(root.FullName, redirectFile.Source.FullName); - _log.LogInformation("Found {Count} changes that still require updates to: {RedirectFile}", missingRedirects.Length, relativeRedirectFile); - } - - foreach (var notFound in missingRedirects) + var deletedAndRenamed = changed.Where(c => c.ChangeType is GitChangeType.Deleted or GitChangeType.Renamed).ToArray(); + var missingCount = 0; + foreach (var change in deletedAndRenamed) { - if (notFound is RenamedGitChange renamed) + var lookupPath = change is RenamedGitChange renamed ? renamed.OldFilePath : change.FilePath; + var docSetRelativePath = Path.GetRelativePath(buildContext.DocumentationSourceDirectory.FullName, Path.Combine(root.FullName, lookupPath)); + var rootRelativePath = Path.GetRelativePath(root.FullName, Path.Combine(root.FullName, lookupPath)); + if (redirects.ContainsKey(docSetRelativePath)) + continue; + if (redirects.ContainsKey(rootRelativePath)) { collector.EmitError(redirectFile.Source, - $"File '{renamed.OldFilePath}' was renamed to '{renamed.NewFilePath}' but it has no redirect configuration set."); - } - else if (notFound.ChangeType is GitChangeType.Deleted) - { - collector.EmitError(redirectFile.Source, - $"File '{notFound.FilePath}' was deleted but it has no redirect targets. This will lead to broken links."); + $"Redirect contains path relative to root '{rootRelativePath}' but should be relative to the documentation set '{docSetRelativePath}'"); + continue; } + missingCount++; + + if (change is RenamedGitChange rename) + collector.EmitError(redirectFile.Source, $"Missing '{docSetRelativePath}' in redirects.yml. '{rename.OldFilePath}' was renamed to '{rename.NewFilePath}' but it has no redirect configuration set."); + else if (change.ChangeType is GitChangeType.Deleted) + collector.EmitError(redirectFile.Source, $"Missing '{docSetRelativePath}' in redirects.yml. '{change.FilePath}' was deleted but it has no redirect targets. This will lead to broken links."); + } + + if (missingCount != 0) + { + var relativeRedirectFile = Path.GetRelativePath(root.FullName, redirectFile.Source.FullName); + _log.LogInformation("Found {Count} changes that still require updates to: {RedirectFile}", missingCount, relativeRedirectFile); } await collector.StopAsync(ctx);