diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 00000000..745397a7 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "docfx": { + "version": "2.73.1", + "commands": [ + "docfx" + ] + } + } +} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 169b4130..034d35fa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,14 @@ jobs: with: submodules: recursive + - name: Setup .NET Core SDK + uses: actions/setup-dotnet@v3.2.0 + with: + dotnet-version: 7.x + + - name: Custom Build Steps + run: .\build.ps1 + - name: Setup MSBuild uses: microsoft/setup-msbuild@v1 @@ -22,12 +30,10 @@ jobs: run: msbuild -t:restore src\harp\Bonsai.Harp.sln - name: Setup DocFX - uses: crazy-max/ghaction-chocolatey@v1 - with: - args: install docfx + run: dotnet tool restore - name: Build Documentation - run: docfx docfx.json + run: dotnet docfx docfx.json - name: Checkout gh-pages uses: actions/checkout@v2 diff --git a/apispec/.gitignore b/apispec/.gitignore new file mode 100644 index 00000000..d0fa4ddc --- /dev/null +++ b/apispec/.gitignore @@ -0,0 +1,4 @@ +############### +# Auto file # +############### +*.md diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 00000000..0c2c1722 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,6 @@ +$files = Get-ChildItem .\src\device.*\device.yml +foreach ($file in $files) +{ + Write-Output "Generating schema tables for $file..." + dotnet run --project .\src\harp.schemaprocessor $file .\apispec +} \ No newline at end of file diff --git a/docfx.json b/docfx.json index e63c95ff..71c96ecb 100644 --- a/docfx.json +++ b/docfx.json @@ -44,7 +44,8 @@ "files": [ "logo.svg", "favicon.ico", - "editor/index.html", + "src/device.*/Assets/*.png", + "src/device.*/Assets/*.jpg", "images/**", "workflows/**" ] @@ -53,7 +54,8 @@ "overwrite": [ { "files": [ - "apidoc/**.md" + "apidoc/**.md", + "apispec/**.md" ], "exclude": [ "obj/**", @@ -88,7 +90,7 @@ "keepFileLink": false, "cleanupCacheHistory": false, "disableGitFeatures": false, - "xrefService": [ "https://xref.docs.microsoft.com/query?uid={uid}" ], + "xrefService": [ "https://learn.microsoft.com/api/xref/query?uid={uid}" ], "xref": [ "https://bonsai-rx.org/docs/xrefmap.yml", "https://horizongir.github.io/opencv.net/xrefmap.yml", diff --git a/src/harp.schemaprocessor/ExpandoHelper.cs b/src/harp.schemaprocessor/ExpandoHelper.cs new file mode 100644 index 00000000..c8390d47 --- /dev/null +++ b/src/harp.schemaprocessor/ExpandoHelper.cs @@ -0,0 +1,19 @@ +using System.Dynamic; + +static class ExpandoHelper +{ + public static ExpandoObject FromDictionary(Dictionary members, params string[] optionalMembers) + { + var result = new ExpandoObject(); + foreach (var kvp in members) + { + result.TryAdd((string)kvp.Key, kvp.Value); + } + + foreach (var member in optionalMembers) + { + result.TryAdd(member, null); + } + return result; + } +} \ No newline at end of file diff --git a/src/harp.schemaprocessor/Program.cs b/src/harp.schemaprocessor/Program.cs new file mode 100644 index 00000000..839afa74 --- /dev/null +++ b/src/harp.schemaprocessor/Program.cs @@ -0,0 +1,93 @@ +using System.Dynamic; +using System.Text; +using YamlDotNet.Core; +using YamlDotNet.Serialization; + +var fileName = args[0]; +var yaml = File.ReadAllText(fileName); +var deserializer = new Deserializer(); +var parser = new MergingParser(new Parser(new StringReader(yaml))); +dynamic deviceModel = deserializer.Deserialize(parser); + +var builder = new StringBuilder(); +builder.AppendLine($@"--- +uid: Harp.{deviceModel.device}.Device +--- + + + + + + + + + + +
{deviceModel.device}
whoAmI{deviceModel.whoAmI}
firmwareVersion{deviceModel.firmwareVersion}
hardwareTargets{deviceModel.hardwareTargets}
+ +### Registers + +| name | address | type | length | access | description | range | interfaceType | +|-|-|-|-|-|-|-|-|"); +foreach (var item in deviceModel.registers) +{ + if (item.Value.TryGetValue("visibility", out object visibility) && + (string)visibility == "private") + { + continue; + } + + var name = item.Key; + var register = ExpandoHelper.FromDictionary(item.Value, + "length", + "description", + "minValue", + "maxValue", + "defaultValue", + "payloadSpec", + "maskType", + "interfaceType"); + var interfaceType = register.maskType + ?? register.interfaceType + ?? (register.payloadSpec != null ? $"{name}Payload" : null); + var interfaceTypeRef = (string)interfaceType == "EnableFlag" + ? "Bonsai.Harp.EnableFlag" + : $"Harp.{deviceModel.device}.{interfaceType}"; + + var access = register.access; + if (access is List accessList) + { + access = string.Join(", ", accessList); + } + + var range = ""; + if (register.minValue != null || register.maxValue != null) + { + range = $"[{register.minValue}:{register.maxValue}]"; + } + if (register.defaultValue != null) range = $"{register.defaultValue} {range}"; + + builder.AppendLine( + $"| [{name}](xref:Harp.{deviceModel.device}.{name}) " + + $"| {register.address} " + + $"| {register.type} " + + $"| {register.length} " + + $"| {access} " + + $"| {register.description} " + + $"| {range} " + + (interfaceType != null ? $"| [{interfaceType}](xref:{interfaceTypeRef}) |" : "| |")); +} + +var output = builder.ToString(); +if (args.Length > 1) +{ + File.WriteAllText(Path.Combine(args[1], $"Harp_{deviceModel.device}_Device.md"), output); + File.WriteAllText(Path.Combine(args[1], $"Harp_{deviceModel.device}.md"), $@"--- +uid: Harp.{deviceModel.device} +--- + +[!include[README](~/src/device.{deviceModel.device.ToLowerInvariant()}/README.md)] + +[!include[RegisterTables](./Harp_{deviceModel.device}_Device.md)]"); +} +else Console.WriteLine(output); diff --git a/src/harp.schemaprocessor/harp.schemaprocessor.csproj b/src/harp.schemaprocessor/harp.schemaprocessor.csproj new file mode 100644 index 00000000..5f77ae18 --- /dev/null +++ b/src/harp.schemaprocessor/harp.schemaprocessor.csproj @@ -0,0 +1,13 @@ + + + + Exe + net7.0 + enable + + + + + + + diff --git a/src/harp.schemaprocessor/harp.schemaprocessor.sln b/src/harp.schemaprocessor/harp.schemaprocessor.sln new file mode 100644 index 00000000..c0486b87 --- /dev/null +++ b/src/harp.schemaprocessor/harp.schemaprocessor.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "harp.schemaprocessor", "harp.schemaprocessor.csproj", "{EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1C2B33A3-49ED-4B82-AF1B-E2F3FB9E4ACF} + EndGlobalSection +EndGlobal