From 007ba8f66c54f1afa25743a240ae2e5a574fc29e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thyge=20Sk=C3=B8dt=20Steffensen?= <31892312+thygesteffensen@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:38:33 +0100 Subject: [PATCH] feat: Working version of documentation extractor and markdown generated --- ...tensions.Manifest.ManifestEnricherTool.sln | 2 +- external/EAVFramework | 2 +- ...tensions.Docs.Extracter.csproj.DotSettings | 6 - .../PluginRegistrationAttributeConverter.cs | 34 ---- .../JsonConverters/TypeConverter.cs | 20 --- .../Plugin/PluginDocumentation.cs | 20 --- .../CustomAssemblyResolver.cs | 2 +- .../DocumentLogic.cs | 13 +- .../EAVFW.Extensions.Docs.Extractor.csproj} | 1 + .../IDocumentLogic.cs | 2 +- .../Plugin/AssemblyInfo.cs | 2 +- .../Plugin/PluginDocumentation.cs | 20 +++ .../Plugin/PluginInfo.cs | 2 +- .../Plugin/PluginRegistrationAttributeData.cs | 12 ++ .../Plugin/TypeInformation.cs | 24 +++ .../Plugin/XmlDocumentationHelper.cs | 2 +- .../Plugin/XmlMemberElement.cs | 2 +- .../ServiceCollectionExtension.cs | 2 +- .../EAVFW.Extensions.Docs.Generator.csproj | 2 +- .../IDocumentationGenerator.cs | 16 ++ .../PluginDocumentationToReadMe.cs | 125 -------------- .../ReadMeDocumentationGenerator.cs | 155 ++++++++++++++++++ .../DocumentationGeneratorCommand.cs | 92 +++++++++++ .../DocumentationSourceCommand.cs | 24 +++ .../DocumentationSourceExtractorCommand.cs} | 50 +++--- ...sions.Manifest.ManifestEnricherTool.csproj | 2 +- .../Program.cs | 7 +- .../Properties/launchSettings.json | 5 +- 28 files changed, 394 insertions(+), 252 deletions(-) delete mode 100644 src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj.DotSettings delete mode 100644 src/EAVFW.Extensions.Docs.Extracter/JsonConverters/PluginRegistrationAttributeConverter.cs delete mode 100644 src/EAVFW.Extensions.Docs.Extracter/JsonConverters/TypeConverter.cs delete mode 100644 src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginDocumentation.cs rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/CustomAssemblyResolver.cs (96%) rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/DocumentLogic.cs (92%) rename src/{EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj => EAVFW.Extensions.Docs.Extractor/EAVFW.Extensions.Docs.Extractor.csproj} (92%) rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/IDocumentLogic.cs (95%) rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/Plugin/AssemblyInfo.cs (81%) create mode 100644 src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginDocumentation.cs rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/Plugin/PluginInfo.cs (96%) create mode 100644 src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginRegistrationAttributeData.cs create mode 100644 src/EAVFW.Extensions.Docs.Extractor/Plugin/TypeInformation.cs rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/Plugin/XmlDocumentationHelper.cs (97%) rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/Plugin/XmlMemberElement.cs (85%) rename src/{EAVFW.Extensions.Docs.Extracter => EAVFW.Extensions.Docs.Extractor}/ServiceCollectionExtension.cs (89%) create mode 100644 src/EAVFW.Extensions.Docs.Generator/IDocumentationGenerator.cs delete mode 100644 src/EAVFW.Extensions.Docs.Generator/PluginDocumentationToReadMe.cs create mode 100644 src/EAVFW.Extensions.Docs.Generator/ReadMeDocumentationGenerator.cs create mode 100644 src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationGeneratorCommand.cs create mode 100644 src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceCommand.cs rename src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/{DocumentCommand.cs => Documentation/DocumentationSourceExtractorCommand.cs} (75%) diff --git a/EAVFW.Extensions.Manifest.ManifestEnricherTool.sln b/EAVFW.Extensions.Manifest.ManifestEnricherTool.sln index 1cb1253..146db41 100644 --- a/EAVFW.Extensions.Manifest.ManifestEnricherTool.sln +++ b/EAVFW.Extensions.Manifest.ManifestEnricherTool.sln @@ -44,7 +44,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EAVFramework", "external\EA EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EAVFW.Extensions.Manifest.SDK", "external\EAVFramework\sdk\EAVFW.Extensions.Manifest.SDK.csproj", "{3BEF0769-ABD1-4D34-8004-C98DE9FB0339}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EAVFW.Extensions.Docs.Extracter", "src\EAVFW.Extensions.Docs.Extracter\EAVFW.Extensions.Docs.Extracter.csproj", "{432042AB-6A78-4ED7-B8AC-73B047F6630F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EAVFW.Extensions.Docs.Extractor", "src\EAVFW.Extensions.Docs.Extractor\EAVFW.Extensions.Docs.Extractor.csproj", "{432042AB-6A78-4ED7-B8AC-73B047F6630F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EAVFW.Extensions.Docs.Generator", "src\EAVFW.Extensions.Docs.Generator\EAVFW.Extensions.Docs.Generator.csproj", "{71FCB365-F4AE-4578-BF86-B4A3C278B6B1}" EndProject diff --git a/external/EAVFramework b/external/EAVFramework index 65e40e2..f58d2ee 160000 --- a/external/EAVFramework +++ b/external/EAVFramework @@ -1 +1 @@ -Subproject commit 65e40e29208c746d0580ee123845df11f209d3b1 +Subproject commit f58d2eeef1ad7c24177e434fd093465c16e55094 diff --git a/src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj.DotSettings b/src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj.DotSettings deleted file mode 100644 index 6ed5a98..0000000 --- a/src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj.DotSettings +++ /dev/null @@ -1,6 +0,0 @@ - - True diff --git a/src/EAVFW.Extensions.Docs.Extracter/JsonConverters/PluginRegistrationAttributeConverter.cs b/src/EAVFW.Extensions.Docs.Extracter/JsonConverters/PluginRegistrationAttributeConverter.cs deleted file mode 100644 index bc70d3c..0000000 --- a/src/EAVFW.Extensions.Docs.Extracter/JsonConverters/PluginRegistrationAttributeConverter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using EAVFramework.Plugins; - -namespace EAVFW.Extensions.Docs.Extracter -{ - public class PluginRegistrationAttributeConverter : JsonConverter - { - public override PluginRegistrationAttribute? Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) - { - throw new NotImplementedException(); - } - - public override void Write( - Utf8JsonWriter writer, - PluginRegistrationAttribute value, - JsonSerializerOptions options) - { - var _object = new JsonObject - { - { nameof(value.Order), value.Order }, - { nameof(value.Operation), value.Operation.ToString() }, - { nameof(value.Execution), value.Execution.ToString() }, - { nameof(value.Mode), value.Mode.ToString() } - }; - _object.WriteTo(writer); - } - } -} diff --git a/src/EAVFW.Extensions.Docs.Extracter/JsonConverters/TypeConverter.cs b/src/EAVFW.Extensions.Docs.Extracter/JsonConverters/TypeConverter.cs deleted file mode 100644 index 3154860..0000000 --- a/src/EAVFW.Extensions.Docs.Extracter/JsonConverters/TypeConverter.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; - -namespace EAVFW.Extensions.Docs.Extracter -{ - public class TypeConverter : JsonConverter - { - public override Type? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - throw new NotImplementedException(); - } - - public override void Write(Utf8JsonWriter writer, Type value, JsonSerializerOptions options) - { - JsonValue.Create(value.Name).WriteTo(writer, options); - } - } -} diff --git a/src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginDocumentation.cs b/src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginDocumentation.cs deleted file mode 100644 index e6ae712..0000000 --- a/src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginDocumentation.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.Json.Serialization; -using EAVFramework.Plugins; - -namespace EAVFW.Extensions.Docs.Extracter -{ - public class PluginDocumentation - { - public IEnumerable PluginRegistrations { get; set; } = - Array.Empty(); - - public string? Name { get; set; } - - [JsonConverter(typeof(TypeConverter))] public Type? Context { get; set; } - - [JsonConverter(typeof(TypeConverter))] public Type? Entity { get; set; } - public string Summary { get; set; } = ""; - } -} diff --git a/src/EAVFW.Extensions.Docs.Extracter/CustomAssemblyResolver.cs b/src/EAVFW.Extensions.Docs.Extractor/CustomAssemblyResolver.cs similarity index 96% rename from src/EAVFW.Extensions.Docs.Extracter/CustomAssemblyResolver.cs rename to src/EAVFW.Extensions.Docs.Extractor/CustomAssemblyResolver.cs index a2922f3..f0f8d67 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/CustomAssemblyResolver.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/CustomAssemblyResolver.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Reflection; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public static class CustomAssemblyResolver { diff --git a/src/EAVFW.Extensions.Docs.Extracter/DocumentLogic.cs b/src/EAVFW.Extensions.Docs.Extractor/DocumentLogic.cs similarity index 92% rename from src/EAVFW.Extensions.Docs.Extracter/DocumentLogic.cs rename to src/EAVFW.Extensions.Docs.Extractor/DocumentLogic.cs index 0da526c..3ac7e5e 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/DocumentLogic.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/DocumentLogic.cs @@ -4,14 +4,12 @@ using System.Linq; using System.Reflection; using System.Runtime.Loader; -using System.Security.Principal; using System.Text.Json; -using System.Text.Json.Serialization; using EAVFramework.Plugins; using EAVFW.Extensions.Manifest.SDK; using WorkflowEngine.Core; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public class DocumentLogic : IDocumentLogic { @@ -53,11 +51,12 @@ from implementingType in implementingTypes .FirstOrDefault(i => i.GenericTypeArguments.Length == 2) select new PluginDocumentation { - PluginRegistrations = pluginRegistrations, + PluginRegistrations = pluginRegistrations.Select(x => new PluginRegistrationAttributeData + { Order = x.Order, Execution = x.Execution, Operation = x.Operation, Mode = x.Mode }), Name = implementingType.Name, Summary = implementingType.GetDocumentation(), - Context = _interface.GetGenericArguments().First(), - Entity = _interface.GetGenericArguments().Last() + Context = new TypeInformation(_interface.GetGenericArguments().First()), + Entity = new TypeInformation(_interface.GetGenericArguments().Last()) }; return plugins; @@ -106,7 +105,7 @@ from wizard in entity.Value.Wizards from _tabs in wizard.Value.Tabs select _tabs).AsEnumerable(); - // Glorified for loop? + // Glorified for loop?w var tabsWithWorkflows = from tab in tabs where tab.Value.OnTransitionOut?.Workflow != null || tab.Value.OnTransitionIn?.Workflow != null diff --git a/src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj b/src/EAVFW.Extensions.Docs.Extractor/EAVFW.Extensions.Docs.Extractor.csproj similarity index 92% rename from src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj rename to src/EAVFW.Extensions.Docs.Extractor/EAVFW.Extensions.Docs.Extractor.csproj index c87d43c..a3fecf8 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/EAVFW.Extensions.Docs.Extracter.csproj +++ b/src/EAVFW.Extensions.Docs.Extractor/EAVFW.Extensions.Docs.Extractor.csproj @@ -4,6 +4,7 @@ 9.0 net8.0 enable + EAVFW.Extensions.Docs.Extracter diff --git a/src/EAVFW.Extensions.Docs.Extracter/IDocumentLogic.cs b/src/EAVFW.Extensions.Docs.Extractor/IDocumentLogic.cs similarity index 95% rename from src/EAVFW.Extensions.Docs.Extracter/IDocumentLogic.cs rename to src/EAVFW.Extensions.Docs.Extractor/IDocumentLogic.cs index bb70159..e74952c 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/IDocumentLogic.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/IDocumentLogic.cs @@ -2,7 +2,7 @@ using System.IO; using EAVFW.Extensions.Manifest.SDK; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public interface IDocumentLogic { diff --git a/src/EAVFW.Extensions.Docs.Extracter/Plugin/AssemblyInfo.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/AssemblyInfo.cs similarity index 81% rename from src/EAVFW.Extensions.Docs.Extracter/Plugin/AssemblyInfo.cs rename to src/EAVFW.Extensions.Docs.Extractor/Plugin/AssemblyInfo.cs index d76edcc..6168edb 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/Plugin/AssemblyInfo.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/AssemblyInfo.cs @@ -1,4 +1,4 @@ -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public class AssemblyInfo { diff --git a/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginDocumentation.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginDocumentation.cs new file mode 100644 index 0000000..facc0f5 --- /dev/null +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginDocumentation.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace EAVFW.Extensions.Docs.Extractor +{ + public class PluginDocumentation + { + public IEnumerable PluginRegistrations { get; set; } = + Array.Empty(); + + public string? Name { get; set; } + + [JsonPropertyName("context")] public TypeInformation Context { get; set; } + + [JsonPropertyName("entity")] public TypeInformation Entity { get; set; } + + public string Summary { get; set; } = ""; + } +} diff --git a/src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginInfo.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginInfo.cs similarity index 96% rename from src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginInfo.cs rename to src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginInfo.cs index f26bf60..344c615 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/Plugin/PluginInfo.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginInfo.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public struct PluginInfo { diff --git a/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginRegistrationAttributeData.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginRegistrationAttributeData.cs new file mode 100644 index 0000000..84ec9b5 --- /dev/null +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/PluginRegistrationAttributeData.cs @@ -0,0 +1,12 @@ +using EAVFramework.Plugins; + +namespace EAVFW.Extensions.Docs.Extractor +{ + public class PluginRegistrationAttributeData + { + public EntityPluginExecution Execution { get; set; } + public EntityPluginOperation Operation { get; set; } + public EntityPluginMode Mode { get; set; } + public int Order { get; set; } + } +} diff --git a/src/EAVFW.Extensions.Docs.Extractor/Plugin/TypeInformation.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/TypeInformation.cs new file mode 100644 index 0000000..1f6c4fb --- /dev/null +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/TypeInformation.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; +using System.Text.Json.Serialization; + +namespace EAVFW.Extensions.Docs.Extractor +{ + public class TypeInformation + { + [JsonPropertyName("AssemblyQualifiedName")] + public string AssemblyQualifiedName { get; set; } + + [JsonIgnore] + public string Name => AssemblyQualifiedName.Split(',').First().Split('.').Last().Trim(); + + public TypeInformation() + { + } + + public TypeInformation(Type type) + { + AssemblyQualifiedName = type.AssemblyQualifiedName; + } + } +} diff --git a/src/EAVFW.Extensions.Docs.Extracter/Plugin/XmlDocumentationHelper.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/XmlDocumentationHelper.cs similarity index 97% rename from src/EAVFW.Extensions.Docs.Extracter/Plugin/XmlDocumentationHelper.cs rename to src/EAVFW.Extensions.Docs.Extractor/Plugin/XmlDocumentationHelper.cs index 1ae0044..9aefe99 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/Plugin/XmlDocumentationHelper.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/XmlDocumentationHelper.cs @@ -4,7 +4,7 @@ using System.Reflection; using System.Xml; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public static class XmlDocumentationHelper { diff --git a/src/EAVFW.Extensions.Docs.Extracter/Plugin/XmlMemberElement.cs b/src/EAVFW.Extensions.Docs.Extractor/Plugin/XmlMemberElement.cs similarity index 85% rename from src/EAVFW.Extensions.Docs.Extracter/Plugin/XmlMemberElement.cs rename to src/EAVFW.Extensions.Docs.Extractor/Plugin/XmlMemberElement.cs index ce53ecf..03eba34 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/Plugin/XmlMemberElement.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/Plugin/XmlMemberElement.cs @@ -1,6 +1,6 @@ using System.Xml.Serialization; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { [XmlRoot("member")] public class XmlMemberElement diff --git a/src/EAVFW.Extensions.Docs.Extracter/ServiceCollectionExtension.cs b/src/EAVFW.Extensions.Docs.Extractor/ServiceCollectionExtension.cs similarity index 89% rename from src/EAVFW.Extensions.Docs.Extracter/ServiceCollectionExtension.cs rename to src/EAVFW.Extensions.Docs.Extractor/ServiceCollectionExtension.cs index 9701d2c..f690cc4 100644 --- a/src/EAVFW.Extensions.Docs.Extracter/ServiceCollectionExtension.cs +++ b/src/EAVFW.Extensions.Docs.Extractor/ServiceCollectionExtension.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.DependencyInjection; -namespace EAVFW.Extensions.Docs.Extracter +namespace EAVFW.Extensions.Docs.Extractor { public static class ServiceCollectionExtension { diff --git a/src/EAVFW.Extensions.Docs.Generator/EAVFW.Extensions.Docs.Generator.csproj b/src/EAVFW.Extensions.Docs.Generator/EAVFW.Extensions.Docs.Generator.csproj index f4f75e8..07bae44 100644 --- a/src/EAVFW.Extensions.Docs.Generator/EAVFW.Extensions.Docs.Generator.csproj +++ b/src/EAVFW.Extensions.Docs.Generator/EAVFW.Extensions.Docs.Generator.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/EAVFW.Extensions.Docs.Generator/IDocumentationGenerator.cs b/src/EAVFW.Extensions.Docs.Generator/IDocumentationGenerator.cs new file mode 100644 index 0000000..b3daecd --- /dev/null +++ b/src/EAVFW.Extensions.Docs.Generator/IDocumentationGenerator.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using EAVFW.Extensions.Docs.Extractor; +using EAVFW.Extensions.Manifest.SDK; + +namespace EAVFW.Extensions.Docs.Generator +{ + public interface IDocumentationGenerator + { + public void AddPluginSource(IEnumerable pluginDocumentations); + public void AddWizardSource(Dictionary entitiesWithWizards); + public void AddGeneratedManifest(ManifestDefinition generatedManifest); + public Task Write(FileInfo outputLocation, string component); + } +} diff --git a/src/EAVFW.Extensions.Docs.Generator/PluginDocumentationToReadMe.cs b/src/EAVFW.Extensions.Docs.Generator/PluginDocumentationToReadMe.cs deleted file mode 100644 index c524be7..0000000 --- a/src/EAVFW.Extensions.Docs.Generator/PluginDocumentationToReadMe.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using EAVFW.Extensions.Docs.Extracter; -using EAVFW.Extensions.Manifest.SDK; -using JsonSerializer = System.Text.Json.JsonSerializer; - -namespace EAVFW.Extensions.Docs.Generator -{ - public class PluginDocumentationToReadMe : IDisposable - { - private readonly StreamWriter _writer; - private readonly Dictionary _logicalNameLookup = new(); - private readonly TransformXmlTag _transformXmlTag; - - public PluginDocumentationToReadMe( - string path = "/Users/thyge/Documents/Obsidian Vault/Delegate Lava-Stone/Delegate/documentation.md") - { - _transformXmlTag = new TransformXmlTag(); - _writer = new StreamWriter(path); - } - - public async Task WriteTables(FileInfo manifest, string component) - { - var manifestObject = await JsonSerializer.DeserializeAsync(manifest.OpenRead()); - - await _writer.WriteLineAsync("## Tables:\n"); - - var t = new DefaultSchemaNameManager(); - - Debug.Assert(manifestObject != null, nameof(manifestObject) + " != null"); - foreach (var (key, value) in manifestObject.Entities) - { - _logicalNameLookup[t.ToSchemaName(key)] = key; - - await _writer.WriteLineAsync($"### {key}"); - await _writer.WriteLineAsync($"Logical name: `{t.ToSchemaName(key)}`"); - await _writer.WriteLineAsync($"Plural name: {value.PluralName}"); - await _writer.WriteLineAsync($"Description: {value.Description}"); - await _writer.WriteLineAsync("Attributes:"); - } - } - - public async Task WritePlugins(IEnumerable pluginDocumentations, string component) - { - var groups = pluginDocumentations.GroupBy(x => x.Entity!.Name); - await _writer.WriteLineAsync("## Plugins "); - foreach (var group in groups) - { - await _writer.WriteLineAsync($"### {group.FirstOrDefault()?.Entity?.Name}"); - foreach (var pluginDocumentation in group) - { - await _writer.WriteLineAsync($"#### {pluginDocumentation.Name}"); - await _writer.WriteLineAsync( - $"Entity:\t[{pluginDocumentation.Entity?.Name}](#{pluginDocumentation.Entity?.Name})"); - await _writer.WriteLineAsync( - $"Context:\t[{pluginDocumentation.Entity?.Name}](#{pluginDocumentation.Entity?.Name})"); - await _writer.WriteLineAsync("Triggers:\n"); - await _writer.WriteLineAsync("| Operation | Execution | Mode | Order |"); - await _writer.WriteLineAsync("|---|---|---|:-:|"); - foreach (var reg in pluginDocumentation.PluginRegistrations.OrderBy(x => x.Order)) - { - await _writer.WriteLineAsync($"|{reg.Operation}|{reg.Execution}|{reg.Mode}|{reg.Order}|"); - } - - await _writer.WriteLineAsync("\n**Summary:**"); - - await _writer.WriteLineAsync(SanitizeSummary(pluginDocumentation.Summary)); - - await _writer.WriteLineAsync(); - } - } - } - - public async Task WriteWizards() - { - - } - - - private string SanitizeSummary(string summary) - { - if (string.IsNullOrWhiteSpace(summary)) return summary; - - var lines = summary.Split("\n").Select(x => x); - - lines = lines.Where(x => !string.IsNullOrWhiteSpace(x)); - lines = lines.Select(x => x.Trim()); - lines = lines.Select(x => _transformXmlTag.TransformString(x, TransformTag)); - - return string.Join(" ", lines); - } - - /// - /// Function i expression motoren - /// - /// - /// - /// - private string TransformTag(string tag, Dictionary properties) - { - if (tag != "see") - return tag; - - var target = properties["cref"]; - - var key = target.Split(':').Last().Split('.').Last(); - - _logicalNameLookup.TryGetValue(key, out var value); - - return $"[{value ?? key}](#{key})"; - } - - - public async void Dispose() - { - await _writer.FlushAsync(); - await _writer.DisposeAsync(); - GC.SuppressFinalize(this); - } - } -} diff --git a/src/EAVFW.Extensions.Docs.Generator/ReadMeDocumentationGenerator.cs b/src/EAVFW.Extensions.Docs.Generator/ReadMeDocumentationGenerator.cs new file mode 100644 index 0000000..7a92899 --- /dev/null +++ b/src/EAVFW.Extensions.Docs.Generator/ReadMeDocumentationGenerator.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using EAVFW.Extensions.Docs.Extractor; +using EAVFW.Extensions.Manifest.SDK; + +namespace EAVFW.Extensions.Docs.Generator +{ + public class ReadMeDocumentationGenerator : IDocumentationGenerator + { + private readonly TransformXmlTag _transformXmlTag = new(); + private readonly Dictionary _logicalNameLookup = new(); + private Dictionary _wizards; + private IEnumerable _pluginDocumentations; + private ManifestDefinition _manifestObject; + + + public void AddPluginSource(IEnumerable pluginDocumentations) + { + _pluginDocumentations = pluginDocumentations; + } + + + public void AddWizardSource(Dictionary entitiesWithWizards) + { + _wizards = entitiesWithWizards; + } + + public void AddGeneratedManifest(ManifestDefinition generatedManifest) + { + _manifestObject = generatedManifest; + } + + public async Task Write(FileInfo outputLocation, string component) + { + var writer = new StreamWriter(outputLocation.FullName); + + await WriteTables(writer, component); + await WriteWizards(writer); + await WritePlugins(writer); + + await writer.FlushAsync(); + } + + + private async Task WriteTables(TextWriter writer, string component) + { + await writer.WriteLineAsync("## Tables:\n"); + + var t = new DefaultSchemaNameManager(); + + var entitiesToWrite = _manifestObject.Entities; + + if (!string.IsNullOrWhiteSpace(component)) + { + entitiesToWrite = entitiesToWrite.Where(entity => + entity.Value.AdditionalFields.ContainsKey("moduleSource") && + entity.Value.AdditionalFields["moduleSource"].ToString() == component) + .ToDictionary(x => x.Key, x => x.Value); + } + + foreach (var (key, value) in entitiesToWrite) + { + _logicalNameLookup[t.ToSchemaName(key)] = key; + + await writer.WriteLineAsync($"### {key}"); + await writer.WriteLineAsync($"Logical name: `{t.ToSchemaName(key)}`"); + await writer.WriteLineAsync($"Plural name: {value.PluralName}"); + await writer.WriteLineAsync($"Description: {value.Description}"); + await writer.WriteLineAsync("Attributes:"); + } + } + + private async Task WritePlugins(TextWriter writer) + { + var groups = _pluginDocumentations.GroupBy(x => x.Entity!.Name); + await writer.WriteLineAsync("## Plugins: "); + foreach (var group in groups) + { + await writer.WriteLineAsync($"### {group.FirstOrDefault()?.Entity?.Name}"); + foreach (var pluginDocumentation in group) + { + await writer.WriteLineAsync($"#### {pluginDocumentation.Name}"); + await writer.WriteLineAsync( + $"Entity:\t[{pluginDocumentation.Entity?.Name}](#{pluginDocumentation.Entity?.Name})"); + await writer.WriteLineAsync( + $"Context:\t[{pluginDocumentation.Entity?.Name}](#{pluginDocumentation.Entity?.Name})"); + await writer.WriteLineAsync("Triggers:\n"); + await writer.WriteLineAsync("| Operation | Execution | Mode | Order |"); + await writer.WriteLineAsync("|---|---|---|:-:|"); + foreach (var reg in pluginDocumentation.PluginRegistrations.OrderBy(x => x.Order)) + { + await writer.WriteLineAsync($"|{reg.Operation}|{reg.Execution}|{reg.Mode}|{reg.Order}|"); + } + + await writer.WriteLineAsync("\n**Summary:**"); + + await writer.WriteLineAsync(SanitizeSummary(pluginDocumentation.Summary)); + + await writer.WriteLineAsync(); + } + } + } + + private async Task WriteWizards(TextWriter writer) + { + await writer.WriteLineAsync("## Wizards:"); + + foreach (var (key, value) in _wizards.Where(x => x.Value.Wizards.Count > 0)) + { + await writer.WriteLineAsync($"### {key}"); + + foreach (var (wizardKey, wizardDefinition) in value.Wizards) + { + await writer.WriteLineAsync($"#### {wizardKey}"); + } + } + } + + + private string SanitizeSummary(string summary) + { + if (string.IsNullOrWhiteSpace(summary)) return summary; + + var lines = summary.Split("\n").Select(x => x); + + lines = lines.Where(x => !string.IsNullOrWhiteSpace(x)); + lines = lines.Select(x => x.Trim()); + lines = lines.Select(x => _transformXmlTag.TransformString(x, TransformTag)); + + return string.Join(" ", lines); + } + + /// + /// Function i expression motoren + /// + /// + /// + /// + private string TransformTag(string tag, Dictionary properties) + { + if (tag != "see") + return tag; + + var target = properties["cref"]; + + var key = target.Split(':').Last().Split('.').Last(); + + _logicalNameLookup.TryGetValue(key, out var value); + + return $"[{value ?? key}](#{key})"; + } + } +} diff --git a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationGeneratorCommand.cs b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationGeneratorCommand.cs new file mode 100644 index 0000000..f1cc919 --- /dev/null +++ b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationGeneratorCommand.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Parsing; +using System.ComponentModel; +using System.IO; +using System.Text.Json; +using System.Threading.Tasks; +using EAVFW.Extensions.Docs.Extractor; +using EAVFW.Extensions.Docs.Generator; +using EAVFW.Extensions.Manifest.SDK; + +namespace EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands.Documentation +{ + public class DocumentationGeneratorCommand : Command + { + [Alias("-gm")] + [Description("Path to the generate manifest")] + public FileInfo GeneratedManifestPath { get; set; } + + [Alias("-p")] + [Description("Path to plugin source")] + public FileInfo PluginSourcePath { get; set; } + + [Alias("-w")] + [Description("Path to wizard source directory")] + public DirectoryInfo WizardSourcePath { get; set; } + + [Alias("-c")] + [Description("Component")] + public string Component { get; set; } + + [Alias("-o")] [Description("Output")] public FileInfo Output { get; set; } + + public DocumentationGeneratorCommand() : base("generate", "Generate") + { + Handler = COmmandExtensions.Create(this, Array.Empty(), Run); + } + + private async Task Run(ParseResult parseResult, IConsole console) + { + if (IsFilesAndFoldersMissing(out var missing)) + { + console.WriteLine($"The following file(s)/folder(s) are missing: {string.Join(", ", missing)}"); + return 1; + } + + var documentationGenerator = new ReadMeDocumentationGenerator(); + + await using var pluginStream = PluginSourcePath.OpenRead(); + documentationGenerator.AddPluginSource( + await JsonSerializer.DeserializeAsync>(pluginStream)); + + + var wizards = new Dictionary(); + var files = Directory.GetFiles(WizardSourcePath.FullName, "*.json"); + foreach (var file in files) + { + var fileInfo = new FileInfo(file); + await using var openStream = fileInfo.OpenRead(); + var w = await JsonSerializer.DeserializeAsync(openStream); + wizards[Path.GetFileNameWithoutExtension(fileInfo.Name)] = w; + } + + documentationGenerator.AddWizardSource(wizards); + + await using var manifestStream = GeneratedManifestPath.OpenRead(); + documentationGenerator.AddGeneratedManifest( + await JsonSerializer.DeserializeAsync(manifestStream)); + + await documentationGenerator.Write(Output, Component); + + return 0; + } + + private bool IsFilesAndFoldersMissing(out List missing) + { + missing = new List(); + + if (!GeneratedManifestPath.Exists) + missing.Add(GeneratedManifestPath.Name); + + if (!PluginSourcePath.Exists) + missing.Add(PluginSourcePath.Name); + + if (!WizardSourcePath.Exists) + missing.Add(WizardSourcePath.Name); + + return missing.Count > 0; + } + } +} diff --git a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceCommand.cs b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceCommand.cs new file mode 100644 index 0000000..a24158f --- /dev/null +++ b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceCommand.cs @@ -0,0 +1,24 @@ +using System; +using System.CommandLine; +using System.CommandLine.Parsing; +using System.Threading.Tasks; +using EAVFW.Extensions.Docs.Extractor; + +namespace EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands.Documentation +{ + public class DocumentationSourceCommand : Command + { + public DocumentationSourceCommand(IDocumentLogic documentLogic) : base("docs", "Work with documentation") + { + Handler = COmmandExtensions.Create(this, Array.Empty(), Run); + + AddCommand(new DocumentationSourceExtractorCommand(documentLogic)); + AddCommand(new DocumentationGeneratorCommand()); + } + + private Task Run(ParseResult parseResult, IConsole console) + { + return Task.FromResult(0); + } + } +} diff --git a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/DocumentCommand.cs b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceExtractorCommand.cs similarity index 75% rename from src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/DocumentCommand.cs rename to src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceExtractorCommand.cs index e966be2..5d01223 100644 --- a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/DocumentCommand.cs +++ b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Commands/Documentation/DocumentationSourceExtractorCommand.cs @@ -7,14 +7,19 @@ using System.Linq; using System.Text.Json; using System.Threading.Tasks; -using EAVFW.Extensions.Docs.Extracter; -using EAVFW.Extensions.Docs.Generator; +using EAVFW.Extensions.Docs.Extractor; -namespace EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands +namespace EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands.Documentation { - public class DocumentCommand : Command + /* + * There are many parameters to the command and generating source for both plugin and wizard requires the tool to be + * executed twice. Alternatively, the "configuration" could be done using a configuration, which would provide all + * necessary parameters. Both it would be more rigid and could not easily be changed in a pipeline or other. + */ + + public class DocumentationSourceExtractorCommand : Command { - private readonly IDocumentLogic documentLogic; + private readonly IDocumentLogic _documentLogic; [Alias("-a")] [Alias("--assembly")] @@ -29,15 +34,15 @@ public class DocumentCommand : Command [Alias("-p")] [Alias("--probing-path")] [Description("Path to probe for dependent assemblies")] - public DirectoryInfo RootPathOption { get; set; } + public DirectoryInfo ProbePathOption { get; set; } [Alias("-c")] [Alias("--configuration")] [Description("Configuration for the built assembly")] public string ConfigurationOption { get; set; } - + [Alias("--component")] - [Description("Component to generate documentation. E.g., `mainfest.component.json`")] + [Description("Component to generate documentation. E.g., `manifest.component.json`")] public string ComponentOption { get; set; } [Alias("-f")] @@ -61,9 +66,9 @@ public enum Targets Wizards } - public DocumentCommand(IDocumentLogic documentLogic) : base("docs", "Generate documentation") + public DocumentationSourceExtractorCommand(IDocumentLogic documentLogic) : base("extract", "Extract documentation source") { - this.documentLogic = documentLogic ?? throw new ArgumentNullException(nameof(documentLogic)); + _documentLogic = documentLogic ?? throw new ArgumentNullException(nameof(documentLogic)); Handler = COmmandExtensions.Create(this, Array.Empty(), Run); } @@ -75,7 +80,7 @@ private async Task Run(ParseResult parseResult, IConsole console) return 126; } - if (!RootPathOption.Exists) + if (!ProbePathOption.Exists) { Console.WriteLine("Probing path does not exists"); return 1; @@ -90,15 +95,15 @@ private async Task Run(ParseResult parseResult, IConsole console) switch (Target) { case Targets.Plugins: - return await HandlePlugins(); + return await GeneratePluginSource(); case Targets.Wizards: - return await HandleWizards(); + return await GenerateWizardSource(); default: throw new ArgumentOutOfRangeException(); } } - private async Task HandleWizards() + private async Task GenerateWizardSource() { if (!ManifestPathOption?.Exists ?? true) { @@ -106,9 +111,9 @@ private async Task HandleWizards() return 1; } - var entityDefinitions = documentLogic.ExtractWizardDocumentation( + var entityDefinitions = _documentLogic.ExtractWizardDocumentation( ManifestPathOption, - new PluginInfo(RootPathOption, + new PluginInfo(ProbePathOption, AssemblyPathOption, ConfigurationOption, FrameworkOption)); @@ -133,16 +138,15 @@ private async Task HandleWizards() return 0; } - private async Task HandlePlugins() + private async Task GeneratePluginSource() { - var plugins = documentLogic - .ExtractPluginDocumentation(new PluginInfo(RootPathOption, AssemblyPathOption, ConfigurationOption, + var plugins = _documentLogic + .ExtractPluginDocumentation(new PluginInfo(ProbePathOption, AssemblyPathOption, ConfigurationOption, FrameworkOption)) .ToArray(); - + var jsonString = JsonSerializer.Serialize(plugins, new JsonSerializerOptions { - Converters = { new PluginRegistrationAttributeConverter() }, WriteIndented = true }); @@ -169,8 +173,8 @@ private bool IsMissingOptions(out List missing) if (AssemblyPathOption == null) missing.Add(nameof(AssemblyPathOption)); - if (RootPathOption == null) - missing.Add(nameof(RootPathOption)); + if (ProbePathOption == null) + missing.Add(nameof(ProbePathOption)); if (string.IsNullOrWhiteSpace(ConfigurationOption)) missing.Add(nameof(ConfigurationOption)); diff --git a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/EAVFW.Extensions.Manifest.ManifestEnricherTool.csproj b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/EAVFW.Extensions.Manifest.ManifestEnricherTool.csproj index cf8e85a..138c728 100644 --- a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/EAVFW.Extensions.Manifest.ManifestEnricherTool.csproj +++ b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/EAVFW.Extensions.Manifest.ManifestEnricherTool.csproj @@ -54,7 +54,7 @@ - + diff --git a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Program.cs b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Program.cs index 9535825..0b0153f 100644 --- a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Program.cs +++ b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Program.cs @@ -1,6 +1,4 @@  - - // See https://aka.ms/new-console-template for more information using EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands; using EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands.GPT; @@ -9,7 +7,8 @@ using Microsoft.Extensions.Logging; using System.CommandLine; using System.Threading.Tasks; -using EAVFW.Extensions.Docs.Extracter; +using EAVFW.Extensions.Docs.Extractor; +using EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands.Documentation; using EAVFW.Extensions.Manifest.ManifestEnricherTool.Commands.Gzip; namespace EAVFW.Extensions.Manifest.ManifestEnricherTool @@ -36,7 +35,7 @@ static IServiceCollection ConfigureServices(IServiceCollection serviceCollection serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddGPT(); serviceCollection.AddTransient(); diff --git a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Properties/launchSettings.json b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Properties/launchSettings.json index fcf09a0..48460f1 100644 --- a/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Properties/launchSettings.json +++ b/src/EAVFW.Extensions.Manifest.ManifestEnricherTool/Properties/launchSettings.json @@ -4,8 +4,9 @@ "commandName": "Project", "workingDirectory": "/Users/thyge/dev/playground", // "workingDirectory": "/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.Models", - "commandLineArgs": "docs -c Release -t wizards -f net6.0 -a \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.BusinessLogic/bin/Release/net6.0/Hafnia.BusinessLogic.dll\" -p \"/Users/thyge/dev/hafnia/LetterofIndemnity\" -m \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.Models/manifest.loi.json\"" -// "commandLineArgs": "docs -c Release -t plugins -f net6.0 -a \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.BusinessLogic/bin/Release/net6.0/Hafnia.BusinessLogic.dll\" -p \"/Users/thyge/dev/hafnia/LetterofIndemnity\" -m \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.Models/manifest.loi.json\"" +// "commandLineArgs": "docs extract -c Release -t wizards -f net6.0 -a \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.BusinessLogic/bin/Release/net6.0/Hafnia.BusinessLogic.dll\" -p \"/Users/thyge/dev/hafnia/LetterofIndemnity\" -m \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.Models/manifest.loi.json\"" +// "commandLineArgs": "docs extract -c Release -t plugins -f net6.0 -a \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.BusinessLogic/bin/Release/net6.0/Hafnia.BusinessLogic.dll\" -p \"/Users/thyge/dev/hafnia/LetterofIndemnity\" -m \"/Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.Models/manifest.loi.json\"" + "commandLineArgs": "docs generate -c manifest.loi.json -p /Users/thyge/dev/playground/plugins.json -w /Users/thyge/dev/playground/wizards -o \"/Users/thyge/Documents/Obsidian Vault/Delegate Lava-Stone/Delegate/documentation.md\" -gm /Users/thyge/dev/hafnia/LetterofIndemnity/src/Hafnia.Models/obj/manifest.g.json" // "commandLineArgs": "binary --unzip 0x1F8B08000000000000139C51414EC33010FC8BAFD4C8719C36C9AD824BA50252E90D71D8D8EBC852EA147B73A8A2FE1D3B05CE153E8DAC99D99DD999812637FAC8DA993D0504C2FDDBEE19080EF83561A4178C117ADC2EAC4C72FE3C5106C3E8C28DC35A06CA182937C0D142C795EE2A5EA2042E6AD369B0AAAA9A82AD5840EDCE0E3DA5791FACA884EAACB45CDB3572D5E8861B5B36BFA235405DB3CFEB8A45029A9284BD4F5AA34193ACBAD15CEE1F6CC10D680E0831A7F0D3305C932F05D7F71896F0C71BCE90DC0993B514B2E485E0853C8A4DAB8A56C9C7B2484B370F42B442FC2D31B394C8D1E51516DD1E89308CD67983279FFE7FAA8CB702C66076E6FECD4DBA451EF1AFEAF2FB060000FFFF" // "commandLineArgs": "binary --unzip 0x1F8B08000000000000139C51414EC33010FC8BAFD4C8719C36C9AD824BA50252E90D71D8D8EBC852EA147B73A8A2FE1D3B05CE153E8DAC99D99DD999812637FAC8DA993D0504C2FDDBEE19080EF83561A4178C117ADC2EAC4C72FE3C5106C3E8C28DC35A06CA182937C0D142C795EE2A5EA2042E6AD369B0AAAA9A82AD5840EDCE0E3DA5791FACA884EAACB45CDB3572D5E8861B5B36BFA235405DB3CFEB8A45029A9284BD4F5AA34193ACBAD15CEE1F6CC10D680E0831A7F0D3305C932F05D7F71896F0C71BCE90DC0993B514B2E485E0853C8A4DAB8A56C9C7B2484B370F42B442FC2D31B394C8D1E51516DD1E89308CD67983279FFE7FAA8CB702C66076E6FECD4DBA451EF1AFEAF2FB060000FFFF" // "commandLineArgs": "binary --unzip --pretty-print 0x1F8B08000000000000139C51414EC33010FC8BAFD4C8719C36C9AD824BA50252E90D71D8D8EBC852EA147B73A8A2FE1D3B05CE153E8DAC99D99DD999812637FAC8DA993D0504C2FDDBEE19080EF83561A4178C117ADC2EAC4C72FE3C5106C3E8C28DC35A06CA182937C0D142C795EE2A5EA2042E6AD369B0AAAA9A82AD5840EDCE0E3DA5791FACA884EAACB45CDB3572D5E8861B5B36BFA235405DB3CFEB8A45029A9284BD4F5AA34193ACBAD15CEE1F6CC10D680E0831A7F0D3305C932F05D7F71896F0C71BCE90DC0993B514B2E485E0853C8A4DAB8A56C9C7B2484B370F42B442FC2D31B394C8D1E51516DD1E89308CD67983279FFE7FAA8CB702C66076E6FECD4DBA451EF1AFEAF2FB060000FFFF"