Skip to content

Commit bf427c1

Browse files
committed
docs: use numbered editions and complete released API coverage
1 parent 7f62490 commit bf427c1

16 files changed

Lines changed: 651 additions & 227 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,6 @@ new-cli/logs/
131131

132132
# Agent skills (name collides with the VS build-output [Rr]elease/ rule above)
133133
!.agents/skills/release/
134+
135+
# Local agent planning notes
136+
/.devagent/

build/docs/Tasks/BuildDocs.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,5 @@ public override bool ShouldRun(BuildContext context)
1818
return shouldRun;
1919
}
2020

21-
public override void Run(BuildContext context)
22-
{
23-
VersionedDocs.Build(context);
24-
}
21+
public override void Run(BuildContext context) => VersionedDocs.Build(context);
2522
}

build/docs/Tasks/PreviewDocs.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,5 @@ public override bool ShouldRun(BuildContext context)
1616
return shouldRun;
1717
}
1818

19-
public override void Run(BuildContext context)
20-
{
21-
VersionedDocs.Preview(context);
22-
}
19+
public override void Run(BuildContext context) => VersionedDocs.Preview(context);
2320
}

build/docs/Tasks/PublishDocs.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,15 @@ private static void PublishDocumentation(BuildContext context)
7575
BranchName = publishBranchName
7676
});
7777

78-
foreach (var directory in System.IO.Directory.GetDirectories(publishFolder.FullPath))
78+
foreach (var directory in System.IO.Directory.GetDirectories(publishFolder.FullPath).Where(directory => System.IO.Path.GetFileName(directory) != ".git"))
7979
{
80-
if (System.IO.Path.GetFileName(directory) != ".git") System.IO.Directory.Delete(directory, true);
80+
System.IO.Directory.Delete(directory, true);
8181
}
82-
foreach (var file in System.IO.Directory.GetFiles(publishFolder.FullPath))
83-
if (System.IO.Path.GetFileName(file) is not ("CNAME" or ".nojekyll")) System.IO.File.Delete(file);
82+
foreach (var file in System.IO.Directory.GetFiles(publishFolder.FullPath).Where(file => System.IO.Path.GetFileName(file) is not ("CNAME" or ".nojekyll")))
83+
{
84+
System.IO.File.Delete(file);
85+
}
86+
8487
DocsInputs.CopyTree(context.MakeAbsolute(Paths.ArtifactsDocs.Combine("preview")).FullPath, publishFolder.FullPath);
8588

8689
var schemaTargetDir = publishFolder.Combine("schemas");

build/docs/Utilities/DocsApi.cs

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
using System.Xml.Linq;
12
using Microsoft.CodeAnalysis;
23
using Microsoft.CodeAnalysis.CSharp;
34
using Microsoft.CodeAnalysis.CSharp.Syntax;
4-
using System.Xml.Linq;
55
using Path = System.IO.Path;
66

77
namespace Docs.Utilities;
@@ -24,44 +24,76 @@ public static void Prepare(string source, string assemblies)
2424
var exported = Types(symbol.GlobalNamespace).Where(Public).ToArray();
2525
inventory.AddRange(exported.Select(t => t.GetDocumentationCommentId()!).Where(id => id is not null));
2626
routes.AddRange(exported.Select(t => t.ContainingNamespace.ToDisplayString() + "/" + t.MetadataName.Replace('`', '_') + "/index.html"));
27-
var project = Path.Combine(source, "src", name == "gitversion" ? "GitVersion.App" : name);
28-
if (!Directory.Exists(project)) continue;
29-
var trees = Directory.GetFiles(project, "*.cs", SearchOption.AllDirectories)
30-
.Where(p => !Path.GetRelativePath(project, p).Split(Path.DirectorySeparatorChar).Any(s => s is "bin" or "obj" or "Templates"))
31-
.Select(p => CSharpSyntaxTree.ParseText(File.ReadAllText(p), new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose), p)).ToArray();
32-
var compilation = CSharpCompilation.Create(name, trees, references.Where(r => r != assembly),
33-
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
34-
var path = Path.Combine(assemblies, name + ".xml");
35-
var document = File.Exists(path) ? XDocument.Load(path) : new XDocument(new XElement("doc", new XElement("assembly", new XElement("name", name)), new XElement("members")));
36-
var members = document.Root!.Element("members")!;
37-
var existing = members.Elements("member").Select(m => (string?)m.Attribute("name")).ToHashSet();
38-
foreach (var tree in trees)
39-
{
40-
var model = compilation.GetSemanticModel(tree);
41-
foreach (var node in tree.GetRoot().DescendantNodes().Where(n => n is MemberDeclarationSyntax or VariableDeclaratorSyntax))
42-
{
43-
var declared = model.GetDeclaredSymbol(node);
44-
var id = declared?.GetDocumentationCommentId();
45-
if (id is null || existing.Contains(id)) continue;
46-
var xml = declared!.GetDocumentationCommentXml();
47-
if (string.IsNullOrWhiteSpace(xml)) continue;
48-
try { members.Add(XElement.Parse(xml)); existing.Add(id); }
49-
catch (System.Xml.XmlException e) { throw new InvalidOperationException($"Invalid API comment for {id} in {tree.FilePath}", e); }
50-
}
51-
}
52-
document.Save(path);
27+
SupplementComments(source, assemblies, references, assembly, name);
5328
}
5429
File.WriteAllLines(Path.Combine(assemblies, "public-types.txt"), inventory.Order(StringComparer.Ordinal));
5530
File.WriteAllLines(Path.Combine(assemblies, "public-type-routes.txt"), routes.Order(StringComparer.Ordinal));
5631
}
5732

