|
3 | 3 |
|
4 | 4 | namespace Microsoft.DocAsCode.Build.SchemaDriven
|
5 | 5 | {
|
| 6 | + using System; |
6 | 7 | using System.Collections.Generic;
|
7 | 8 | using System.Composition;
|
8 | 9 | using System.Linq;
|
9 | 10 |
|
10 | 11 | using Microsoft.DocAsCode.Build.Common;
|
| 12 | + using Microsoft.DocAsCode.Build.OverwriteDocuments; |
11 | 13 | using Microsoft.DocAsCode.Common;
|
| 14 | + using Microsoft.DocAsCode.Exceptions; |
| 15 | + using Microsoft.DocAsCode.MarkdigEngine; |
12 | 16 | using Microsoft.DocAsCode.Plugins;
|
13 | 17 |
|
14 |
| - [Export(nameof(SchemaDrivenDocumentProcessor), typeof(IDocumentBuildStep))] |
| 18 | + // [Export(nameof(SchemaDrivenDocumentProcessor), typeof(IDocumentBuildStep))] |
| 19 | + // TODO: export to the entire SchemaDrivenDocumentProcessor when incremental is ready |
| 20 | + [Export("SchemaDrivenDocumentProcessor.RESTComponentV3", typeof(IDocumentBuildStep))] |
| 21 | + [Export("SchemaDrivenDocumentProcessor.RESTOperationV3", typeof(IDocumentBuildStep))] |
| 22 | + [Export("SchemaDrivenDocumentProcessor.RESTOperationGroupV3", typeof(IDocumentBuildStep))] |
15 | 23 | public class ApplyOverwriteFragments : BaseDocumentBuildStep, ISupportIncrementalBuildStep
|
16 | 24 | {
|
17 | 25 | public override string Name => nameof(ApplyOverwriteFragments);
|
18 | 26 |
|
19 | 27 | public override int BuildOrder => 0x08;
|
20 | 28 |
|
21 |
| - public virtual void Build(FileModel model, IHostService host) |
| 29 | + public override void Build(FileModel model, IHostService host) |
22 | 30 | {
|
23 |
| - var overwriteApplier = new OverwriteApplier(host, OverwriteModelType.MarkdownFragments); |
24 |
| - |
25 |
| - var overwriteDocumentModels = model.MarkdownFragmentsModel?.Content as List<OverwriteDocumentModel>; |
26 |
| - if (overwriteDocumentModels == null) |
| 31 | + if (model.MarkdownFragmentsModel == null) |
27 | 32 | {
|
28 | 33 | return;
|
29 | 34 | }
|
| 35 | + if (!(model.MarkdownFragmentsModel.Content is string)) |
| 36 | + { |
| 37 | + var message = "Unable to parse markdown fragments. Expect string content."; |
| 38 | + Logger.LogError(message); |
| 39 | + throw new DocfxException(message); |
| 40 | + } |
| 41 | + if (model.MarkdownFragmentsModel.Properties.MarkdigMarkdownService == null || !(model.MarkdownFragmentsModel.Properties.MarkdigMarkdownService is MarkdigMarkdownService)) |
| 42 | + { |
| 43 | + var message = "Unable to find markdig markdown service in file model."; |
| 44 | + Logger.LogError(message); |
| 45 | + throw new DocfxException(message); |
| 46 | + } |
| 47 | + if (!(model.Properties.Schema is DocumentSchema)) |
| 48 | + { |
| 49 | + var message = "Unable to find schema in file model."; |
| 50 | + Logger.LogError(message); |
| 51 | + throw new DocfxException(message); |
| 52 | + } |
30 | 53 |
|
31 |
| - var schema = model.Properties.Schema as DocumentSchema; |
32 |
| - using (new LoggerFileScope(model.LocalPathFromRoot)) |
| 54 | + using (new LoggerFileScope(model.MarkdownFragmentsModel.LocalPathFromRoot)) |
33 | 55 | {
|
34 |
| - foreach (var overwriteDocumentModel in overwriteDocumentModels) |
| 56 | + try |
| 57 | + { |
| 58 | + BuildCore(model, host); |
| 59 | + } |
| 60 | + catch (MarkdownFragmentsException ex) |
35 | 61 | {
|
36 |
| - var uidDefiniton = model.Uids.Where(s => s.Name == overwriteDocumentModel.Uid).ToList(); |
37 |
| - if (uidDefiniton.Count == 0) |
38 |
| - { |
39 |
| - Logger.LogWarning($"Unable to find UidDefinition for Uid {overwriteDocumentModel.Uid}"); |
40 |
| - } |
41 |
| - |
42 |
| - if (uidDefiniton.Count > 1) |
43 |
| - { |
44 |
| - Logger.LogWarning($"There are more than one UidDefinitions found for Uid {overwriteDocumentModel.Uid} in lines {string.Join(", ", uidDefiniton.Select(uid => uid.Line).ToList())}"); |
45 |
| - } |
46 |
| - |
47 |
| - var ud = uidDefiniton[0]; |
48 |
| - var jsonPointer = new JsonPointer(ud.Path).GetParentPointer(); |
49 |
| - var schemaForCurrentUid = jsonPointer.FindSchema(schema); |
50 |
| - var source = jsonPointer.GetValue(model.Content); |
51 |
| - |
52 |
| - overwriteApplier.MergeContentWithOverwrite(ref source, overwriteDocumentModel.Metadata, ud.Name, string.Empty, schemaForCurrentUid); |
| 62 | + Logger.LogWarning( |
| 63 | + $"Unable to parse markdown fragments: {ex.Message}", |
| 64 | + line: ex.Position == -1 ? null : ex.Position.ToString(), |
| 65 | + code: WarningCodes.Overwrite.InvalidMarkdownFragments); |
| 66 | + return; |
53 | 67 | }
|
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + private void BuildCore(FileModel model, IHostService host) |
| 72 | + { |
| 73 | + var markdownService = (MarkdigMarkdownService)model.MarkdownFragmentsModel.Properties.MarkdigMarkdownService; |
| 74 | + var overwriteDocumentModelCreater = new OverwriteDocumentModelCreater(model.File); |
| 75 | + var overwriteApplier = new OverwriteApplier(host, OverwriteModelType.MarkdownFragments); |
| 76 | + var schema = model.Properties.Schema as DocumentSchema; |
| 77 | + List<OverwriteDocumentModel> overwriteDocumentModels; |
| 78 | + |
| 79 | + // 1. string => AST(MarkdownDocument) |
| 80 | + var ast = markdownService.Parse((string)model.MarkdownFragmentsModel.Content, model.File); |
54 | 81 |
|
55 |
| - // 1. Validate schema after the merge |
56 |
| - ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content); |
| 82 | + // 2 AST(MarkdownDocument) => MarkdownFragmentModel |
| 83 | + var fragments = new MarkdownFragmentsCreater().Create(ast); |
| 84 | + |
| 85 | + // 3. MarkdownFragmentModel => OverwriteDocument |
| 86 | + overwriteDocumentModels = fragments.Select(overwriteDocumentModelCreater.Create).ToList(); |
| 87 | + |
| 88 | + // 4. Apply schema to OverwriteDocument, and merge with skeyleton YAML object |
| 89 | + foreach (var overwriteDocumentModel in overwriteDocumentModels) |
| 90 | + { |
| 91 | + var uidDefinitons = model.Uids.Where(s => s.Name == overwriteDocumentModel.Uid).ToList(); |
| 92 | + if (uidDefinitons.Count == 0) |
| 93 | + { |
| 94 | + throw new DocfxException($"Unable to find UidDefinition for Uid {overwriteDocumentModel.Uid}"); |
| 95 | + } |
| 96 | + if (uidDefinitons.Count > 1) |
| 97 | + { |
| 98 | + Logger.LogWarning($"There are more than one UidDefinitions found for Uid {overwriteDocumentModel.Uid} in lines {string.Join(", ", uidDefinitons.Select(uid => uid.Line).ToList())}"); |
| 99 | + } |
57 | 100 |
|
58 |
| - // 2. Re-export xrefspec after the merge |
59 |
| - overwriteApplier.UpdateXrefSpec(model, schema); |
| 101 | + var ud = uidDefinitons[0]; |
| 102 | + var jsonPointer = new JsonPointer(ud.Path).GetParentPointer(); |
| 103 | + var schemaForCurrentUid = jsonPointer.FindSchema(schema); |
| 104 | + var source = jsonPointer.GetValue(model.Content); |
| 105 | + overwriteApplier.BuildOverwriteWithSchema(model.MarkdownFragmentsModel, overwriteDocumentModel, schema); |
| 106 | + overwriteApplier.MergeContentWithOverwrite(ref source, overwriteDocumentModel.Metadata, ud.Name, string.Empty, schemaForCurrentUid); |
60 | 107 | }
|
| 108 | + |
| 109 | + // 5. Validate schema after the merge |
| 110 | + ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content); |
| 111 | + |
| 112 | + // 6. Re-export xrefspec after the merge |
| 113 | + overwriteApplier.UpdateXrefSpec(model, schema); |
| 114 | + |
| 115 | + model.LinkToUids = model.LinkToUids.Union(model.MarkdownFragmentsModel.LinkToUids); |
| 116 | + model.LinkToFiles = model.LinkToFiles.Union(model.MarkdownFragmentsModel.LinkToFiles); |
| 117 | + model.FileLinkSources = model.FileLinkSources.Merge(model.MarkdownFragmentsModel.FileLinkSources); |
| 118 | + model.UidLinkSources = model.UidLinkSources.Merge(model.MarkdownFragmentsModel.UidLinkSources); |
| 119 | + model.MarkdownFragmentsModel.Content = overwriteDocumentModels; |
61 | 120 | }
|
62 | 121 |
|
63 | 122 | #region ISupportIncrementalBuildStep Members
|
64 | 123 |
|
65 |
| - public bool CanIncrementalBuild(FileAndType fileAndType) => true; |
| 124 | + // TODO: support incremental build |
| 125 | + public bool CanIncrementalBuild(FileAndType fileAndType) => false; |
66 | 126 |
|
67 | 127 | public string GetIncrementalContextHash() => null;
|
68 | 128 |
|
|
0 commit comments