Skip to content

Commit df31b39

Browse files
authored
Add exporter options to assembler (#1320)
* stage * stage * Add exporter options to assembler command line * ensure minimal parse skips validation again * Bump to ingest and transport that AOT compile under .NET 9
1 parent 78ae348 commit df31b39

File tree

21 files changed

+409
-68
lines changed

21 files changed

+409
-68
lines changed

Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<PackageVersion Include="AWSSDK.Core" Version="4.0.0.2" />
1717
<PackageVersion Include="AWSSDK.SQS" Version="4.0.0.1" />
1818
<PackageVersion Include="AWSSDK.S3" Version="4.0.0.1" />
19+
<PackageVersion Include="Elastic.Ingest.Elasticsearch" Version="0.11.3" />
1920
</ItemGroup>
2021
<!-- Build -->
2122
<ItemGroup>
@@ -63,4 +64,4 @@
6364
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
6465
<PackageVersion Include="xunit.v3" Version="1.1.0" />
6566
</ItemGroup>
66-
</Project>
67+
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Elastic.Ingest.Elasticsearch" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\Elastic.Documentation\Elastic.Documentation.csproj"/>
15+
</ItemGroup>
16+
17+
</Project>

src/Elastic.Documentation/Diagnostics/IDiagnosticsCollector.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ public static void EmitWarning(this IDiagnosticsCollector collector, IFileInfo f
3535

3636
public static void EmitHint(this IDiagnosticsCollector collector, IFileInfo file, string message) =>
3737
collector.EmitHint(file.FullName, message);
38+
39+
/// Emit an error not associated with a file
40+
public static void EmitGlobalError(this IDiagnosticsCollector collector, string message, Exception? e = null) =>
41+
collector.EmitError(string.Empty, message, e);
42+
43+
/// Emit a warning not associated with a file
44+
public static void EmitGlobalWarning(this IDiagnosticsCollector collector, string message) =>
45+
collector.EmitWarning(string.Empty, message);
46+
47+
/// Emit a hint not associated with a file
48+
public static void EmitGlobalHint(this IDiagnosticsCollector collector, string message) =>
49+
collector.EmitHint(string.Empty, message);
3850
}
3951

4052

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Text.Json.Serialization;
6+
7+
namespace Elastic.Documentation.Search;
8+
9+
public record DocumentationDocument
10+
{
11+
[JsonPropertyName("title")]
12+
public string? Title { get; set; }
13+
14+
[JsonPropertyName("body")]
15+
public string? Body { get; set; }
16+
17+
[JsonPropertyName("abstract")]
18+
public string? Abstract { get; set; }
19+
20+
[JsonPropertyName("headings")]
21+
public string[] Headings { get; set; } = [];
22+
23+
[JsonPropertyName("links")]
24+
public string[] Links { get; set; } = [];
25+
26+
[JsonPropertyName("url")]
27+
public string? Url { get; set; }
28+
}
29+

src/Elastic.Documentation/Serialization/SourceGenerationContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System.Text.Json.Serialization;
66
using Elastic.Documentation.Links;
7+
using Elastic.Documentation.Search;
78
using Elastic.Documentation.State;
89

910
namespace Elastic.Documentation.Serialization;
@@ -16,4 +17,5 @@ namespace Elastic.Documentation.Serialization;
1617
[JsonSerializable(typeof(GitCheckoutInformation))]
1718
[JsonSerializable(typeof(LinkRegistry))]
1819
[JsonSerializable(typeof(LinkRegistryEntry))]
20+
[JsonSerializable(typeof(DocumentationDocument))]
1921
public sealed partial class SourceGenerationContext : JsonSerializerContext;

src/Elastic.Markdown/DocumentationGenerator.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
namespace Elastic.Markdown;
2020

21+
/// Used primarily for testing, do not use in production paths since it might keep references alive to long
2122
public interface IConversionCollector
2223
{
2324
void Collect(MarkdownFile file, MarkdownDocument document, string html);
@@ -40,6 +41,7 @@ public class DocumentationGenerator
4041
private readonly ILogger _logger;
4142
private readonly IFileSystem _writeFileSystem;
4243
private readonly IDocumentationFileExporter _documentationFileExporter;
44+
private readonly IMarkdownExporter[] _markdownExporters;
4345
private HtmlWriter HtmlWriter { get; }
4446

4547
public DocumentationSet DocumentationSet { get; }
@@ -51,12 +53,14 @@ public DocumentationGenerator(
5153
ILoggerFactory logger,
5254
INavigationHtmlWriter? navigationHtmlWriter = null,
5355
IDocumentationFileOutputProvider? documentationFileOutputProvider = null,
56+
IMarkdownExporter[]? markdownExporters = null,
5457
IDocumentationFileExporter? documentationExporter = null,
5558
IConversionCollector? conversionCollector = null,
5659
ILegacyUrlMapper? legacyUrlMapper = null,
5760
IPositionalNavigation? positionalNavigation = null
5861
)
5962
{
63+
_markdownExporters = markdownExporters ?? [];
6064
_documentationFileOutputProvider = documentationFileOutputProvider;
6165
_conversionCollector = conversionCollector;
6266
_writeFileSystem = docSet.Context.WriteFileSystem;
@@ -100,7 +104,7 @@ public async Task<GenerationResult> GenerateAll(Cancel ctx)
100104

101105
var generationState = Context.SkipDocumentationState ? null : GetPreviousGenerationState();
102106

103-
// clear output directory if force is true but never for assembler builds since these build multiple times to the output.
107+
// clear the output directory if force is true but never for assembler builds since these build multiple times to the output.
104108
if (Context is { AssemblerBuild: false, Force: true }
105109
// clear the output directory if force is false but generation state is null, except for assembler builds.
106110
|| (Context is { AssemblerBuild: false, Force: false } && generationState == null))
@@ -209,7 +213,7 @@ private async Task ExtractEmbeddedStaticResources(Cancel ctx)
209213
}
210214
}
211215

212-
private async Task ProcessFile(HashSet<string> offendingFiles, DocumentationFile file, DateTimeOffset outputSeenChanges, Cancel token)
216+
private async Task ProcessFile(HashSet<string> offendingFiles, DocumentationFile file, DateTimeOffset outputSeenChanges, Cancel ctx)
213217
{
214218
if (!Context.Force)
215219
{
@@ -220,10 +224,27 @@ private async Task ProcessFile(HashSet<string> offendingFiles, DocumentationFile
220224
}
221225

222226
_logger.LogTrace("--> {FileFullPath}", file.SourceFile.FullName);
223-
//TODO send file to OutputFile() so we can validate its scope is defined in navigation.yml
224227
var outputFile = OutputFile(file.RelativePath);
225228
if (outputFile is not null)
226-
await _documentationFileExporter.ProcessFile(Context, file, outputFile, HtmlWriter, _conversionCollector, token);
229+
{
230+
var context = new ProcessingFileContext
231+
{
232+
BuildContext = Context,
233+
OutputFile = outputFile,
234+
ConversionCollector = _conversionCollector,
235+
File = file,
236+
HtmlWriter = HtmlWriter
237+
};
238+
await _documentationFileExporter.ProcessFile(context, ctx);
239+
if (file is MarkdownFile markdown)
240+
{
241+
foreach (var exporter in _markdownExporters)
242+
{
243+
var document = context.MarkdownDocument ??= await markdown.ParseFullAsync(ctx);
244+
_ = await exporter.ExportAsync(new MarkdownExportContext { Document = document, File = markdown }, ctx);
245+
}
246+
}
247+
}
227248
}
228249

229250
private IFileInfo? OutputFile(string relativePath)

src/Elastic.Markdown/Exporters/DocumentationFileExporter.cs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@
55
using System.IO.Abstractions;
66
using Elastic.Markdown.IO;
77
using Elastic.Markdown.Slices;
8+
using Markdig.Syntax;
89

910
namespace Elastic.Markdown.Exporters;
1011

12+
public class ProcessingFileContext
13+
{
14+
public required BuildContext BuildContext { get; init; }
15+
public required DocumentationFile File { get; init; }
16+
public required IFileInfo OutputFile { get; init; }
17+
public required HtmlWriter HtmlWriter { get; init; }
18+
public required IConversionCollector? ConversionCollector { get; init; }
19+
20+
public MarkdownDocument? MarkdownDocument { get; set; }
21+
}
22+
1123
public interface IDocumentationFileExporter
1224
{
13-
/// Used in documentation state to ensure we break the build cache if a different exporter is chosen
25+
/// Used in the documentation state to ensure we break the build cache if a different exporter is chosen
1426
string Name { get; }
1527

16-
Task ProcessFile(BuildContext context, DocumentationFile file, IFileInfo outputFile, HtmlWriter htmlWriter, IConversionCollector? conversionCollector,
17-
Cancel token);
28+
ValueTask ProcessFile(ProcessingFileContext context, Cancel ctx);
1829

1930
Task CopyEmbeddedResource(IFileInfo outputFile, Stream resourceStream, Cancel ctx);
2031
}
@@ -23,16 +34,14 @@ public abstract class DocumentationFileExporterBase(IFileSystem readFileSystem,
2334
{
2435
public abstract string Name { get; }
2536

26-
public abstract Task ProcessFile(BuildContext context, DocumentationFile file, IFileInfo outputFile, HtmlWriter htmlWriter,
27-
IConversionCollector? conversionCollector,
28-
Cancel token);
37+
public abstract ValueTask ProcessFile(ProcessingFileContext context, Cancel ctx);
2938

3039
protected async Task CopyFileFsAware(DocumentationFile file, IFileInfo outputFile, Cancel ctx)
3140
{
3241
// fast path, normal case.
3342
if (readFileSystem == writeFileSystem)
3443
readFileSystem.File.Copy(file.SourceFile.FullName, outputFile.FullName, true);
35-
//slower when we are mocking the write filesystem
44+
//slower when we are mocking the write-filesystem
3645
else
3746
{
3847
var bytes = await file.SourceFile.FileSystem.File.ReadAllBytesAsync(file.SourceFile.FullName, ctx);
@@ -49,26 +58,20 @@ public async Task CopyEmbeddedResource(IFileInfo outputFile, Stream resourceStre
4958
}
5059
}
5160

52-
public class DocumentationFileExporter(
53-
IFileSystem readFileSystem,
54-
IFileSystem writeFileSystem
55-
) : DocumentationFileExporterBase(readFileSystem, writeFileSystem)
61+
public class DocumentationFileExporter(IFileSystem readFileSystem, IFileSystem writeFileSystem)
62+
: DocumentationFileExporterBase(readFileSystem, writeFileSystem)
5663
{
57-
public override string Name { get; } = nameof(DocumentationFileExporter);
64+
public override string Name => nameof(DocumentationFileExporter);
5865

59-
public override async Task ProcessFile(BuildContext context, DocumentationFile file,
60-
IFileInfo outputFile,
61-
HtmlWriter htmlWriter,
62-
IConversionCollector? conversionCollector,
63-
Cancel token)
66+
public override async ValueTask ProcessFile(ProcessingFileContext context, Cancel ctx)
6467
{
65-
if (file is MarkdownFile markdown)
66-
await htmlWriter.WriteAsync(outputFile, markdown, conversionCollector, token);
68+
if (context.File is MarkdownFile markdown)
69+
context.MarkdownDocument = await context.HtmlWriter.WriteAsync(context.OutputFile, markdown, context.ConversionCollector, ctx);
6770
else
6871
{
69-
if (outputFile.Directory is { Exists: false })
70-
outputFile.Directory.Create();
71-
await CopyFileFsAware(file, outputFile, token);
72+
if (context.OutputFile.Directory is { Exists: false })
73+
context.OutputFile.Directory.Create();
74+
await CopyFileFsAware(context.File, context.OutputFile, ctx);
7275
}
7376
}
7477
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Elastic.Markdown.IO;
6+
using Markdig.Syntax;
7+
8+
namespace Elastic.Markdown.Exporters;
9+
10+
public class MarkdownExportContext
11+
{
12+
public required MarkdownDocument Document { get; init; }
13+
public required MarkdownFile File { get; init; }
14+
public string? LLMText { get; set; }
15+
}
16+
17+
public interface IMarkdownExporter
18+
{
19+
ValueTask StartAsync(Cancel ctx = default);
20+
ValueTask StopAsync(Cancel ctx = default);
21+
ValueTask<bool> ExportAsync(MarkdownExportContext context, Cancel ctx);
22+
}

src/Elastic.Markdown/Exporters/NoopDocumentationFileExporter.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@
33
// See the LICENSE file in the project root for more information
44

55
using System.IO.Abstractions;
6-
using Elastic.Markdown.IO;
7-
using Elastic.Markdown.Slices;
86

97
namespace Elastic.Markdown.Exporters;
108

119
public class NoopDocumentationFileExporter : IDocumentationFileExporter
1210
{
1311
public string Name { get; } = nameof(NoopDocumentationFileExporter);
1412

15-
public Task ProcessFile(BuildContext context, DocumentationFile file, IFileInfo outputFile, HtmlWriter htmlWriter,
16-
IConversionCollector? conversionCollector, Cancel token) =>
17-
Task.CompletedTask;
13+
public ValueTask ProcessFile(ProcessingFileContext context, Cancel ctx) =>
14+
ValueTask.CompletedTask;
1815

1916
public Task CopyEmbeddedResource(IFileInfo outputFile, Stream resourceStream, Cancel ctx) => Task.CompletedTask;
2017
}

src/Elastic.Markdown/Extensions/DetectionRules/RuleDocumentationFileExporter.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,24 @@ public class RuleDocumentationFileExporter(IFileSystem readFileSystem, IFileSyst
1414
{
1515
public override string Name { get; } = nameof(RuleDocumentationFileExporter);
1616

17-
public override async Task ProcessFile(BuildContext context, DocumentationFile file, IFileInfo outputFile, HtmlWriter htmlWriter,
18-
IConversionCollector? conversionCollector, Cancel token)
17+
public override async ValueTask ProcessFile(ProcessingFileContext context, Cancel ctx)
1918
{
20-
if (file is DetectionRuleFile df)
21-
await htmlWriter.WriteAsync(DetectionRuleFile.OutputPath(outputFile, context), df, conversionCollector, token);
22-
else if (file is MarkdownFile markdown)
23-
await htmlWriter.WriteAsync(outputFile, markdown, conversionCollector, token);
24-
else
19+
var htmlWriter = context.HtmlWriter;
20+
var outputFile = context.OutputFile;
21+
var conversionCollector = context.ConversionCollector;
22+
switch (context.File)
2523
{
26-
if (outputFile.Directory is { Exists: false })
27-
outputFile.Directory.Create();
28-
await CopyFileFsAware(file, outputFile, token);
24+
case DetectionRuleFile df:
25+
context.MarkdownDocument = await htmlWriter.WriteAsync(DetectionRuleFile.OutputPath(outputFile, context.BuildContext), df, conversionCollector, ctx);
26+
break;
27+
case MarkdownFile markdown:
28+
context.MarkdownDocument = await htmlWriter.WriteAsync(outputFile, markdown, conversionCollector, ctx);
29+
break;
30+
default:
31+
if (outputFile.Directory is { Exists: false })
32+
outputFile.Directory.Create();
33+
await CopyFileFsAware(context.File, outputFile, ctx);
34+
break;
2935
}
3036
}
3137
}

0 commit comments

Comments
 (0)