diff --git a/src/Elastic.Markdown/IO/DocumentationSet.cs b/src/Elastic.Markdown/IO/DocumentationSet.cs index 1d22fd6..d2ba557 100644 --- a/src/Elastic.Markdown/IO/DocumentationSet.cs +++ b/src/Elastic.Markdown/IO/DocumentationSet.cs @@ -64,12 +64,18 @@ public DocumentationSet(BuildContext context) .ToDictionary(g => g.Key, g => g.ToArray()); var fileIndex = 0; - Tree = new DocumentationGroup(Configuration.TableOfContents, FlatMappedFiles, folderFiles, ref fileIndex) + Tree = new DocumentationGroup(Context, Configuration.TableOfContents, FlatMappedFiles, folderFiles, ref fileIndex) { Parent = null }; - MarkdownFiles = Files.OfType().ToDictionary(i => i.NavigationIndex, i => i).ToFrozenDictionary(); + var markdownFiles = Files.OfType().ToArray(); + + var excludedChildren = markdownFiles.Where(f => f.NavigationIndex == -1).ToArray(); + foreach (var excludedChild in excludedChildren) + Context.EmitError(Context.ConfigurationPath, $"{excludedChild.RelativePath} is unreachable in the TOC because one of its parents matches exclusion glob"); + + MarkdownFiles = markdownFiles.Where(f => f.NavigationIndex > -1).ToDictionary(i => i.NavigationIndex, i => i).ToFrozenDictionary(); } diff --git a/src/Elastic.Markdown/IO/MarkdownFile.cs b/src/Elastic.Markdown/IO/MarkdownFile.cs index cbd5224..e5ff571 100644 --- a/src/Elastic.Markdown/IO/MarkdownFile.cs +++ b/src/Elastic.Markdown/IO/MarkdownFile.cs @@ -61,7 +61,7 @@ public string? NavigationTitle public string FileName { get; } public string Url => $"{UrlPathPrefix}/{RelativePath.Replace(".md", ".html")}"; - public int NavigationIndex { get; set; } + public int NavigationIndex { get; internal set; } = -1; private bool _instructionsParsed; private DocumentationGroup? _parent; diff --git a/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs b/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs index 0faed81..3a80550 100644 --- a/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs +++ b/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs @@ -2,6 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.IO.Configuration; namespace Elastic.Markdown.IO.Navigation; @@ -33,16 +34,16 @@ public class DocumentationGroup public int Depth { get; } public DocumentationGroup( + BuildContext context, IReadOnlyCollection toc, IDictionary lookup, IDictionary folderLookup, ref int fileIndex, int depth = 0, - MarkdownFile? index = null - ) + MarkdownFile? index = null) { Depth = depth; - Index = ProcessTocItems(index, toc, lookup, folderLookup, depth, ref fileIndex, out var groups, out var files, out var navigationItems); + Index = ProcessTocItems(context, index, toc, lookup, folderLookup, depth, ref fileIndex, out var groups, out var files, out var navigationItems); GroupsInOrder = groups; FilesInOrder = files; @@ -55,6 +56,7 @@ public DocumentationGroup( } private MarkdownFile? ProcessTocItems( + BuildContext context, MarkdownFile? configuredIndex, IReadOnlyCollection toc, IDictionary lookup, @@ -73,15 +75,26 @@ public DocumentationGroup( { if (tocItem is FileReference file) { - if (!lookup.TryGetValue(file.Path, out var d) || d is not MarkdownFile md) + if (!lookup.TryGetValue(file.Path, out var d)) + { + context.EmitError(context.ConfigurationPath, $"The following file could not be located: {file.Path} it may be excluded from the build in docset.yml"); + continue; + } + if (d is ExcludedFile excluded && excluded.RelativePath.EndsWith(".md")) + { + context.EmitError(context.ConfigurationPath, $"{excluded.RelativePath} matches exclusion glob from docset.yml yet appears in TOC"); + continue; + } + if (d is not MarkdownFile md) continue; md.Parent = this; - md.NavigationIndex = ++fileIndex; + var navigationIndex = Interlocked.Increment(ref fileIndex); + md.NavigationIndex = navigationIndex; if (file.Children.Count > 0 && d is MarkdownFile virtualIndex) { - var group = new DocumentationGroup(file.Children, lookup, folderLookup, ref fileIndex, depth + 1, virtualIndex) + var group = new DocumentationGroup(context, file.Children, lookup, folderLookup, ref fileIndex, depth + 1, virtualIndex) { Parent = this }; @@ -111,7 +124,7 @@ public DocumentationGroup( .ToArray(); } - var group = new DocumentationGroup(children, lookup, folderLookup, ref fileIndex, depth + 1) + var group = new DocumentationGroup(context, children, lookup, folderLookup, ref fileIndex, depth + 1) { Parent = this };