33+
private static void SupplementComments(string source, string assemblies, PortableExecutableReference[] references, PortableExecutableReference assembly, string name)
34+
{
35+
var project = Path.Combine(source, "src", name == "gitversion" ? "GitVersion.App" : name);
36+
if (!Directory.Exists(project))
37+
{
38+
return;
39+
}
40+
41+
var trees = Directory.GetFiles(project, "*.cs", SearchOption.AllDirectories)
42+
.Where(p => !Path.GetRelativePath(project, p).Split(Path.DirectorySeparatorChar).Any(s => s is "bin" or "obj" or "Templates"))
43+
.Select(p => CSharpSyntaxTree.ParseText(File.ReadAllText(p), new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose), p)).ToArray();
44+
var compilation = CSharpCompilation.Create(name, trees, references.Where(r => r != assembly),
45+
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
46+
var path = Path.Combine(assemblies, name + ".xml");
47+
var document = File.Exists(path) ? XDocument.Load(path) : new XDocument(new XElement("doc", new XElement("assembly", new XElement("name", name)), new XElement("members")));
48+
var members = document.Root!.Element("members")!;
49+
var existing = members.Elements("member").Select(m => (string?)m.Attribute("name")).ToHashSet();
50+
foreach (var tree in trees)
51+
{
52+
AddTreeComments(compilation.GetSemanticModel(tree), tree, members, existing);
53+
}
54+
55+
document.Save(path);
56+
}
57+
58+
private static void AddTreeComments(SemanticModel model, SyntaxTree tree, XElement members, HashSet<string?> existing)
59+
{
60+
foreach (var node in tree.GetRoot().DescendantNodes().Where(n => n is MemberDeclarationSyntax or VariableDeclaratorSyntax))
61+
{
62+
var declared = model.GetDeclaredSymbol(node);
63+
var id = declared?.GetDocumentationCommentId();
64+
if (id is null || existing.Contains(id))
65+
{
66+
continue;
67+
}
68+
69+
var xml = declared!.GetDocumentationCommentXml();
70+
if (string.IsNullOrWhiteSpace(xml))
71+
{
72+
continue;
73+
}
74+
75+
try { members.Add(XElement.Parse(xml)); existing.Add(id); }
76+
catch (System.Xml.XmlException e) { throw new InvalidOperationException($"Invalid API comment for {id} in {tree.FilePath}", e); }
77+
}
78+
79+
}
80+
5881
private static IEnumerable<INamedTypeSymbol> Types(INamespaceOrTypeSymbol parent)
5982
{
6083
foreach (var member in parent.GetMembers())
6184
{
62-
if (member is INamedTypeSymbol type) yield return type;
85+
if (member is INamedTypeSymbol type)
86+
{
87+
yield return type;
88+
}
89+
6390
if (member is INamespaceOrTypeSymbol container)
64-
foreach (var child in Types(container)) yield return child;
91+
{
92+
foreach (var child in Types(container))
93+
{
94+
yield return child;
95+
}
96+
}
6597
}
6698
}
6799

0 commit comments

Comments
 (0)