in src/tooling/docs-assembler/Links/NavigationPrefixChecker.cs [82:127]
public async Task CheckAllPublishedLinks(DiagnosticsCollector collector, Cancel ctx) =>
await FetchAndValidateCrossLinks(collector, null, null, ctx);
private async Task FetchAndValidateCrossLinks(DiagnosticsCollector collector, string? updateRepository, LinkReference? updateReference, Cancel ctx)
{
var fetcher = new LinksIndexCrossLinkFetcher(_loggerFactory);
var resolver = new CrossLinkResolver(fetcher);
var crossLinks = await resolver.FetchLinks(ctx);
var dictionary = new Dictionary<string, SeenPaths>();
if (!string.IsNullOrEmpty(updateRepository) && updateReference is not null)
crossLinks = resolver.UpdateLinkReference(updateRepository, updateReference);
foreach (var (repository, linkReference) in crossLinks.LinkReferences)
{
if (!_repositories.Contains(repository))
continue;
// Todo publish all relative folders as part of the link reference
// That way we don't need to iterate over all links and find all permutations of their relative paths
foreach (var (relativeLink, _) in linkReference.Links)
{
var navigationPaths = _uriResolver.ResolveToSubPaths(new Uri($"{repository}://{relativeLink}"), relativeLink);
foreach (var navigationPath in navigationPaths)
{
if (dictionary.TryGetValue(navigationPath, out var seen))
{
if (seen.Repository == repository)
continue;
if (_phantoms.Count > 0 && _phantoms.Contains(new Uri($"{repository}://{navigationPath}")))
continue;
var url = _uriResolver.Resolve(new Uri($"{repository}://{relativeLink}"), PublishEnvironmentUriResolver.MarkdownPathToUrlPath(relativeLink));
collector.EmitError(repository,
$"'{seen.Repository}' defines: '{seen.Path}' that '{repository}://{relativeLink} resolving to '{url.AbsolutePath}' conflicts with ");
}
else
{
dictionary.Add(navigationPath, new SeenPaths
{
Repository = repository,
Path = navigationPath
});
}
}
}
}
}