From 1147500597d5b5d4db8ec25a9973d6260772961f Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Tue, 5 May 2026 15:33:09 -0500 Subject: [PATCH 1/8] Updates for FHIR Foundation --- .github/workflows/docs.yaml | 2 +- CHANGELOG.md | 5 +- CLAUDE.md | 0 CODE_OF_CONDUCT.md | 10 +-- CONTRIBUTING.MD | 36 +++++++++ GeoPol.xml | 26 ------- LICENSE | 4 +- README.md | 150 ++++-------------------------------- SECURITY.md | 42 ++-------- 9 files changed, 65 insertions(+), 210 deletions(-) delete mode 100644 CLAUDE.md create mode 100644 CONTRIBUTING.MD delete mode 100644 GeoPol.xml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index d301ff344..142ede0d8 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -3,7 +3,7 @@ name: Docs on: push: branches: - - main + - main-disabled paths: - src/** - docfx/** diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d656da35..48c0a13b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,7 @@ -### 1.0.1 +### CURRENT -* DSTU2 - * Fixed incorrect mapping of QuestionnaireResponseGroup to QuestionnaireGroup +* Migrated from Microsoft/fhir-codegen to FHIR/fhir-codegen. --- diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c72a5749c..48355ff02 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,9 +1,3 @@ -# Microsoft Open Source Code of Conduct +# HL7 Code of Conduct -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). - -Resources: - -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns +To ensure a welcoming environment, we follow the [HL7 Code of Conduct](https://www.hl7.org/legal/code-of-conduct.cfm). diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD new file mode 100644 index 000000000..4dd8e8ae7 --- /dev/null +++ b/CONTRIBUTING.MD @@ -0,0 +1,36 @@ +# Contributing + +This document describes guidelines for contributing to this repo. + +To ensure a welcoming environment, we follow the [HL7 Code of Conduct](https://www.hl7.org/legal/code-of-conduct.cfm) and expect contributors to do the same. + +Before making a contribution, please familiarize yourself with this document, as well as our [LICENSE](LICENSE) and [README](README.md). + + +## Submitting Pull Requests + +- **DO** submit all changes via pull requests (PRs). They will be reviewed and potentially be merged by maintainers after a peer review that includes at least one of the team members. +- **DO** give PRs short but descriptive names. +- **DO** write a useful but brief description of what the PR is for. +- **DO** refer to any relevant issues and use [keywords](https://help.github.com/articles/closing-issues-using-keywords/) that automatically close issues when the PR is merged. +- **DO** ensure each commit successfully builds. The entire PR must pass all checks before it will be merged. +- **DO** address PR feedback in additional commits instead of amending. +- **DO** assume that [Squash and Merge](https://blog.github.com/2016-04-01-squash-your-commits/) will be used to merge the commits unless specifically requested otherwise. +- **DO NOT** submit "work in progress" PRs. A PR should only be submitted when it is considered ready for review. +- **DO NOT** mix independent and unrelated changes in one PR. + +## Coding Style + +The coding style is enforced through [StyleCop.Analyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers), [.editorconfig](.editorconfig), and [stylecop.json](stylecop.json). Contributors should ensure these guidelines are followed when making submissions. + +- **DO** address the StyleCop.Analyzers errors. +- **DO** follow the [.editorconfig](.editorconfig) and [stylecop.json](stylecop.json) settings. + +## Creating Issues + +- **DO** use a descriptive title that identifies the issue or the requested feature. +- **DO** write a detailed description of the issue or the requested feature. +- **DO** provide details for issues you create: + - Describe the expected and actual behavior. + - Provide any relevant exception message or OperationOutcome. +- **DO** subscribe to notifications for created issues in case there are any follow-up questions. \ No newline at end of file diff --git a/GeoPol.xml b/GeoPol.xml deleted file mode 100644 index d47dd16cc..000000000 --- a/GeoPol.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - -]> - - - -&GitRepoName; - - - - . - - - - - .gitignore - GeoPol.xml - fhirVersions - generated - src\Microsoft.Health.Fhir.SpecManager\fhir - - diff --git a/LICENSE b/LICENSE index 3d8b93bc7..b4924198b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License - Copyright (c) Microsoft Corporation. + Copyright (c) Gino Canessa. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE + SOFTWARE \ No newline at end of file diff --git a/README.md b/README.md index 582fa4669..37735bfac 100644 --- a/README.md +++ b/README.md @@ -2,147 +2,31 @@ A .Net application, library, and related utilities to work with FHIR specifications. -# Documentation - -Detailed documentation can be found on the [documentation site](https://microsoft.github.io/fhir-codegen/). - -# Projects in this Repository - -Project source code is hosted on [GitHub](https://github.com/microsoft/fhir-codegen). - -All projects are currently built on .Net 8.0 and tested on multiple platforms, though Windows is the primary development platform. The -.Net 8.0 SDK and runtimes are available for free at: https://dotnet.microsoft.com/en-us/download . - -## Fhir.CodeGen.Common - -This project is a class library that contains the common (normalized) models used in these projects. The project is lightweight with -minimal dependencies and used to ensure that additional projects and external development have access to models. - -Detailed information about the models can be found in the [Common Models Documentation](https://microsoft.github.io/fhir-codegen/api/Fhir.CodeGen.Common.Models.html). - -## Fhir.CodeGen.CrossVersionLoader - -This project is a class library that provides *basic* support for loading specifications from multiple versions of FHIR. The library is scoped -to the needs of this project and is not intended to be a full FHIR library. It is incomplete in support, though we do plan on expanding in the -future. - -## Fhir.CodeGen.MappingLanguage - -This project is a class library that provides support for working with the FHIR Mapping Language (FML). Today, content is focused on parsing FML -and providing useful abstractions for consumption. - -## Fhir.CodeGen.Lib - -This project is a class library that contains the logic used to process FHIR specifications. For example, this project contains the code to: -* download packages, -* resolve canonical URLs, -* normalize different versions of FHIR, -* read metadata (CapabilityStatement or Conformance) from FHIR servers, -* compare packages or artifacts, -* convert normalized models into language-specific models, -* etc. - -More information about this project can be found in the [API Documentation](https://microsoft.github.io/fhir-codegen/api/index.html). +## FHIR Foundation Project Statement +* Maintainers: Gino Canessa +* Issues / Discussion: Any issues should be submitted on [GitHub](https://github.com/FHIR/fhir-codegen/issues). Discussion can be performed here on GitHub, or on the [dotnet stream on chat.fhir.org](https://chat.fhir.org/#narrow/stream/179171-dotnet). +* License: This software is offered under the [MIT License](LICENSE). +* Contribution Policy: See [Contributing](#contributing). +* Security Information: See [Security](#security). -### Export Languages -The projects in this repository can be used to translate FHIR packages (core or IG) into other forms - e.g., programming language definitions -(C#, TypeScript, Ruby, etc.), other language definitions (FHIR Shorthand, OpenAPI, etc.), or data formats (Info text, etc.). +## Contributing -More information about current languages can be found on the [Export Languages Page](https://microsoft.github.io/fhir-codegen/articles/languages.html). -Information about adding new languages can be found on the [Extending Page](https://microsoft.github.io/fhir-codegen/articles/extending.html). +There are many ways to contribute: +* [Submit bugs](https://github.com/FHIR/fhir-codegen/issues) and help us verify fixes as they are checked in. +* Review the [source code changes](https://github.com/FHIR/fhir-codegen/pulls). +* Engage with users and developers on the [dotnet stream on FHIR Zulip](https://chat.fhir.org/#narrow/stream/179171-dotnet) +* Contribute features or bug fixes - see [Contributing](CONTRIBUTING.MD) for details. +To ensure a welcoming environment, we follow the [HL7 Code of Conduct](https://www.hl7.org/legal/code-of-conduct.cfm) and expect contributors to do the same. -## fhir-codegen - -This project is a command-line application that can be used to perform export operations (e.g., for CI Pipelines). Generally, it can: -* manage the FHIR Package Cache (`~/.fhir`) - add/update packages -* perform exports / transforms of FHIR packages -* compare specification packages - -To run this project from a command line: -* `dotnet run --project src/fhir-codegen-cli/fhir-codegen-cli.csproj -- [command] [options]` -or you can build a release version to run: -* `dotnet build -c Release` -* `./src/fhir-codegen/bin/Release/net8.0/fhir-codegen-cli.exe` - -``` -Description: - A utility for processing FHIR packages into other formats/languages. - -Usage: - fhir-codegen [command] [options] - -Options: - --fhir-cache Location of the FHIR cache (none specified defaults to user .fhir directory). [] - --use-official-registries Use official FHIR registries to resolve packages. [] - --additional-fhir-registry-urls Additional FHIR registry URLs to use. [] - --additional-npm-registry-urls Additional NPM registry URLs to use. [] - --output-dir, --output-directory, --output-path File or directory to write output. [] - --output-filename Filename to write output. [] - -p, --load-package, --package Package to load, either as directive ([name]#[version/literal]) or URL. [] - --auto-load-expansions When loading core packages, load the expansions packages automatically. [] - --resolve-dependencies Resolve package dependencies. [] - --load-structures Types of FHIR structures to load. [] - opt: CapabilityStatement - opt: CodeSystem - opt: Compartment - opt: ComplexType - opt: ConceptMap - opt: Extension - opt: ImplementationGuide - opt: Interface - opt: LogicalModel - opt: NamingSystem - opt: Operation - opt: PrimitiveType - opt: Profile - opt: Resource - opt: SearchParameter - opt: StructureMap - opt: Unknown - opt: ValueSet - - --export-keys Keys of FHIR structures to export (e.g., Patient), empty means all. [] - --load-canonical-examples Load canonical examples from packages. [] - --offline Offline mode (will not download missing packages). [] - --fhir-version FHIR version to use. [] - --version Show version information - -?, -h, --help Show help and usage information - -Commands: - generate Generate output from a FHIR package and exit. - compare Compare two sets of packages. -``` - -More information about this project can be found in the [Command Line Documentation](https://microsoft.github.io/fhir-codegen/articles/cli.html). - -### Examples - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a TypeScript file in the current directory - * `fhir-codegen generate TypeScript -p hl7.fhir.r4.core --output-path ./R4.ts` - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a TypeScript file in the current directory, restricted to just the Resources: Patient, Encounter, and Observation - * `fhir-codegen generate TypeScript -p hl7.fhir.r4.core --output-path ./R4.ts --export-keys Patient|Encounter|Observation` - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, reach out the Firely Test Server, and build a set of OpenAPI definitions - * `generate OpenApi --fhir-server-url http://server.fire.ly/r4 -p hl7.fhir.r4.core#4.0.1 --output-path ./FS-OpenApi-R4 --include-experimental --schema-level names --metadata true --multi-file true --single-responses false --resolve-server-canonicals false --resolve-external-canonicals false --basic-scopes-only true` - - -# Contributing +# Documentation -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. +Apologies - the documentation for this project is currently quite stale and was causing more issues than solving. -When you submit a pull request, a CLA bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. +Documentation updates are in progress, and will be updated Soon(TM). -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. # Trademarks -FHIR® is the registered trademark of HL7 and is used under Community Project guidelines. This project is not affiliated with, or approved or sponsored by, HL7. +FHIR® is the registered trademark of HL7 and is used with the permission of HL7. diff --git a/SECURITY.md b/SECURITY.md index 7ab49eb82..94c92a772 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,41 +1,9 @@ - +# Reporting Security Issues -## Security +While this repository contains tooling for developers and testing, we take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). +To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/ginocanessa/fhir-codegen/security/advisories/new) tab. -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. +The team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). - -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - +Report security bugs in third-party modules to the person or team maintaining the module. From 628f5082cacd596f03521372fb62231a8d576c68 Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Tue, 5 May 2026 15:36:58 -0500 Subject: [PATCH 2/8] Skill update --- .github/skills/dev-do/SKILL.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/skills/dev-do/SKILL.md b/.github/skills/dev-do/SKILL.md index e14e307f2..2bb4559c6 100644 --- a/.github/skills/dev-do/SKILL.md +++ b/.github/skills/dev-do/SKILL.md @@ -1,6 +1,6 @@ --- name: dev-do -description: "Executes an implementation plan produced by `dev-plan` in the role of a staff-level Engineer. USE FOR: actually doing the work — writing/modifying code, running builds and tests, committing locally as phases complete, and keeping `plan.md` updated with current status. Accepts either a full path to the plan file or a short slot number that expands to `scratch/[MMDD]-[##]/plan.md`. Optional `max_subagents` (default 3) caps parallel sub-agent fan-out. Optional `checkpoint_every` (default 0 = never) yields back to the user after every N completed phases; the default is to run the entire plan in a single invocation without re-prompting. May commit locally with concise conventional-commit messages, but **must not push and must not open a PR**. The `plan.md` file may be edited but never deleted." +description: "Executes an implementation plan produced by `dev-plan` in the role of a staff-level Engineer. USE FOR: actually doing the work — writing/modifying code, running builds and tests, committing locally as phases complete, and keeping `plan.md` updated with current status. Accepts either a full path to the plan file or a short slot number that expands to `scratch/[MMDD]-[##]/plan.md`. Optional `max_subagents` (default 3) caps parallel sub-agent fan-out. Optional `checkpoint_every` (default 0 = never) yields back to the user after every N completed phases; the default is to run the entire plan in a single invocation without re-prompting. May commit locally with concise conventional-commit messages, but **must not push and must not open a PR**. The `plan.md` file may be edited but never deleted nor committed." --- # Dev Do Skill @@ -65,9 +65,9 @@ invocation. The default contract is: - Run **all** remaining `Pending` phases back-to-back. - A successful verification + commit is **not** a yield point. - Updating `plan.md` and committing is a normal step inside the loop; - immediately mark the next `Pending` phase `In-progress` and keep - going. + Updating `plan.md` and committing code is a normal step inside + the loop; immediately mark the next `Pending` phase `In-progress` + and keep going. - Yield to the user **only** for the reasons enumerated in "Yield Conditions" below. @@ -144,14 +144,11 @@ sibling source request (`featurerequest.md` / `bugreport.md`). `Complete` and append a `## Progress Log` entry (with the pending commit SHA placeholder; you'll fill it in after the commit, or amend immediately after). - 5. Stage **both** the code changes and the `plan.md` update and - commit them together as a single phase commit with a concise + 5. Stage the code changes (not the `plan.md`) update and + commit as a single phase commit with a concise conventional-commit message (`(): `, e.g., `fix(github-source): handle empty FSH alias map`). Include - the standard co-author trailer required by this repo. Folding - the plan update into the phase commit is the default; a - separate `chore(plan):` commit is allowed only when the code - and plan changes are genuinely independent. + the standard co-author trailer required by this repo. 6. **Continue immediately to the next `Pending` phase. Do not yield.** Successful verification + commit is *not* a stopping point. The only legal reasons to break out of this loop are the From 6c548b654a9b179fecfeccd8d4231228890a09ba Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Wed, 6 May 2026 10:36:34 -0500 Subject: [PATCH 3/8] docs: stand up top-level docs/ authoring root Migrate docs/*.md, specs/*.md, and src/Fhir.CodeGen.Packages/docs/ into a single top-level docs/ tree (articles/ + specs/) with new index.md, README.md, and toc.yml. The new tree is additive: docfx/articles/ remains intact so the existing (broken-but-buildable) DocFX inputs are still parseable until Phase 2 cuts over. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/README.md | 59 ++++++++ docs/{xver.md => articles/cross-version.md} | 0 docs/articles/extending.md | 116 +++++++++++++++ docs/articles/intro.md | 90 +++++++++++ docs/articles/languages.md | 140 ++++++++++++++++++ .../articles/packages-resolution.md | 0 docs/{ => articles}/sanitization.md | 0 docs/articles/toc.yml | 14 ++ docs/index.md | 66 +++++++++ .../specs/fhirdb-comparer-compare.md | 0 .../specs/fhirdb-comparer-do-structure.md | 0 .../specs/fhirdb-comparer-do-valueset.md | 0 docs/specs/toc.yml | 8 + .../specs/xver-processor-write-fhir.md | 0 docs/toc.yml | 7 + fhir-codegen.sln | 5 +- 16 files changed, 503 insertions(+), 2 deletions(-) create mode 100644 docs/README.md rename docs/{xver.md => articles/cross-version.md} (100%) create mode 100644 docs/articles/extending.md create mode 100644 docs/articles/intro.md create mode 100644 docs/articles/languages.md rename src/Fhir.CodeGen.Packages/docs/resolution.md => docs/articles/packages-resolution.md (100%) rename docs/{ => articles}/sanitization.md (100%) create mode 100644 docs/articles/toc.yml create mode 100644 docs/index.md rename specs/FhirDbComparer.Compare-specification.md => docs/specs/fhirdb-comparer-compare.md (100%) rename specs/FhirDbComparer.doStructureComparisons-specification.md => docs/specs/fhirdb-comparer-do-structure.md (100%) rename specs/FhirDbComparer-doValueSetComparisons-specification.md => docs/specs/fhirdb-comparer-do-valueset.md (100%) create mode 100644 docs/specs/toc.yml rename specs/XVerProcessor_WriteFhirFromDatabase-specification.md => docs/specs/xver-processor-write-fhir.md (100%) create mode 100644 docs/toc.yml diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..2d0d0eebc --- /dev/null +++ b/docs/README.md @@ -0,0 +1,59 @@ +# `docs/` — fhir-codegen documentation source + +This directory is the **single source of truth** for fhir-codegen's +authored documentation. The published site lives at +. + +## What lives where + +| Path | Purpose | +|---|---| +| `docs/index.md` | Site landing page. | +| `docs/toc.yml` | Top-level table of contents. | +| `docs/articles/` | Long-form, hand-authored articles. | +| `docs/specs/` | Internal design / process specs. | +| `docfx/` | DocFX **build configuration only** (no narrative content here). | +| `docfx/cli-generated/cli.md` | Built by `fhir-codegen docs cli`; not committed. | +| `docfx/api/` | Built by DocFX `metadata`; not committed. | +| `docfx/_site/` | Built site output; not committed. | + +## Authoring policy + +- Top-level `docs/` is the single source of truth. Per-project `docs/` + folders (e.g. the old `src/Fhir.CodeGen.Packages/docs/`) are retired. + If a project needs documentation, add it under `docs/articles/`. +- `docfx/` holds build configuration (`docfx.json`, `.gitignore`) and + build outputs only — no narrative `.md` files. +- The CLI usage page (`articles/cli.html` on the site) is generated at + build time from the live System.CommandLine surface by the + `fhir-codegen docs cli` subcommand and written to + `docfx/cli-generated/cli.md`. **Do not hand-edit it.** It is + `.gitignore`d and surfaced into the site by a `docfx.json` content + entry. + +## Building locally + +```powershell +# 1. Build the solution (needed for DocFX metadata + the CLI emitter). +dotnet build fhir-codegen.sln -c Release + +# 2. Generate the live CLI page (optional — without it, articles/cli.html +# will 404 in the local preview but the rest of the site still builds). +dotnet run --no-build --configuration Release ` + --project src/fhir-codegen/fhir-codegen.csproj -- ` + docs cli --output docfx/cli-generated/cli.md + +# 3. Install DocFX (one-time per machine) and build the site. +dotnet tool install -g docfx +docfx ./docfx/docfx.json --serve +``` + +The CI workflow `.github/workflows/docs.yaml` runs the same three steps +on every push to `main` and deploys the result to GitHub Pages. + +## Important: build order matters + +`docfx` reads metadata from compiled `.dll`s. The +`dotnet build fhir-codegen.sln -c Release` step **must** run before +`docfx ./docfx/docfx.json`. If you ever rearrange the workflow, keep the +build step ahead of the `docfx` step. diff --git a/docs/xver.md b/docs/articles/cross-version.md similarity index 100% rename from docs/xver.md rename to docs/articles/cross-version.md diff --git a/docs/articles/extending.md b/docs/articles/extending.md new file mode 100644 index 000000000..f5f49942e --- /dev/null +++ b/docs/articles/extending.md @@ -0,0 +1,116 @@ +# Extending: Adding a New Language Exporter + +`fhir-codegen`'s extension point is the +[`ILanguage`](xref:Fhir.CodeGen.Lib.Language.ILanguage) interface +under `src/Fhir.CodeGen.Lib/Language/`. Adding a new exporter is a +pure code-add: you write a new class, the +[`LanguageManager`](xref:Fhir.CodeGen.Lib.Language.LanguageManager) +discovers it via reflection, and the CLI surfaces it as a +`generate ` subcommand automatically. + +## The recipe + +1. **Pick a name and location.** Single-file exporters live directly + under `src/Fhir.CodeGen.Lib/Language/.cs` (see `TypeScript.cs`). + More complex exporters get their own folder, e.g. `OpenApi/`, + `Firely/`, `Ruby/`. The folder convention scales better — language + common types and helpers live next to the exporter. +2. **Implement `ILanguage`.** The required surface is small: a + `Name` property and an `Export(ICodeGenConfig, DefinitionCollection)` + method. Look at + [`Info.LangInfo`](xref:Fhir.CodeGen.Lib.Language.Info.LangInfo) as a + minimal single-file exporter, and at + [`OpenApi.LangOpenApi`](xref:Fhir.CodeGen.Lib.Language.OpenApi.LangOpenApi) + as a "model-builder" exporter that converts the generic normalized + model into language-specific intermediate types before writing. +3. **Define an options class** that derives from + [`ConfigGenerate`](xref:Fhir.CodeGen.Lib.Configuration.ConfigGenerate). + The convention is a nested `Options` class on the + exporter, or a sibling `Options.cs` file. This class + carries every CLI flag the exporter accepts. +4. **Surface each option twice — once as a `[ConfigOption]` attribute, + once as a `ConfigurationOption` static.** This is the pattern used + throughout the existing exporters, e.g. + `src/Fhir.CodeGen.Lib/Configuration/ConfigSql.cs`. + + ```csharp + [ConfigOption( + ArgName = "--my-flag", + EnvName = "My_Flag", + Description = "Toggle the thing.")] + public bool MyFlag { get; set; } = false; + + private static ConfigurationOption MyFlagParameter { get; } = new() + { + Name = "MyFlag", + EnvVarName = "My_Flag", + DefaultValue = false, + CliOption = new System.CommandLine.Option( + "--my-flag", "Toggle the thing.") + { + Arity = System.CommandLine.ArgumentArity.ZeroOrOne, + IsRequired = false, + }, + }; + ``` + + ### Why two? + + The `[ConfigOption]` attribute is consumed by helper code that + binds parsed arguments back onto the strongly-typed properties of + the options class. The `ConfigurationOption` static is what + [`LaunchUtils.BuildCliOptions`](xref:fhir_codegen_shared.LaunchUtils) + walks to build the actual `System.CommandLine.Option` tree + handed to the parser. + + The two-surface pattern is **deliberate** today, but it is also a + known drift risk: if you add a new flag and forget to define its + `ConfigurationOption`, the CLI will silently ignore it; if you + change a default in only one place, the parser and the binder will + disagree. **Keep them in sync.** Several `*OptionsTests` already + exist in `Fhir.CodeGen.Lib.Tests` to pin this down for individual + languages; if you add a new exporter, add a similar pin-test. + +5. **You're done.** No registry to update. The next + `dotnet build fhir-codegen.sln` will pick the new exporter up via + `LanguageManager.LoadLanguages()`, the next `fhir-codegen --help` + will list `generate ` as a subcommand, and the next CI + docs build will add a `### generate ` section to + [Command Line Usage](cli.md) automatically. + +## Discovery, in detail + +`LanguageManager.LoadLanguages()` walks `typeof(ILanguage).Assembly` +once at static-init time and registers every concrete type that +implements `ILanguage`. The lookup is name-based and case-insensitive, +so `generate TypeScript` and `generate typescript` both resolve. + +This means **every exporter must live in the +`Fhir.CodeGen.Lib` assembly** (or be loaded into it before +`LanguageManager` is touched). Out-of-assembly exporters are not +currently supported. + +## Output discipline + +- Tests do **not** write generated artifacts to disk by default — + `Fhir.CodeGen.Lib.Tests.GenerationTestBase.WriteGeneratedFiles = + false`. Don't flip it in committed code; toggle it locally when + debugging a regression. +- The `Export` method should write into the directory passed to it (or + build its output in memory and let the caller decide where to put + it). It must not assume CWD. + +## Reference exporters + +| Pattern | Look at | +|---|---| +| Minimal single-file exporter | `TypeScript.cs`, `Info/LangInfo.cs` | +| Folder layout with shared helpers | `Firely/`, `OpenApi/`, `Ruby/`, `Cql/` | +| Two-stage (normalize → language-specific model → emit) | `OpenApi/ModelBuilder.cs` | +| Database-backed exporter | `SQLite/LangSQLite.cs` (delegates to `Fhir.CodeGen.LangSQLite`) | + +## See also + +- [Export Languages](languages.md) — current set and how to choose one. +- [Command Line Usage](cli.md) — generated CLI page; verify your new + exporter shows up here after a build. diff --git a/docs/articles/intro.md b/docs/articles/intro.md new file mode 100644 index 000000000..691398ff6 --- /dev/null +++ b/docs/articles/intro.md @@ -0,0 +1,90 @@ +# Introduction + +`fhir-codegen` is a .NET solution for ingesting FHIR specification +packages and exporting them into other languages and formats. + +The FHIR specification (both core and implementation guides) is itself +defined in FHIR — every resource, profile, value set, and search +parameter is delivered as a FHIR resource inside a `.tgz` package. That +makes the specification computable, but it also makes it inconvenient +for downstream consumers: a TypeScript or Ruby application doesn't want +to walk a `StructureDefinition` graph at runtime; it wants to use plain +classes / records / hashes that match the resource shape. + +This project bridges that gap. It loads FHIR packages, normalizes their +definitional content into a consistent in-memory model +([`Fhir.CodeGen.Common.Models`](xref:Fhir.CodeGen.Common.Models)), and +hands the normalized model to a pluggable set of language exporters +that emit code, schemas, or summaries. + +## High-level pipeline + +``` + .tgz packages from ~/.fhir + │ + ▼ + Fhir.CodeGen.Packages (cache + registry lookup) + │ + ▼ + Fhir.CodeGen.Lib.Loader.PackageLoader + │ + ▼ + normalized DefinitionCollection + (Fhir.CodeGen.Common.Models) + │ + ┌─────────────────┼─────────────────┐ + ▼ ▼ ▼ + ILanguage ILanguage ILanguage + (TypeScript) (Ruby) (Cql) ... + │ │ │ + ▼ ▼ ▼ + files on disk (or in-memory output) +``` + +The same pipeline backs three top-level CLI commands: + +- `generate ` — emit one language's output for one or more + packages. +- `compare` — diff two sets of packages. +- `xver` — produce cross-version artifacts (ValueSets and + StructureDefinition extensions) across FHIR R2–R5. + +A fourth command, `docs cli`, generates the +[Command Line Usage](cli.md) page on this site directly from the live +parser. + +## Multi-version FHIR is built in + +The Firely .NET SDK ships separate `Hl7.Fhir.STU3`, `Hl7.Fhir.R4`, +`Hl7.Fhir.R4B`, and `Hl7.Fhir.R5` assemblies. Their type names collide +(every version has its own `Patient`), so this solution uses MSBuild +extern-alias targets to load them side-by-side. See the +`AddPackageAliases` target in `src/fhir-codegen/fhir-codegen.csproj` +and `src/Fhir.CodeGen.Lib.Tests/Fhir.CodeGen.Lib.Tests.csproj` for the +exact mapping. + +This is the mechanism that lets `Fhir.CodeGen.CrossVersionLoader` and +`Fhir.CodeGen.Comparison` reason about R3 and R5 in the same process. + +## Why C#? + +When you build tooling that targets multiple language pipelines you +have to pick a host language. C# was chosen because it is performant, +cross-platform, and pleasant to work in; the toolchain (`dotnet`, +xUnit, Shouldly) is also enough to keep contributors productive without +extra glue. + +## Documentation site + +This documentation site is built with +[DocFX](https://dotnet.github.io/docfx/) on every push to `main` and +served from [GitHub Pages](https://pages.github.com/) at +. The full source for the site +lives under `docs/` in the repository; the +[Command Line Usage](cli.md) page is generated at build time by the +`fhir-codegen docs cli` subcommand and is the only article that is not +hand-authored. + +For details on adding a new exporter, see [Extending](extending.md). +For the current set of exporters and how to choose one, see +[Export Languages](languages.md). diff --git a/docs/articles/languages.md b/docs/articles/languages.md new file mode 100644 index 000000000..f70df97bc --- /dev/null +++ b/docs/articles/languages.md @@ -0,0 +1,140 @@ +# Export Languages + +`fhir-codegen` ships a set of language exporters that each take a +loaded FHIR package set and emit a different output format. This page +gives a tour of what's currently in the box and what each exporter is +optimized for. For the **exact** list of CLI options each exporter +accepts, see the [Command Line Usage](cli.md) page — that page is +generated from the live binary and cannot drift from what the CLI +actually parses. + +## The exporter contract + +Every exporter implements +[`ILanguage`](xref:Fhir.CodeGen.Lib.Language.ILanguage) and lives under +`src/Fhir.CodeGen.Lib/Language/` either as a single-file exporter +(`TypeScript.cs`) or as its own folder (`Firely/`, `OpenApi/`, etc.). +They are auto-discovered by +[`LanguageManager`](xref:Fhir.CodeGen.Lib.Language.LanguageManager) at +static-init time via reflection over `typeof(ILanguage).Assembly`, so +adding a new language is a pure code-add — there is no registry to +update. See [Extending](extending.md) for the recipe. + +Each exporter exposes a nested `*Options` class (e.g. +`TypeScript.TypeScriptOptions`) that carries its language-specific +configuration. Options are surfaced to the CLI via +`[ConfigOption]` attributes plus a matching `ConfigurationOption` +static; both must stay in sync. The CLI page's per-language sections +come straight from the `ConfigurationOption` side of that pair. + +## Current exporters + +> All exporters target the normalized `DefinitionCollection` +> produced by `Fhir.CodeGen.Lib.Loader.PackageLoader`. That model is +> FHIR-version-agnostic, which means the same exporter can run against +> R3, R4, R4B, R5, or any IG built on top of them. + +### TypeScript + +Source: `src/Fhir.CodeGen.Lib/Language/TypeScript.cs`. + +Emits a single TypeScript file containing interface declarations for +the resources, complex types, and (optionally) inline enums in the +loaded package. The output is FHIR+JSON shape-compatible — there is no +runtime; the file is meant to be consumed by `tsc` for static +type-checking. + +This is also the exporter that backs the `@types/fhir` definitions on +DefinitelyTyped (post-processed downstream); changes to the output +shape should be coordinated with the +[fhir-dts-generator](https://github.com/Vermonster/fhir-dts-generator) +maintainers. + +### Firely (`CSharpFirely2`) + +Source: `src/Fhir.CodeGen.Lib/Language/Firely/`. + +Emits the C# classes used by the +[Firely .NET SDK](https://fire.ly/products/firely-net-sdk/). The +exporter has a `subset` option (`all` / `common` / `main`) that splits +the output between the version-specific classes and the +`firely-net-common` package. There is also a `CSharpFirelyIG` +sub-mode that emits IG-specific additions on top of an existing SDK +build. + +Changes to this exporter must be approved by the Firely SDK +maintainers, since the SDK consumes the output verbatim. + +### OpenApi + +Source: `src/Fhir.CodeGen.Lib/Language/OpenApi/`. + +Emits an [OpenAPI](https://www.openapis.org/) definition (v2 or v3) +describing a FHIR REST API for the loaded package. Tool-chains that +consume OpenAPI vary widely in what they accept, so this exporter is +the most option-heavy of the bunch — it can include or exclude +`Bundle` / `_history` / search-by-POST endpoints, expand or collapse +schemas, control description generation, etc. See the +[Command Line Usage](cli.md) page for the full list. + +### Ruby + +Source: `src/Fhir.CodeGen.Lib/Language/Ruby/`. + +Emits Ruby class definitions matching the loaded package shape. +Useful when you need a Ruby SDK for an IG that has no published +language binding. + +### CQL + +Source: `src/Fhir.CodeGen.Lib/Language/Cql/`. + +Emits [Clinical Quality Language](https://cql.hl7.org/) model-info +artifacts built from the loaded package. Used by CQL tooling that +needs a model-info file describing a non-standard FHIR profile or IG. + +### FHIR Shorthand + +Source: `src/Fhir.CodeGen.Lib/Language/Shorthand/`. + +Emits [FHIR Shorthand](https://build.fhir.org/ig/HL7/fhir-shorthand/) +(`.fsh`) for the loaded package — useful when you need a Shorthand +representation of an existing IG, for example to feed back into a +SUSHI-driven pipeline. + +### SQLite + +Source: `src/Fhir.CodeGen.Lib/Language/SQLite/`. + +Emits a SQLite database whose schema mirrors the loaded package +structure. Backed by the `Fhir.CodeGen.LangSQLite` project; downstream +tooling that needs to query a FHIR package shape with SQL uses this. + +### Info + +Source: `src/Fhir.CodeGen.Lib/Language/Info/LangInfo.cs`. + +Emits a single text file summarizing the loaded package: every +resource, complex type, primitive, value set, and code system, with +their elements, cardinalities, and bindings. Used both as a +human-readable inspection aid and as a fixture for regression-testing +the loader. + +## Choosing an exporter + +| If you need… | Use… | +|---|---| +| Static types for a TypeScript / JavaScript app | `TypeScript` | +| C# classes that round-trip via the Firely SDK | `Firely` (`CSharpFirely2`) | +| An OpenAPI spec for a FHIR REST endpoint | `OpenApi` | +| Ruby SDK shapes for a custom IG | `Ruby` | +| CQL model-info for a non-standard profile | `Cql` | +| Shorthand (`.fsh`) round-trip of an IG | `Shorthand` | +| A SQLite schema mirroring a FHIR package | `SQLite` | +| A text summary you can grep | `Info` | + +## See also + +- [Extending](extending.md) — recipe for adding a new exporter. +- [Command Line Usage](cli.md) — exact CLI flags and defaults for every + exporter, generated from the live binary. diff --git a/src/Fhir.CodeGen.Packages/docs/resolution.md b/docs/articles/packages-resolution.md similarity index 100% rename from src/Fhir.CodeGen.Packages/docs/resolution.md rename to docs/articles/packages-resolution.md diff --git a/docs/sanitization.md b/docs/articles/sanitization.md similarity index 100% rename from docs/sanitization.md rename to docs/articles/sanitization.md diff --git a/docs/articles/toc.yml b/docs/articles/toc.yml new file mode 100644 index 000000000..77725f944 --- /dev/null +++ b/docs/articles/toc.yml @@ -0,0 +1,14 @@ +- name: Introduction + href: intro.md +- name: Export Languages + href: languages.md +- name: Extending + href: extending.md +- name: Command Line Usage + href: cli.md +- name: Cross-Version Artifacts + href: cross-version.md +- name: FHIR Sanitization Utilities + href: sanitization.md +- name: FHIR Package Resolution + href: packages-resolution.md diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..ef1b9c156 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,66 @@ +# fhir-codegen + +A .NET solution for ingesting FHIR specification packages and exporting +them into other languages and formats. + +fhir-codegen normalizes the definitional surface of FHIR (core and +implementation guides, R2 through R5) into a single in-memory model and +exposes that model to a pluggable set of language exporters. It ships +both as a library set and as a `System.CommandLine`-based CLI. + +## What you can do with it + +- Generate strongly typed code for application use: + TypeScript, Firely C# (`CSharpFirely2`), Ruby, CQL, FHIR Shorthand. +- Generate API surfaces from a FHIR package: OpenAPI definitions. +- Generate database / lookup artifacts: SQLite schemas, the textual + `Info` summary, and other inspection helpers. +- Compare two sets of FHIR packages and emit Markdown / JSON diffs. +- Run cross-version (`xver`) processing across R2/R3/R4/R4B/R5 to + produce bridge ValueSets and StructureDefinition extensions. + +## Solution layout + +| Project | Role | +|---|---| +| `Fhir.CodeGen.Common` | Lightweight POCOs / shared models / polyfills. | +| `Fhir.CodeGen.Packages` | FHIR package cache management (download, resolve, registry lookup). | +| `Fhir.CodeGen.CrossVersionLoader` | Load and reconcile artifacts across FHIR versions. | +| `Fhir.CodeGen.MappingLanguage` | FHIR Mapping Language (FML) parser/abstractions. | +| `Fhir.CodeGen.LangSQLite` | SQLite export backend used by the `Lib` engine. | +| `Fhir.CodeGen.Lib` | Core engine: loader → normalized model → language exporters. | +| `Fhir.CodeGen.Comparison` | Package and artifact diffing. | +| `Fhir.CodeGen.CrossVersionExporter` | Produces cross-version artifacts. | +| `fhir-codegen` | The CLI (`System.CommandLine`-based). | + +Internal helpers — `Fhir.CodeGen.SQLiteGenerator` and +`performance-test-cli` — are not part of the published API surface and +are excluded from the API reference on this site. + +## Where to go next + +- [Introduction](articles/intro.md) — what this project is and the + history behind it. +- [Export Languages](articles/languages.md) — the current set of + language exporters and how to think about choosing one. +- [Extending](articles/extending.md) — add a new language exporter + (`ILanguage` + `LanguageManager` discovery + `[ConfigOption]` / + `ConfigurationOption` pairing). +- [Command Line Usage](articles/cli.md) — every CLI subcommand and + option, generated from the live binary on every build. +- [Cross-Version Artifacts](articles/cross-version.md) — the four-phase + process for producing cross-version ValueSets and extensions. +- [FHIR Sanitization Utilities](articles/sanitization.md) — + `FhirSanitizationUtils` reference for code-generator authors. +- [FHIR Package Resolution](articles/packages-resolution.md) — how + package directives are parsed and resolved across registries. +- [API Reference](api/index.md) — XMLDoc-driven API for the + `Fhir.CodeGen.*` library set. + +## Source + +- Repository: +- Issues: +- Discussion: the + [`#dotnet` stream on chat.fhir.org](https://chat.fhir.org/#narrow/stream/179171-dotnet) +- License: [MIT](https://github.com/FHIR/fhir-codegen/blob/main/LICENSE) diff --git a/specs/FhirDbComparer.Compare-specification.md b/docs/specs/fhirdb-comparer-compare.md similarity index 100% rename from specs/FhirDbComparer.Compare-specification.md rename to docs/specs/fhirdb-comparer-compare.md diff --git a/specs/FhirDbComparer.doStructureComparisons-specification.md b/docs/specs/fhirdb-comparer-do-structure.md similarity index 100% rename from specs/FhirDbComparer.doStructureComparisons-specification.md rename to docs/specs/fhirdb-comparer-do-structure.md diff --git a/specs/FhirDbComparer-doValueSetComparisons-specification.md b/docs/specs/fhirdb-comparer-do-valueset.md similarity index 100% rename from specs/FhirDbComparer-doValueSetComparisons-specification.md rename to docs/specs/fhirdb-comparer-do-valueset.md diff --git a/docs/specs/toc.yml b/docs/specs/toc.yml new file mode 100644 index 000000000..2a9409825 --- /dev/null +++ b/docs/specs/toc.yml @@ -0,0 +1,8 @@ +- name: FhirDbComparer.Compare + href: fhirdb-comparer-compare.md +- name: FhirDbComparer.doStructureComparisons + href: fhirdb-comparer-do-structure.md +- name: FhirDbComparer.doValueSetComparisons + href: fhirdb-comparer-do-valueset.md +- name: XVerProcessor.WriteFhirFromDatabase + href: xver-processor-write-fhir.md diff --git a/specs/XVerProcessor_WriteFhirFromDatabase-specification.md b/docs/specs/xver-processor-write-fhir.md similarity index 100% rename from specs/XVerProcessor_WriteFhirFromDatabase-specification.md rename to docs/specs/xver-processor-write-fhir.md diff --git a/docs/toc.yml b/docs/toc.yml new file mode 100644 index 000000000..4f8cc531a --- /dev/null +++ b/docs/toc.yml @@ -0,0 +1,7 @@ +- name: Articles + href: articles/ +- name: Specifications + href: specs/ +- name: API Documentation + href: api/ + homepage: api/index.md diff --git a/fhir-codegen.sln b/fhir-codegen.sln index 259d49d5c..c1b7f8609 100644 --- a/fhir-codegen.sln +++ b/fhir-codegen.sln @@ -52,8 +52,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fhir.CodeGen.SQLiteGenerato EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" ProjectSection(SolutionItems) = preProject - docs\sanitization.md = docs\sanitization.md - docs\xver.md = docs\xver.md + docs\README.md = docs\README.md + docs\index.md = docs\index.md + docs\toc.yml = docs\toc.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".claude", ".claude", "{6601332F-A738-4E4E-9ACC-D6A52E4FF6FA}" From 1072727dfc2d1b7f16072c937bb2eb7b6ffd9a42 Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Wed, 6 May 2026 10:54:30 -0500 Subject: [PATCH 4/8] docs: rewrite docfx.json for current project set; cutover to top-level docs/ Phase 2 of the docs-site restoration plan. Rewrites docfx/docfx.json to generate API reference for the current 8-project Fhir.CodeGen.* library set only (no CLI types, no SQLiteGenerator, no performance-test-cli, no *.Tests). Adds three content roots: api/ (generated), ../docs (new authoring root from Phase 1), and cli-generated/ (Phase 3 emitter output, gitignored). Sets _appTitle and _gitContribute metadata to FHIR/fhir-codegen. Cutover deletes the old docfx/articles/, docfx/index.md, and docfx/toc.yml that were superseded by docs/ in Phase 1. Fixes four pre-existing source XMLDoc bugs that surfaced during the docs build: - PackageLoader.cs:1523, ServerConnector.cs:825 - cref `FhirCache` pointed at a removed type; replaced with the enclosing class name. - PackageManifest.cs:88 - unescaped `` in a `` block; escaped to `<filename>`. - RegistryCatalogRecord.cs:22,43 - unescaped `&` in two example URLs; escaped to `&`. docfx now builds with 12 warnings: 3 are pre-existing CS warnings unrelated to docs, 9 are InvalidFileLink to the cli.md file that the Phase 3 emitter generates at build time. Strict --warningsAsErrors validation is deferred to the end of Phase 3. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docfx/.gitignore | 1 + docfx/api/index.md | 21 +- docfx/articles/blazorui.md | 65 ------- docfx/articles/cli.md | 105 ---------- docfx/articles/extending.md | 17 -- docfx/articles/intro.md | 31 --- docfx/articles/languages.md | 138 ------------- docfx/articles/test.md | 28 --- docfx/articles/toc.yml | 12 -- docfx/docfx.json | 48 +++-- docfx/index.md | 184 ------------------ docfx/toc.yml | 5 - docs/articles/extending.md | 6 +- docs/articles/packages-resolution.md | 2 +- docs/index.md | 5 +- docs/toc.yml | 3 - src/Fhir.CodeGen.Lib/Loader/PackageLoader.cs | 2 +- src/Fhir.CodeGen.Lib/Net/ServerConnector.cs | 2 +- .../Models/PackageManifest.cs | 2 +- .../Models/RegistryCatalogRecord.cs | 4 +- 20 files changed, 63 insertions(+), 618 deletions(-) delete mode 100644 docfx/articles/blazorui.md delete mode 100644 docfx/articles/cli.md delete mode 100644 docfx/articles/extending.md delete mode 100644 docfx/articles/intro.md delete mode 100644 docfx/articles/languages.md delete mode 100644 docfx/articles/test.md delete mode 100644 docfx/articles/toc.yml delete mode 100644 docfx/index.md delete mode 100644 docfx/toc.yml diff --git a/docfx/.gitignore b/docfx/.gitignore index 9e6226d1f..8604ef0be 100644 --- a/docfx/.gitignore +++ b/docfx/.gitignore @@ -7,3 +7,4 @@ /**/bin/ /**/obj/ _site +cli-generated/ diff --git a/docfx/api/index.md b/docfx/api/index.md index d695f4fb7..fa78f9e1b 100644 --- a/docfx/api/index.md +++ b/docfx/api/index.md @@ -1,5 +1,22 @@ # API Documentation -This section contains API documentation automatically generated from the source code comments. +This section contains API documentation automatically generated from +the XMLDoc comments on the `Fhir.CodeGen.*` library set: -Information about specific projects can be found on the [Documentation Home Page](/fhir-codegen/index.md). \ No newline at end of file +- `Fhir.CodeGen.Common` — shared models and POCOs. +- `Fhir.CodeGen.Packages` — FHIR package cache, registry lookup, and + resolution. +- `Fhir.CodeGen.CrossVersionLoader` — load and reconcile artifacts + across FHIR versions. +- `Fhir.CodeGen.MappingLanguage` — FHIR Mapping Language (FML) parser. +- `Fhir.CodeGen.LangSQLite` — SQLite export backend. +- `Fhir.CodeGen.Lib` — core engine: loader → normalized model → + language exporters. +- `Fhir.CodeGen.Comparison` — package and artifact diffing. +- `Fhir.CodeGen.CrossVersionExporter` — cross-version artifact emission. + +Use the navigation pane on the left to browse by namespace and type. + +The CLI itself (`fhir-codegen.exe`) is documented on the **Command +Line Usage** page rather than here; its internal types are +implementation detail. diff --git a/docfx/articles/blazorui.md b/docfx/articles/blazorui.md deleted file mode 100644 index 7cfa12d7f..000000000 --- a/docfx/articles/blazorui.md +++ /dev/null @@ -1,65 +0,0 @@ -# FhirCodeGenBlazor - -The Blazor project is intended as a developer-friendly interface for exploring FHIR packages and exporting 'language' outputs. - -The project is a server-hosted Blazor web UI. To date, it has only been tested as a single-user context - i.e., this is a UI for a local computer, not a hosted server. - -## Index Page - -The main index page is a listing of the contents of the user's FHIR Cache. Individual packages (package id plus version) can be loaded directly, or packages can be added or removed. - -Clicking 'Add Package' takes a user to the [Add Package Page](#add-package-page). - -Clicking 'Load' on a package directive record loads the package into memory and exposes additional page links: [View Package](#view-package-page), [Package Elements](#package-elements-page), and [Export Package](#export-package-page). - -## Add Package Page - -The 'Add Package Page' is used to find and download FHIR packages. Packages can be pulled from package registries (`http://packages.fhir.org/` and `http://packages2.fhir.org`), released web-packages of FHIR core (e.g., `http://hl7.org/fhir/R4/hl7.fhir.r4.core.tgz`), or the CI build server (`http://build.fhir.org`, with various branch and IG conventions). - -For release packages, the 'Lookup' option requests the package version manifests from the registry servers and allows downloading specific versions. - -For CI Builds, the lookup is used to confirm that a package exists at the requested location. - -## View Package Page - -The 'View Package Page' is used to explore package artifacts. It is intended to be considered as a view equivalent to browsing the published definitions, though it does not contain additional information (e.g., HTML pages) and is not considered a 'normative' view into packages. - -It does contain additional features for traversing nested definitions, expanding into datatypes (e.g., presenting a datatype element the same way a backbone element is displayed), etc.. - -## Package Elements Page - -The 'Package Elements Page' is used to search over all 'FHIR Elements' within a package (can be filtered by artifact type). - -The page includes the ability to download JSON representations of the results, either an array of all FHIR Element Paths, or the normalized element definitions. - -### LINQ - -One of the mechanisms to search over package elements is a LINQ predicate. The predicate is evaluated on each (normalized) [FhirElement](/fhir-codegen/api/Microsoft.Health.Fhir.CodeGenCommon.Models.FhirElement.html) in the package, and there is global access to the current-context [FhirVersionInfo](/fhir-codegen/api/Microsoft.Health.Fhir.SpecManager.Manager.FhirVersionInfo.html) as `Info`. - -Some examples: -* to search for all elements that have a type of `uri` -```c# -e => (e.ElementTypes?.ContainsKey("uri") ?? false) -``` - -* to search for all elements that have a type of `reference` and do not have search parameters: -```c# -e => ((e.ElementTypes?.ContainsKey("Reference") ?? false) && (!Info.SearchParametersByUrl.Values.Any(sp => sp.Expression.Contains(e.Path)))) -``` - -* to search for elements that have a `required` binding to a value-set that starts with `http://hl7.org/fhir/ValueSet/request`: -```c# -e => ((e.BindingStrength?.Equals("required") ?? false) && (e.ValueSet?.StartsWith("http://hl7.org/fhir/ValueSet/request") ?? false)) -``` - -## Export Package Page - -The 'Export Package Page' is used to perform an export based on a loaded package. The page allows for selection of the Export Language module, common export parameters, and language-specific options. - -Note that the export path is local to the computer running the Blazor UI (server). - -## Diff Tool Page - -The 'Diff Tool Page' is used to granularly compare either two packages or two artifacts. The packages must be loaded into memory to be available for selection. - -The artifact types and changes detected are constantly being improved. If you have suggestions or requests, please let us know! diff --git a/docfx/articles/cli.md b/docfx/articles/cli.md deleted file mode 100644 index dbf3f24a6..000000000 --- a/docfx/articles/cli.md +++ /dev/null @@ -1,105 +0,0 @@ -# Command Line Interface - -The command-line-interface (CLI) project is intended as a utility suitable for both manual and automated (e.g., CI Pipeline) use. - -The CLI is focused on language-export. It includes options to specify inputs (e.g., which FHIR packages to download/parse, if additional filters should be used, etc.) and outputs (e.g., export language, destination directory, etc.). - -## Options - -The CLI self-reports all options with descriptions: - -```dos -Usage: - fhir-codegen-cli [options] - -Options: - -o, --output-path File or directory to write output. - - --package-directory The path to a local directory for FHIR packages, - if different than the default - FHIR cache (~/.fhir); e.g., (.../fhirPackages)). - - -l, --language Name of the language to export (default: - Info|TypeScript|CSharpBasic). - --language-help Display languages and their options. - [default: False] - --language-options, --opts Language specific options, see documentation for - more details. Example: - Lang1|opt=a|opt2=b|Lang2|opt=tt|opt3=oo. - --language-input-dir The full path to a local directory to pass - additional content to languages. - - --offline-mode Offline mode (will not download packages). - [default: False] - -k, --export-keys '|' separated list of items to export (not present - to export everything). - --official-expansions-only Set to restrict value-sets to only official - expansions. [default: False] - --experimental, --include-experimental If the output should include structures marked - experimental. [default: False] - --export-types, --types Types of FHIR structures to export - (primitive|complex|resource|interaction|enum), - default is all. - --extension-support The level of extensions to include (none| - official|officialNonPrimitive|nonPrimitive|all), - default is nonPrimitive. - --fhir-server-url, --server FHIR Server URL to pull a CapabilityStatement - or Conformance from. The server - must provide application/fhir+json support. - - -p, --packages '|' separated list of packages, with or without - version numbers, e.g., - hl7.fhir.r4.core#4.0.1|hl7.fhir.us.core#latest. - --load-DSTU2, --load-r2 If FHIR DSTU2 should be loaded, which version - (e.g., 1.0.2 or latest) - --load-r3, --load-STU3 If FHIR STU3 should be loaded, which version - (e.g., 3.0.2 or latest) - --load-r4 If FHIR R4 should be loaded, which version - (e.g., 4.0.1 or latest) - --load-r4b If FHIR R4B should be loaded, which version - (e.g., 4.3.0 or latest) - --load-r5 If FHIR R5 should be loaded, which version - (e.g., 5.0.0-ballot or latest) - --ci-branch If loading from the CI server, the name of the - branch to use. - - -v, --verbose Show verbose output. [default: False] - --version Show version information - -?, -h, --help Show help and usage information -``` - -## Package Source - -By default, the CLI will use the user's FHIR cache directory (`~/.fhir`). This directory is common to many tools in the FHIR ecosystem, such as the publication tooling (e.g., IG Publisher) and package-based tools from other companies (e.g., Firely). - -If a different directory is desired (e.g., CI Builds in a docker image, 'clean' builds from a specific location, etc.), the `--package-directory` option can be used. - -## Specifying Packages - -Initially, the CLI only supported loading FHIR Core specifications (e.g., FHIR R4). In order to maintain backwards compatibility, explicit options to load core specifications are still supported (e.g., `--load-r4 latest`), though users should consider changing to the package directive format (e.g., `--packages hl7.fhir.r4.core#latest`). - -## Languages - -fhir-codegen supports several export languages, each with their own configuration (options), additional files, and artifact support. Since the language support is common to all projects in the repository, more information can be found on the [Languages Page](languages.md) - -## Filtering - -Several options relate to filtering the artifacts included in a package, e.g., `--export-keys` is used to provide an explicit list of artifacts that should be allowed; `--server` is used to filter packages based on the capabilities of an existing FHIR server; etc.. - -These filters are applied after packages are loaded. For example, a user may want to generate *only* definitions for FHIR R4 Patient, Encounter, Observation, and Bundle resources. A user can specify to load the FHIR R4 specification and use the option `--export-keys Patient|Encounter|Observation|Bundle` to filter the specification. Note that the filtering is "smart" in that all definitions required by those resources (e.g., data types, etc.) will still be included. - -Note that some languages will provide 'object' stubs for elements that cannot be defined, while others may exclude them entirely. - -## Examples - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a TypeScript file in the current directory - * `fhir-codegen-cli -p hl7.fhir.r4#latest --language TypeScript --output-path ./R4.ts` - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a TypeScript file in the current directory, restricted to just the Resources: Patient, Encounter, and Observation - * `fhir-codegen-cli --load-r4 latest --language TypeScript --output-path ./R4.ts --export-keys Patient|Encounter|Observation` - -* Download and parse the latest published version of each FHIR release into the user FHIR cache, then build a C# file for each in ./cs - * `fhir-codegen-cli --load-r2 latest --load-r3 latest --load-r4 latest --load-r5 latest --language CSharpBasic --output-path ./cs` - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a C# file in the current directory using the namespace: MyOrg.MyProject.Fhir - * `fhir-codegen-cli -p hl7.fhir.r4#latest --language CSharpBasic --output-path ./cs/R4.cs --language-options CSharpBasic|namespace=MyOrg.MyProject.Fhir` diff --git a/docfx/articles/extending.md b/docfx/articles/extending.md deleted file mode 100644 index c38fb5e29..000000000 --- a/docfx/articles/extending.md +++ /dev/null @@ -1,17 +0,0 @@ -# Adding New Languages - -The system is designed to allow developers to add additional languages to be exported. - -Language files must be added to the `src/Microsoft.Health.Fhir.SpecManager/Language` directory, and implement the [ILanguage](/fhir-codegen/api/Microsoft.Health.Fhir.SpecManager.Language.ILanguage.html) interface present in the same directory. - -The library loads and parses all FHIR versions into a consistent local model. - -During export, the interface function [Export](/fhir-codegen/api/Microsoft.Health.Fhir.SpecManager.Language.ILanguage.html#methods) is called, with a [IPackageExportable](/fhir-codegen/api/Microsoft.Health.Fhir.SpecManager.Manager.IPackageExportable.html) already set to all user options (e.g., the requested version of FHIR has been loaded, filtering has been applied, etc.). - -The `Export` function may write as many files as desired in the `exportDirectory`. The exporter will move those files into the user-requested directory, and will bundle them together in an archive if necessary (relative paths are preserved). - -Existing language implementations can be used to serve as templates for export. Specifically: -* [Info](/fhir-codegen/api/Microsoft.Health.Fhir.SpecManager.Language.Info.html) is a good 'single-file' export language that covers many types of artifacts. -* [TypeScriptSdk](/fhir-codegen/api/Microsoft.Health.Fhir.SpecManager.Language.TypeScriptSdk.html) is a good example of an 'advanced' configuration that performs a conversion from the generic models into language-specific objects before exporting. - -More information about all of the implemented language modules can be found on the [Export Languages Page](languages.md). \ No newline at end of file diff --git a/docfx/articles/intro.md b/docfx/articles/intro.md deleted file mode 100644 index 5263ce81e..000000000 --- a/docfx/articles/intro.md +++ /dev/null @@ -1,31 +0,0 @@ -# About - -This project is intended to allow for easy use of FHIR specification packages. The FHIR specification (both core and implementation guides) are defined via FHIR models. FHIR definitional models are detailed computable structures for (e.g.): -* defining and supporting the publication of the specifications, -* consumption by applications to control behavior, -* etc. - -Because of the targets of these structures, they are often are not too "friendly" for downstream projects or usage. - -Additionally, the FHIR specification has, and continues to, evolve over time. - -To that end, this project attempts to normalize the definitional aspects of FHIR into more developer-friendly models and abstract many of the internal changes that occur within the specifications. - -# Navigation - -Articles about the projects or major topics are in the navigation links (either side-bar or as 'Table of Contents'). - -API documentation is automatically generated from the source code and available [here](/fhir-codegen/api/index.html). - - -# History / Development FAQs - -## Why C#? - -The decision was somewhat arbitrary - when building tooling intended to be used in multiple language pipelines, one has to be chosen. I enjoy working in C# (both the language itself and associated tooling), it is performant, and it is cross-platform. - -## Documentation Site - -[DocFX](https://dotnet.github.io/docfx/) is used to generate this documentation site. Articles are written in Markdown in this repo, while the API documentation is generated via the XMLDoc comments in the source code. - -[GitHub Pages](https://pages.github.com/) is used to host this documentation site. \ No newline at end of file diff --git a/docfx/articles/languages.md b/docfx/articles/languages.md deleted file mode 100644 index 284a33255..000000000 --- a/docfx/articles/languages.md +++ /dev/null @@ -1,138 +0,0 @@ -# Export Language Information - -While each 'export language' is unique, there are several definitions that have evolved over time and kept prior versions (for existing functionality). This page groups languages for context. - -## C\# Basic Models - -These languages are used to generate 'basic' FHIR models in C\#. That is to say, classes that represent the FHIR+JSON structures and can round-trip in FHIR+JSON. Initially, these classes were used to bootstrap this project, though only the definitions from DSTU2 are still used for this. - -Today, these exports are used as part of the 'generated' definitions to ensure that parsing and export remain consistent in a compilable (testable) format, as well as for prototyping changes to the core FHIR specifications. - -### CSharpBasic - -Initial basic C# language bindings, useful for prototyping and small projects. Exported classes are able to serialize to and parse from FHIR+JSON. This language exports a single file containing all exported artifacts. - -| Language Option | Description | Default | Allowed | -| --------- | ----------- | ------- | ------- | -| namespace | Namespace to use when exporting C\# files. | `fhir` | C\# namespace literal strings | - - -### CSharp2 - -Second version of basic C# language bindings, useful for prototyping and small projects. Exported classes are able to serialize to and parse from FHIR+JSON using `System.Text.Json`. This language exports a directory structure with individual files for each artifact (e.g., resource, value set, etc.). - -| Language Option | Description | Default | Allowed | -| --------- | ----------- | ------- | ------- | -| access-modifier | Access modifier for exported elements. | `public` | `public` \| `internal` \| `private` | -| namespace | Namespace to use when exporting C# files. | `Fhir.R{VersionNumber}` | C# namespace literal strings | - -## Firely C\# - -These language definitions are used to generate the 'generated' portions of the [Firely .Net SDK](https://fire.ly/products/firely-net-sdk/). - -Note that changes to these modules must be submitted or approved by Firely SDK maintainers. - -### CSharpFirely1 - -Export base C# classes needed for the Firely-maintained C# API ([FHIR-Net-API](https://github.com/FirelyTeam/fhir-net-api/)), v1. - -| Language Option | Description | Default | Allowed | -| --------- | ----------- | ------- | ------- | -| DetailedHeader | If the generator should include the user and date/time information in the header. | `true` | `true` \| `false` | - -### CSharpFirely2 - -Export base C# classes needed for the Firely-maintained C# API ([FHIR-Net-API](https://github.com/FirelyTeam/fhir-net-api/)), v2. - -| Language Option | Description | Default | Allowed | -| --------- | ----------- | ------- | ------- | -| subset | Which subset of language exports to make. | `main` | `all` \| `common` \| `main` | -| w5 | If output should include 5 W's mappings. | `true` | `true` \| `false` | - -#### Subsets - -Note that the `subset` option is used to control which type of objects are exported: -* `all` is used to export all package artifacts. -* `common` is used to export artifacts which have been promoted to the [common](https://github.com/FirelyTeam/firely-net-common/) Firely SDK package. -* `main` is used to export version-specific artifacts, a complement to `common`. - -### CSharpFirelyIG - -Prototype module for generating Implementation Guide-specific additions to the Firely Net SDK. - -## Info - -This language definition produces a text output of package contents. This is used as part of the 'generated' file set to ensure that parsing and generation remain consistent. These files are also useful as a method to quickly find information from a package. - -## TypeScript - -TypeScript generation includes a few different language export modules with different goals. Each is detailed below. - -### TypeScript - -This language exports a single TypeScript file, useful for prototyping and small projects. Exported classes are able to serialize to and parse from FHIR+JSON. - -This language is kept stable as it is used to generate the definitions used in [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/fhir) (`@types/fhir`). Post-processing of this file into the DTS used is done by Vermonster's [fhir-dts-generator](https://github.com/Vermonster/fhir-dts-generator) project. - -Note that changes to this module must be submitted or approved by Vermonster. - -### TypeScript2 - -This is the second (internal) iteration of TypeScript exports. It generates a single file per artifact (e.g., resource, value-set, etc.). It is a prototype for moving from 'JSON-definition' to 'SDK' territory. - -| Language Option | Description | Default | Allowed | -| --------- | ----------- | ------- | ------- | -| namespace | Namespace to use when exporting C# files. | `Fhir.R{VersionNumber}` | C# namespace literal strings | - -### TypeScriptSdk - -This module is used to generate the [fhir-typescript](https://github.com/fhir-typescript/fhir-typescript) SDK (beta). While serialization and parsing are FHIR+JSON compatible, the class definitions provide a smoother developer experience (e.g., choice types are a single property with multiple allowed types). - -Note that this is the first export module to separate language-specific generation from the file writing. E.g., the class in `Language/TypeScriptSdk/ModelBuilder.cs` is used to convert the internal normalized but generic models (e.g., `FhirElement`) into TypeScript-specific models (e.g., `TypeScriptSdk.ModelBuilder.ExportElement`). This style of module is generally preferred moving forward, as it allows for more flexibility in exports (e.g., being able to internalize the models for FHIR R4 when exporting an IG built on that version of FHIR). - -Note that changes to this module must be submitted or approved by 'fhir-typescript' maintainers. - -## Cytoscape - - **EXPERIMENTAL** - -Export a [cytoscape](https://js.cytoscape.org/) data file (JSON). - -## OpenAPI - - **EXPERIMENTAL** - -This module is used to export [OpenAPI](https://www.openapis.org/) definitions. Tool-chains that consume OpenAPI definitions are varied and often have quite specific requirements. To be more widely useful, this module defines *many* options to modify the exported definitions. - -Note that this module is still considered experimental/beta at this time. Note that this module is expected to become 'stable' relatively Soon™ (2022-2023). - -| Language Option | Description | Default | Allowed | -| --------- | ----------- | ------- | ------- | -| SchemaLevel | How much schema to include. | `detailed` | `minimal` \| `names` \| `detailed` | -| FhirJson | If paths should explicitly support FHIR+JSON. | `true` | `true` \| `false` | -| FhirXml | If paths should explicitly support FHIR+XML. | `false` | `true` \| `false` | -| PatchJson | If PATCH operations should explicitly support json-patch. | `false` | `true` \| `false` | -| PatchXml | If PATCH operations should explicitly support XML-patch. | `false` | `true` \| `false` | -| PatchFhir | If PATCH operations should explicitly support FHIR types. | `true` | `true` \| `false` | -| SearchSupport | Supported search methods. | `both` | `both` \| `get` \| `post` \| `none` | -| SearchPostParams | Where search params should appear in post-based search. | `body` | `body` \| `query` \| `both` \| `none` | -| History | If _history GET operations should be included. | `false` | `true` \| `false` | -| Metadata | If the JSON should include a link to /metadata. | `true` | `true` \| `false` | -| BundleOperations | If the generator should include /Bundle, etc.. | `true` | `true` \| `false` | -| ReadOnly | If the output should only contain GET operations. | `false` | `true` \| `false` | -| WriteOnly | If the output should only contain POST/PUT/DELETE operations. | `false` | `true` \| `false` | -| Descriptions | If properties should include descriptions. | `true` | `true` \| `false` | -| DescriptionMaxLen | Maximum length of descriptions, if being validated. | `60` | Positive Integer values | -| DescriptionValidation | If descriptions are required and should be validated. | `false` | `true` \| `false` | -| ExpandProfiles | If types should expand based on allowed profiles. | `true` | `true` \| `false` | -| ExpandReferences | If types should expand through references. | `true` | `true` \| `false` | -| MaxRecursions | Maximum depth to expand recursions. | `0` | Positive Integer values | -| Minify | If the output JSON should be minified. | `false` | `true` \| `false` | -| OpenApiVersion | Open API version to use. | `2` | `2` \| `3` | -| OperationCase | Case of the first letter of Operation IDs. | `upper` | `upper` \| `lower` | -| RemoveUncommonFields | If the generator should remove some uncommon fields. | `false` | `true` \| `false` | -| Schemas | If schemas should be included. | `true` | `true` \| `false` | -| SchemasInline | If the output should inline all schemas (no inheritance). | `false` | `true` \| `false` | -| SingleResponses | If operations should only include a single response. | `false` | `true` \| `false` | -| Summaries | If responses should include summaries. | `true` | `true` \| `false` | -| Title | Title to use in the Info section. | | \ No newline at end of file diff --git a/docfx/articles/test.md b/docfx/articles/test.md deleted file mode 100644 index bfd670bc1..000000000 --- a/docfx/articles/test.md +++ /dev/null @@ -1,28 +0,0 @@ -# Testing - -Running `dotnet run -p src/fhir-codegen-test-cli/fhir-codegen-test-cli.csproj` launches a full build and test. - -It will generate updated CSharpBasic and TypeScript files for FHIR Versions DSTU2, STU3, R4, and R5 (May 2020). It will then run each through a build process (requires `dotnet` and `tsc`) to validate there are no syntax errors in any of the generated files. - -Note that this test takes several minutes to run. - -## Usage -``` -fhir-codegen-test-cli: - The FHIR CodeGen Test CLI. - -Usage: - fhir-codegen-test-cli [options] - -Options: - --repo-root-path The path to the repository root (if not CWD). - --verbose True to display all output - (default: false) - --fixed-format-statistics True to output *only* test run statistics: - #run[tab]#passed[tab]#failed[tab]#skipped - (default: false) - --errors-to-std-error True to write errors to stderr instead of stdout. - (default: False) - --version Show version information - -?, -h, --help Show help and usage information -``` diff --git a/docfx/articles/toc.yml b/docfx/articles/toc.yml deleted file mode 100644 index 031ed241a..000000000 --- a/docfx/articles/toc.yml +++ /dev/null @@ -1,12 +0,0 @@ -- name: Introduction - href: intro.md -- name: Export Languages - href: languages.md -- name: Extending - href: extending.md -- name: Blazor UI - href: blazorui.md -- name: Command Line - href: cli.md -- name: Testing - href: test.md diff --git a/docfx/docfx.json b/docfx/docfx.json index 767e6c036..d2db5ecd7 100644 --- a/docfx/docfx.json +++ b/docfx/docfx.json @@ -3,7 +3,16 @@ { "src": [ { - "files": ["**.csproj"], + "files": [ + "Fhir.CodeGen.Common/Fhir.CodeGen.Common.csproj", + "Fhir.CodeGen.Packages/Fhir.CodeGen.Packages.csproj", + "Fhir.CodeGen.CrossVersionLoader/Fhir.CodeGen.CrossVersionLoader.csproj", + "Fhir.CodeGen.MappingLanguage/Fhir.CodeGen.MappingLanguage.csproj", + "Fhir.CodeGen.LangSQLite/Fhir.CodeGen.LangSQLite.csproj", + "Fhir.CodeGen.Lib/Fhir.CodeGen.Lib.csproj", + "Fhir.CodeGen.Comparison/Fhir.CodeGen.Comparison.csproj", + "Fhir.CodeGen.CrossVersionExporter/Fhir.CodeGen.CrossVersionExporter.csproj" + ], "src": "../src" } ], @@ -22,11 +31,17 @@ }, { "files": [ - "articles/**.md", - "articles/**/toc.yml", - "toc.yml", + "**/*.md", + "**/toc.yml" + ], + "src": "../docs" + }, + { + "files": [ "*.md" - ] + ], + "src": "cli-generated", + "dest": "articles" } ], "resource": [ @@ -36,18 +51,17 @@ ] } ], - "overwrite": [ - { - "files": [ - "apidoc/**.md" - ], - "exclude": [ - "obj/**", - "_site/**" - ] - } - ], "dest": "_site", + "globalMetadata": { + "_appTitle": "fhir-codegen", + "_appFooter": "fhir-codegen", + "_enableSearch": true, + "_disableContribution": false, + "_gitContribute": { + "repo": "https://github.com/FHIR/fhir-codegen", + "branch": "main" + } + }, "globalMetadataFiles": [], "fileMetadataFiles": [], "template": [ @@ -60,4 +74,4 @@ "cleanupCacheHistory": false, "disableGitFeatures": false } -} \ No newline at end of file +} diff --git a/docfx/index.md b/docfx/index.md deleted file mode 100644 index 3a9205c2d..000000000 --- a/docfx/index.md +++ /dev/null @@ -1,184 +0,0 @@ -# fhir-codegen - -A .Net library and related utilities to work with FHIR specifications. - -# Documentation - -Detailed documentation can be found on the [documentation site](https://microsoft.github.io/fhir-codegen/). - -# Projects in this Repository - -Project source code is hosted on [GitHub](https://github.com/microsoft/fhir-codegen). - -All projects are currently built on .Net 6.0 and tested on multiple platforms, though Windows is the primary development platform. The .Net 6.0 SDK and runtimes are available for free from [Microsoft](https://dotnet.microsoft.com/en-us/download). - -## Microsoft.Health.Fhir.CodeGenCommon - -This project is a class library that contains the common (normalized) models used in these projects. The project is lightweight and used to ensure that additional projects (e.g., a WASM UI) have access to all the models. - -Detailed information about the models can be found in the [Common Models Documentation](/fhir-codegen/api/Microsoft.Health.Fhir.CodeGenCommon.Models.html). - -## Microsoft.Health.Fhir.SpecManager - -This project is a class library that contains the logic used in the various projects. For example, this project contains the code to: -* download packages, -* resolve canonical URLs, -* normalize different versions of FHIR, -* read metadata (CapabilityStatement or Conformance) from FHIR servers, -* compare packages or artifacts, -* convert normalized models into language-specific models, -* etc. - -More information about this project can be found in the [API Documentation](/fhir-codegen/api/index.html). - -### Export Languages - -The projects in this repository can be used to translate FHIR packages (core or IG) into other forms - e.g., programming language definitions (C#, TypeScript, etc.), or data files for consumption (Info, Cytoscape, etc.). - -More information about current languages can be found on the [Export Languages Page](/fhir-codegen/articles/languages.html). Information about adding new languages can be found on the [Extending Page](/fhir-codegen/articles/extending.html). - - -## FhirCodeGenBlazor - -This project is a server-side Blazor application that can be used to interact with the code-generation library. Generally, it can: -* manage the FHIR Package Cache (`~/.fhir`) - add/update/remove packages -* browse package artifacts -* search across element information (e.g., resource/logical models elements) -* compare packages or artifacts (Diff Tool) -* perform exports -* etc. - -To run this project from a command line: -* `dotnet run --project src/FhirCodeGenBlazor/FhirCodeGenBlazor.csproj` -or, you can build a release version to run: -* `dotnet build src/FhirCodeGenBlazor/FhirCodeGenBlazor.csproj -c Release` -* `dotnet ./src/FhirCodeGenBlazor/bin/Release/net6.0/FhirCodeGenBlazor.dll` - -More information about this project can be found in the [Blazor UI Documentation](/fhir-codegen/articles/blazorui.html). - - -## fhir-codegen-cli - -This project is a command-line application that can be used to perform export operations (e.g., for CI Pipelines). Generally, it can: -* manage the FHIR Package Cache (`~/.fhir`) - add/update packages -* perform exports / transforms of FHIR packages - -To run this project from a command line: -* `dotnet run --project src/fhir-codegen-cli/fhir-codegen-cli.csproj -- [options]` -or, you can build a release version to run: -* `dotnet build src/fhir-codegen-cli/fhir-codegen-cli.csproj -c Release` -* `dotnet ./src/fhir-codegen-cli/bin/Release/net6.0/fhir-codegen-cli.dll` - -``` -Usage: - fhir-codegen-cli [options] - -Options: - -o, --output-path File or directory to write output. - --package-directory The path to a local directory for FHIR packages, if different than the default - FHIR cache (~/.fhir); e.g., (.../fhirPackages)). - -l, --language Name of the language to export (default: Info|TypeScript|CSharpBasic). - --language-help Display languages and their options. [default: False] - --language-options, --opts Language specific options, see documentation for more details. Example: - Lang1|opt=a|opt2=b|Lang2|opt=tt|opt3=oo. - --language-input-dir The full path to a local directory to pass additional content to languages. - --offline-mode Offline mode (will not download missing packages). [default: False] - -k, --export-keys '|' separated list of items to export (not present to export everything). - --official-expansions-only Set to restrict value-sets to only official expansions. [default: False] - --experimental, --include-experimental If the output should include structures marked experimental. [default: False] - --export-types, --types Types of FHIR structures to export (primitive|complex|resource| - interaction|enum), default is all. - --extension-support The level of extensions to include (none|official|officialNonPrimitive| - nonPrimitive|all), default is nonPrimitive. - --fhir-server-url, --server FHIR Server URL to pull a CapabilityStatement or Conformance from. The server - must provide application/fhir+json support. - -p, --packages '|' separated list of packages, with or without version numbers, - e.g., hl7.fhir.r4.core#4.0.1|hl7.fhir.us.core#latest. - --load-DSTU2, --load-r2 If FHIR DSTU2 should be loaded, which version (e.g., 1.0.2 or latest) - --load-r3, --load-STU3 If FHIR STU3 should be loaded, which version (e.g., 3.0.2 or latest) - --load-r4 If FHIR R4 should be loaded, which version (e.g., 4.0.1 or latest) - --load-r4b If FHIR R4B should be loaded, which version (e.g., 4.3.0 or latest) - --load-r5 If FHIR R5 should be loaded, which version (e.g., 5.0.0-ballot or latest) - --ci-branch If loading from the CI server, the name of the branch to use. - -v, --verbose Show verbose output. [default: False] - --version Show version information - -?, -h, --help Show help and usage information -``` - -More information about this project can be found in the [Command Line Documentation](/fhir-codegen/articles/cli.html). - -### Examples - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a TypeScript file in the current directory - * `fhir-codegen-cli -p hl7.fhir.r4#latest --language TypeScript --output-path ./R4.ts` - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a TypeScript file in the current directory, restricted to just the Resources: Patient, Encounter, and Observation - * `fhir-codegen-cli --load-r4 latest --language TypeScript --output-path ./R4.ts --export-keys Patient|Encounter|Observation` - -* Download and parse the latest published version of each FHIR release into the user FHIR cache, then build a C# file for each in ./cs - * `fhir-codegen-cli --load-r2 latest --load-r3 latest --load-r4 latest --load-r5 latest --language CSharpBasic --output-path ./cs` - -* Download and parse FHIR R4 (latest published version) into the user FHIR cache, then build a C# file in the current directory using the namespace: MyOrg.MyProject.Fhir - * `fhir-codegen-cli -p hl7.fhir.r4#latest --language CSharpBasic --output-path ./cs/R4.cs --language-options CSharpBasic|namespace=MyOrg.MyProject.Fhir` - -## fhir-codegen-test-cli - -This project is a **minimal** test harness for generated TypeScript and CSharp code. It can be used to ensure that the core parsing and generation is working properly, and potentially as an example for other language outputs. - -To run this project from a command line: -* `dotnet run --project src/fhir-codegen-test-cli/fhir-codegen-test-cli.csproj -- [options]` - -It will use generated CSharpBasic and TypeScript files for FHIR Versions DSTU2, STU3, R4, and R5. It will then run each through a build process (requires `dotnet` for C# and `tsc` for TypeScript) to validate there are no syntax errors in any of the generated files. - -Note that this test takes several minutes to run. - -### Usage -``` -fhir-codegen-test-cli: - The FHIR CodeGen Test CLI. - -Usage: - fhir-codegen-test-cli [options] - -Options: - --repo-root-path The path to the repository root (if not CWD). - --verbose True to display all output (default: false) - --fixed-format-statistics True to output *only* test run statistics: - #run[tab]#passed[tab]#failed[tab]#skipped - (default: false) - --errors-to-std-error True to write errors to stderr instead of stdout. - (default: False) - --version Show version information - -?, -h, --help Show help and usage information -``` - -### Requirements - -In order to run TypeScript tests, the system must be able to find the 'tsc' (TypeScript compile) command. Note that it must be installed and accessible by the test application (e.g., `npm install -g typescript`). - -# fhirCsR2 - -This is a library project used to isolate the FHIR DSTU2 definitions. All other versions of FHIR are dynamically parsed, but there has not been justification to port this forward - no technical corrections for DSTU2 are expected, so this is *mostly* considered legacy. - -# Pre-Generated Files - -The `generated` directory has static outputs for each of the supported versions of FHIR, in some of the supported languages. These files are used to validate changes to the core loading and parsing, but may be useful otherwise. - - -# Contributing - -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. - -When you submit a pull request, a CLA bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -# Trademarks - -FHIR® is the registered trademark of HL7 and is used under Community Project guidelines. This project is not affiliated with, or approved or sponsored by, HL7. diff --git a/docfx/toc.yml b/docfx/toc.yml deleted file mode 100644 index 59f801047..000000000 --- a/docfx/toc.yml +++ /dev/null @@ -1,5 +0,0 @@ -- name: Articles - href: articles/ -- name: Api Documentation - href: api/ - homepage: api/index.md diff --git a/docs/articles/extending.md b/docs/articles/extending.md index f5f49942e..9fc78180d 100644 --- a/docs/articles/extending.md +++ b/docs/articles/extending.md @@ -59,9 +59,9 @@ discovers it via reflection, and the CLI surfaces it as a The `[ConfigOption]` attribute is consumed by helper code that binds parsed arguments back onto the strongly-typed properties of the options class. The `ConfigurationOption` static is what - [`LaunchUtils.BuildCliOptions`](xref:fhir_codegen_shared.LaunchUtils) - walks to build the actual `System.CommandLine.Option` tree - handed to the parser. + `LaunchUtils.BuildCliOptions` (in the `fhir-codegen-shared` shared + project) walks to build the actual `System.CommandLine.Option` + tree handed to the parser. The two-surface pattern is **deliberate** today, but it is also a known drift risk: if you add a new flag and forget to define its diff --git a/docs/articles/packages-resolution.md b/docs/articles/packages-resolution.md index 50125d461..3a0d35c93 100644 --- a/docs/articles/packages-resolution.md +++ b/docs/articles/packages-resolution.md @@ -918,7 +918,7 @@ version = {tools version number} ... ``` -### INI - version.info +### INI - version.info Source: FHIR Core build - `https://build.fhir.org/version.info` diff --git a/docs/index.md b/docs/index.md index ef1b9c156..889aade3e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -54,8 +54,9 @@ are excluded from the API reference on this site. `FhirSanitizationUtils` reference for code-generator authors. - [FHIR Package Resolution](articles/packages-resolution.md) — how package directives are parsed and resolved across registries. -- [API Reference](api/index.md) — XMLDoc-driven API for the - `Fhir.CodeGen.*` library set. +- [API Reference](xref:Fhir.CodeGen.Lib.Loader.PackageLoader) — + XMLDoc-driven API for the `Fhir.CodeGen.*` library set; browse via + the **API Documentation** tab. ## Source diff --git a/docs/toc.yml b/docs/toc.yml index 4f8cc531a..6b3586c8e 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -2,6 +2,3 @@ href: articles/ - name: Specifications href: specs/ -- name: API Documentation - href: api/ - homepage: api/index.md diff --git a/src/Fhir.CodeGen.Lib/Loader/PackageLoader.cs b/src/Fhir.CodeGen.Lib/Loader/PackageLoader.cs index a9da4071e..a2ce2f4f4 100644 --- a/src/Fhir.CodeGen.Lib/Loader/PackageLoader.cs +++ b/src/Fhir.CodeGen.Lib/Loader/PackageLoader.cs @@ -1520,7 +1520,7 @@ public static (object?, FhirJsonException?) LocalPrimitiveParseHandler( /// - /// Releases the unmanaged resources used by the + /// Releases the unmanaged resources used by the /// and optionally releases the managed resources. /// /// True to release both managed and unmanaged resources; false to diff --git a/src/Fhir.CodeGen.Lib/Net/ServerConnector.cs b/src/Fhir.CodeGen.Lib/Net/ServerConnector.cs index bd96d2cae..225d3cbf9 100644 --- a/src/Fhir.CodeGen.Lib/Net/ServerConnector.cs +++ b/src/Fhir.CodeGen.Lib/Net/ServerConnector.cs @@ -822,7 +822,7 @@ private bool TryGetFhirJson(string url, out HttpStatusCode statusCode, out strin } /// - /// Releases the unmanaged resources used by the + /// Releases the unmanaged resources used by the /// and optionally releases the managed resources. /// /// True to release both managed and unmanaged resources; false to diff --git a/src/Fhir.CodeGen.Packages/Models/PackageManifest.cs b/src/Fhir.CodeGen.Packages/Models/PackageManifest.cs index 56b5fdd3b..be7da1d4d 100644 --- a/src/Fhir.CodeGen.Packages/Models/PackageManifest.cs +++ b/src/Fhir.CodeGen.Packages/Models/PackageManifest.cs @@ -86,7 +86,7 @@ public required string Version /// e.g., `(ISC OR GPL-3.0)` /// See: https://spdx.dev/specifications/ /// If the license is not listed in the SPDX license list, it can be a link to a license file - /// i.e., `SEE LICENSE IN ` + /// i.e., `SEE LICENSE IN <filename>` /// If the package is not licensed, use `UNLICENSED`. /// [JsonPropertyName("license")] diff --git a/src/Fhir.CodeGen.Packages/Models/RegistryCatalogRecord.cs b/src/Fhir.CodeGen.Packages/Models/RegistryCatalogRecord.cs index 5014bfbf6..221bade48 100644 --- a/src/Fhir.CodeGen.Packages/Models/RegistryCatalogRecord.cs +++ b/src/Fhir.CodeGen.Packages/Models/RegistryCatalogRecord.cs @@ -19,7 +19,7 @@ namespace Fhir.CodeGen.Packages.Models; /// Note that the registries use different casing conventions for property names and include different properties. /// /// -/// Source: http://packages.fhir.org/catalog?op=find&name=hl7.fhir.uv.subscriptions&pkgcanonical=&canonical=&fhirversion +/// Source: http://packages.fhir.org/catalog?op=find&name=hl7.fhir.uv.subscriptions&pkgcanonical=&canonical=&fhirversion /// /// [ /// { @@ -40,7 +40,7 @@ namespace Fhir.CodeGen.Packages.Models; /// ] /// /// -/// Source: http://packages2.fhir.org/catalog?op=find&name=hl7.fhir.uv.subscriptions&pkgcanonical=&canonical=&fhirversion= +/// Source: http://packages2.fhir.org/catalog?op=find&name=hl7.fhir.uv.subscriptions&pkgcanonical=&canonical=&fhirversion= /// /// [ /// { From 1cd2da54fc43c71f913b955e405fc655414d0b46 Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Wed, 6 May 2026 11:15:35 -0500 Subject: [PATCH 5/8] feat(cli): add 'docs cli' subcommand that emits live CLI markdown Phase 3 of the docs-site restoration plan. Adds a new top-level 'docs' command with a 'cli' sub-command that walks the same _commands + GetOptions() pipeline the parser uses, then writes a structured Markdown page describing every enabled command, sub-command, language, and option. Because it shares a data source with the parser, the page cannot drift from the shipped binary. Changes: - LaunchUtils._commands gains a 'docs' entry (ConfigDocs config, 'cli' sub-command). LaunchCommandRecord is promoted from private to internal so the emitter can iterate it. Adds an internal EnabledCommands enumerable matching the parser's filter (!Disabled) and ordering (by Literal, ordinal). - ConfigDocs : ConfigRoot exposes a single --output option, defaulting to docs/articles/cli.md. - CliDocEmitter (shared project) renders global options, per-command option tables, language sub-command tables, and manual sub-command lists; writes UTF-8 (no BOM) with a trailing newline. - Program.cs routes 'docs' to a new DoDocs handler. - The shared project's .projitems gains CliDocEmitter.cs so any CLI variant picks it up. - fhir-codegen.csproj exposes internals to the new test project via InternalsVisibleTo. - New src/fhir-codegen.Tests project (xUnit + Shouldly, mirrors Fhir.CodeGen.Lib.Tests style); added to fhir-codegen.sln. - Four CliDocEmitterTests cover language coverage, command coverage (including the sql-is-excluded invariant), TypeScript option drift, and the UTF-8/no-BOM/trailing-newline file contract. Default emitter output is docs/articles/cli.md (gitignored via the new docs/.gitignore). Writing into the docs source root keeps DocFX's filesystem-based cross-link checker happy: every '[cli](cli.md)' link in articles/ now resolves cleanly, and 'docfx --warningsAsErrors' exits 0 (the only warnings remaining are pre-existing CS warnings from the metadata compile, which docfx does not promote). The earlier docfx/cli-generated/ content root is removed from docfx.json. All 211 tests in 'dotnet test fhir-codegen.sln --filter "RequiresExternalRepo!=true"' pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docfx/.gitignore | 1 - docfx/docfx.json | 7 - docs/.gitignore | 2 + fhir-codegen.sln | 133 ++++++++ .../Configuration/ConfigDocs.cs | 66 ++++ src/fhir-codegen-shared/CliDocEmitter.cs | 290 ++++++++++++++++++ src/fhir-codegen-shared/LaunchUtils.cs | 30 +- .../fhir-codegen-shared.projitems | 1 + src/fhir-codegen.Tests/CliDocEmitterTests.cs | 88 ++++++ .../fhir-codegen.Tests.csproj | 33 ++ src/fhir-codegen/Program.cs | 48 +++ src/fhir-codegen/fhir-codegen.csproj | 4 + 12 files changed, 694 insertions(+), 9 deletions(-) create mode 100644 docs/.gitignore create mode 100644 src/Fhir.CodeGen.Lib/Configuration/ConfigDocs.cs create mode 100644 src/fhir-codegen-shared/CliDocEmitter.cs create mode 100644 src/fhir-codegen.Tests/CliDocEmitterTests.cs create mode 100644 src/fhir-codegen.Tests/fhir-codegen.Tests.csproj diff --git a/docfx/.gitignore b/docfx/.gitignore index 8604ef0be..9e6226d1f 100644 --- a/docfx/.gitignore +++ b/docfx/.gitignore @@ -7,4 +7,3 @@ /**/bin/ /**/obj/ _site -cli-generated/ diff --git a/docfx/docfx.json b/docfx/docfx.json index d2db5ecd7..00b3341d9 100644 --- a/docfx/docfx.json +++ b/docfx/docfx.json @@ -35,13 +35,6 @@ "**/toc.yml" ], "src": "../docs" - }, - { - "files": [ - "*.md" - ], - "src": "cli-generated", - "dest": "articles" } ], "resource": [ diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..fccaeda26 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +# Auto-generated by `fhir-codegen docs cli` at build time. +articles/cli.md diff --git a/fhir-codegen.sln b/fhir-codegen.sln index c1b7f8609..4cc20d7e7 100644 --- a/fhir-codegen.sln +++ b/fhir-codegen.sln @@ -75,68 +75,200 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fhir.CodeGen.Packages.Tests EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fhir.CodeGen.CrossVersionExporter", "src\Fhir.CodeGen.CrossVersionExporter\Fhir.CodeGen.CrossVersionExporter.csproj", "{07198F60-02E3-4332-B352-3B479AF51B73}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "fhir-codegen.Tests", "src\fhir-codegen.Tests\fhir-codegen.Tests.csproj", "{43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Debug|x64.ActiveCfg = Debug|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Debug|x64.Build.0 = Debug|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Debug|x86.ActiveCfg = Debug|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Debug|x86.Build.0 = Debug|Any CPU {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Release|Any CPU.ActiveCfg = Release|Any CPU {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Release|Any CPU.Build.0 = Release|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Release|x64.ActiveCfg = Release|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Release|x64.Build.0 = Release|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Release|x86.ActiveCfg = Release|Any CPU + {45D0F776-8D6E-4C1A-BB14-DDFAA3301EC7}.Release|x86.Build.0 = Release|Any CPU {CC4D5356-BD06-48A8-B329-7C372201549A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CC4D5356-BD06-48A8-B329-7C372201549A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Debug|x64.ActiveCfg = Debug|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Debug|x64.Build.0 = Debug|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Debug|x86.ActiveCfg = Debug|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Debug|x86.Build.0 = Debug|Any CPU {CC4D5356-BD06-48A8-B329-7C372201549A}.Release|Any CPU.ActiveCfg = Release|Any CPU {CC4D5356-BD06-48A8-B329-7C372201549A}.Release|Any CPU.Build.0 = Release|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Release|x64.ActiveCfg = Release|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Release|x64.Build.0 = Release|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Release|x86.ActiveCfg = Release|Any CPU + {CC4D5356-BD06-48A8-B329-7C372201549A}.Release|x86.Build.0 = Release|Any CPU {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Debug|x64.ActiveCfg = Debug|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Debug|x64.Build.0 = Debug|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Debug|x86.ActiveCfg = Debug|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Debug|x86.Build.0 = Debug|Any CPU {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Release|Any CPU.ActiveCfg = Release|Any CPU {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Release|Any CPU.Build.0 = Release|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Release|x64.ActiveCfg = Release|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Release|x64.Build.0 = Release|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Release|x86.ActiveCfg = Release|Any CPU + {83E732A6-79D1-4A39-AC0C-29A3B45AD176}.Release|x86.Build.0 = Release|Any CPU {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Debug|x64.ActiveCfg = Debug|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Debug|x64.Build.0 = Debug|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Debug|x86.ActiveCfg = Debug|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Debug|x86.Build.0 = Debug|Any CPU {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Release|Any CPU.ActiveCfg = Release|Any CPU {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Release|Any CPU.Build.0 = Release|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Release|x64.ActiveCfg = Release|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Release|x64.Build.0 = Release|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Release|x86.ActiveCfg = Release|Any CPU + {BE10F292-4A7F-46A0-B4C9-D64003153DDE}.Release|x86.Build.0 = Release|Any CPU {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Debug|x64.Build.0 = Debug|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Debug|x86.Build.0 = Debug|Any CPU {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Release|Any CPU.ActiveCfg = Release|Any CPU {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Release|Any CPU.Build.0 = Release|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Release|x64.ActiveCfg = Release|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Release|x64.Build.0 = Release|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Release|x86.ActiveCfg = Release|Any CPU + {E2173A90-0BCA-427F-9A6C-E767889A4E9E}.Release|x86.Build.0 = Release|Any CPU {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Debug|x64.ActiveCfg = Debug|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Debug|x64.Build.0 = Debug|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Debug|x86.ActiveCfg = Debug|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Debug|x86.Build.0 = Debug|Any CPU {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Release|Any CPU.ActiveCfg = Release|Any CPU {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Release|Any CPU.Build.0 = Release|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Release|x64.ActiveCfg = Release|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Release|x64.Build.0 = Release|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Release|x86.ActiveCfg = Release|Any CPU + {6BF42D89-F37F-4BDF-B180-B65F18734F86}.Release|x86.Build.0 = Release|Any CPU {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Debug|x64.ActiveCfg = Debug|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Debug|x64.Build.0 = Debug|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Debug|x86.ActiveCfg = Debug|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Debug|x86.Build.0 = Debug|Any CPU {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Release|Any CPU.ActiveCfg = Release|Any CPU {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Release|Any CPU.Build.0 = Release|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Release|x64.ActiveCfg = Release|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Release|x64.Build.0 = Release|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Release|x86.ActiveCfg = Release|Any CPU + {3408FD47-4413-4DD5-B4AC-65D4846E4002}.Release|x86.Build.0 = Release|Any CPU {8327D398-57D6-4C42-978B-E1C416AC6601}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8327D398-57D6-4C42-978B-E1C416AC6601}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Debug|x64.ActiveCfg = Debug|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Debug|x64.Build.0 = Debug|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Debug|x86.ActiveCfg = Debug|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Debug|x86.Build.0 = Debug|Any CPU {8327D398-57D6-4C42-978B-E1C416AC6601}.Release|Any CPU.ActiveCfg = Release|Any CPU {8327D398-57D6-4C42-978B-E1C416AC6601}.Release|Any CPU.Build.0 = Release|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Release|x64.ActiveCfg = Release|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Release|x64.Build.0 = Release|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Release|x86.ActiveCfg = Release|Any CPU + {8327D398-57D6-4C42-978B-E1C416AC6601}.Release|x86.Build.0 = Release|Any CPU {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Debug|x64.ActiveCfg = Debug|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Debug|x64.Build.0 = Debug|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Debug|x86.ActiveCfg = Debug|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Debug|x86.Build.0 = Debug|Any CPU {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Release|Any CPU.Build.0 = Release|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Release|x64.ActiveCfg = Release|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Release|x64.Build.0 = Release|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Release|x86.ActiveCfg = Release|Any CPU + {2E64B1FE-DE11-416F-9996-E8DD730C8AFA}.Release|x86.Build.0 = Release|Any CPU {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Debug|x64.ActiveCfg = Debug|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Debug|x64.Build.0 = Debug|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Debug|x86.ActiveCfg = Debug|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Debug|x86.Build.0 = Debug|Any CPU {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Release|Any CPU.ActiveCfg = Release|Any CPU {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Release|Any CPU.Build.0 = Release|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Release|x64.ActiveCfg = Release|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Release|x64.Build.0 = Release|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Release|x86.ActiveCfg = Release|Any CPU + {C448739F-ADB8-42A2-B678-9C0CF7AEEE8C}.Release|x86.Build.0 = Release|Any CPU {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Debug|x64.ActiveCfg = Debug|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Debug|x64.Build.0 = Debug|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Debug|x86.ActiveCfg = Debug|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Debug|x86.Build.0 = Debug|Any CPU {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Release|Any CPU.Build.0 = Release|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Release|x64.ActiveCfg = Release|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Release|x64.Build.0 = Release|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Release|x86.ActiveCfg = Release|Any CPU + {9E7D3F81-3930-4663-8770-32BAE4EB3828}.Release|x86.Build.0 = Release|Any CPU {2BD398B7-C441-46DC-BD57-DEC173889479}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2BD398B7-C441-46DC-BD57-DEC173889479}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Debug|x64.Build.0 = Debug|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Debug|x86.Build.0 = Debug|Any CPU {2BD398B7-C441-46DC-BD57-DEC173889479}.Release|Any CPU.ActiveCfg = Release|Any CPU {2BD398B7-C441-46DC-BD57-DEC173889479}.Release|Any CPU.Build.0 = Release|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Release|x64.ActiveCfg = Release|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Release|x64.Build.0 = Release|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Release|x86.ActiveCfg = Release|Any CPU + {2BD398B7-C441-46DC-BD57-DEC173889479}.Release|x86.Build.0 = Release|Any CPU {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Debug|x64.ActiveCfg = Debug|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Debug|x64.Build.0 = Debug|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Debug|x86.ActiveCfg = Debug|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Debug|x86.Build.0 = Debug|Any CPU {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Release|Any CPU.Build.0 = Release|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Release|x64.ActiveCfg = Release|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Release|x64.Build.0 = Release|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Release|x86.ActiveCfg = Release|Any CPU + {ADE90431-3242-4A51-BC2D-2431CA2A6DCA}.Release|x86.Build.0 = Release|Any CPU {07198F60-02E3-4332-B352-3B479AF51B73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {07198F60-02E3-4332-B352-3B479AF51B73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Debug|x64.ActiveCfg = Debug|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Debug|x64.Build.0 = Debug|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Debug|x86.ActiveCfg = Debug|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Debug|x86.Build.0 = Debug|Any CPU {07198F60-02E3-4332-B352-3B479AF51B73}.Release|Any CPU.ActiveCfg = Release|Any CPU {07198F60-02E3-4332-B352-3B479AF51B73}.Release|Any CPU.Build.0 = Release|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Release|x64.ActiveCfg = Release|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Release|x64.Build.0 = Release|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Release|x86.ActiveCfg = Release|Any CPU + {07198F60-02E3-4332-B352-3B479AF51B73}.Release|x86.Build.0 = Release|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Debug|x64.ActiveCfg = Debug|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Debug|x64.Build.0 = Debug|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Debug|x86.ActiveCfg = Debug|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Debug|x86.Build.0 = Debug|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Release|Any CPU.Build.0 = Release|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Release|x64.ActiveCfg = Release|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Release|x64.Build.0 = Release|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Release|x86.ActiveCfg = Release|Any CPU + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -147,6 +279,7 @@ Global {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {DEDEA68B-9432-40E9-BB9E-84013AD677E0} {6601332F-A738-4E4E-9ACC-D6A52E4FF6FA} = {DEDEA68B-9432-40E9-BB9E-84013AD677E0} {815EA4C1-B432-44E1-83B6-9CE9FBE41D27} = {6601332F-A738-4E4E-9ACC-D6A52E4FF6FA} + {43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {17802D6E-34A0-472E-9041-76E54F463711} diff --git a/src/Fhir.CodeGen.Lib/Configuration/ConfigDocs.cs b/src/Fhir.CodeGen.Lib/Configuration/ConfigDocs.cs new file mode 100644 index 000000000..70045d82f --- /dev/null +++ b/src/Fhir.CodeGen.Lib/Configuration/ConfigDocs.cs @@ -0,0 +1,66 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. +// + +using Fhir.CodeGen.Lib.Extensions; + +namespace Fhir.CodeGen.Lib.Configuration; + +/// +/// Configuration for the docs top-level command (documentation tooling). +/// +public class ConfigDocs : ConfigRoot +{ + /// The default output path for generated CLI Markdown. + public const string DefaultOutputPath = "docs/articles/cli.md"; + + /// Gets or sets the output path for generated documentation. + [ConfigOption( + ArgName = "--output", + EnvName = "Docs_Output", + ArgArity = "0..1", + Description = "Path to write the generated documentation file.")] + public string OutputPath { get; set; } = DefaultOutputPath; + + private static ConfigurationOption OutputPathParameter { get; } = new() + { + Name = "Docs_Output", + EnvVarName = "Docs_Output", + DefaultValue = DefaultOutputPath, + CliOption = new System.CommandLine.Option("--output", "Path to write the generated documentation file.") + { + Arity = System.CommandLine.ArgumentArity.ZeroOrOne, + IsRequired = false, + }, + }; + + private static readonly ConfigurationOption[] _options = + [ + OutputPathParameter, + ]; + + /// Gets the array of configuration options. + /// An array of configuration option. + public override ConfigurationOption[] GetOptions() + { + return [.. base.GetOptions(), .. _options]; + } + + /// Parses the given parse result into this configuration instance. + /// The parse result. + public override void Parse(System.CommandLine.Parsing.ParseResult parseResult) + { + base.Parse(parseResult); + + foreach (ConfigurationOption opt in _options) + { + switch (opt.Name) + { + case "Docs_Output": + OutputPath = GetOpt(parseResult, opt, OutputPath); + break; + } + } + } +} diff --git a/src/fhir-codegen-shared/CliDocEmitter.cs b/src/fhir-codegen-shared/CliDocEmitter.cs new file mode 100644 index 000000000..400bd661f --- /dev/null +++ b/src/fhir-codegen-shared/CliDocEmitter.cs @@ -0,0 +1,290 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. +// + +using System.CommandLine; +using System.Text; +using Fhir.CodeGen.Common.Models; +using Fhir.CodeGen.Lib.Configuration; +using Fhir.CodeGen.Lib.Language; + +namespace fhir_codegen_shared; + +/// +/// Emits a Markdown description of the live fhir-codegen CLI surface. +/// +/// +/// The emitter walks the same +/// table and pipeline the parser uses, +/// so the generated page cannot drift from the shipped binary. +/// +internal static class CliDocEmitter +{ + private const string AutogeneratedBanner = + ""; + + /// Emits the full CLI documentation page as a Markdown string. + /// The generated Markdown content. + internal static string EmitMarkdown() + { + StringBuilder sb = new(); + + sb.AppendLine(AutogeneratedBanner); + sb.AppendLine(); + sb.AppendLine("# Command Line Usage"); + sb.AppendLine(); + sb.AppendLine("This page is generated directly from the live `fhir-codegen`"); + sb.AppendLine("command tree, so the options listed here exactly match what the"); + sb.AppendLine("shipped binary accepts."); + sb.AppendLine(); + sb.AppendLine("## Synopsis"); + sb.AppendLine(); + sb.AppendLine("```"); + sb.AppendLine("fhir-codegen [global-options] [] [command-options]"); + sb.AppendLine("```"); + sb.AppendLine(); + + // Global options (from ConfigRoot) + sb.AppendLine("## Global options"); + sb.AppendLine(); + sb.AppendLine("These options apply to every command."); + sb.AppendLine(); + AppendOptionsTable(sb, GetConfigOptions(typeof(ConfigRoot), excludeFromType: null)); + + // Top-level commands + foreach (LaunchUtils.LaunchCommandRecord rec in LaunchUtils.EnabledCommands) + { + sb.AppendLine(); + sb.AppendLine($"## {rec.Literal} \u2014 {rec.Description}"); + sb.AppendLine(); + + List commandOptions = + [.. GetConfigOptions(rec.ConfigurationType, rec.ExcludedConfigurationType)]; + + if (commandOptions.Count > 0) + { + sb.AppendLine($"Options for `{rec.Literal}`:"); + sb.AppendLine(); + AppendOptionsTable(sb, commandOptions); + } + else + { + sb.AppendLine($"`{rec.Literal}` has no command-specific options beyond the globals."); + sb.AppendLine(); + } + + // Language sub-commands + if (rec.IncludeLanguageSubCommands) + { + foreach (ILanguage language in LanguageManager.GetLanguages().OrderBy(l => l.Name, StringComparer.OrdinalIgnoreCase)) + { + sb.AppendLine(); + sb.AppendLine($"### {rec.Literal} {language.Name}"); + sb.AppendLine(); + + List langOptions = + [ + .. GetConfigOptions(LanguageManager.ConfigTypeForLanguage(language.Name), excludeFromType: null), + .. GetConfigOptions(rec.ConfigurationType, rec.ExcludedConfigurationType), + ]; + + if (langOptions.Count > 0) + { + AppendOptionsTable(sb, langOptions); + } + else + { + sb.AppendLine($"`{rec.Literal} {language.Name}` exposes no additional options."); + sb.AppendLine(); + } + } + } + + // Manual (literal) sub-commands + if (rec.SubCommands.Length > 0) + { + sb.AppendLine(); + sb.AppendLine($"### Sub-commands of `{rec.Literal}`"); + sb.AppendLine(); + sb.AppendLine("| Sub-command | Description |"); + sb.AppendLine("| --- | --- |"); + foreach ((string literal, string description) in rec.SubCommands) + { + sb.AppendLine($"| `{literal}` | {EscapeTableCell(description)} |"); + } + sb.AppendLine(); + } + } + + return sb.ToString(); + } + + /// Writes the generated Markdown to a UTF-8 (no BOM) file with a trailing newline. + /// The output file path. + /// 0 on success. + internal static async Task WriteToFileAsync(string outputPath) + { + string content = EmitMarkdown(); + + if (!content.EndsWith('\n')) + { + content += "\n"; + } + + string? directory = Path.GetDirectoryName(Path.GetFullPath(outputPath)); + if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + UTF8Encoding utf8NoBom = new(encoderShouldEmitUTF8Identifier: false); + await File.WriteAllTextAsync(outputPath, content, utf8NoBom); + + return 0; + } + + /// + /// Materialises a config object and returns its list, + /// optionally filtering out properties inherited from a base type (mirrors the + /// inheritance-exclusion behaviour of ). + /// + private static IEnumerable GetConfigOptions(Type forType, Type? excludeFromType) + { + if (forType.IsAbstract) + { + yield break; + } + + object? instance = Activator.CreateInstance(forType); + if (instance is not ICodeGenConfig config) + { + yield break; + } + + HashSet excludedNames = []; + if (excludeFromType != null) + { + object? excludeInstance = Activator.CreateInstance(excludeFromType); + if (excludeInstance is ICodeGenConfig excludeConfig) + { + foreach (ConfigurationOption excluded in excludeConfig.GetOptions()) + { + excludedNames.Add(excluded.Name); + } + } + } + + foreach (ConfigurationOption opt in config.GetOptions()) + { + if (excludedNames.Contains(opt.Name)) + { + continue; + } + + yield return opt; + } + } + + private static void AppendOptionsTable(StringBuilder sb, IEnumerable options) + { + List opts = [.. options]; + + if (opts.Count == 0) + { + return; + } + + sb.AppendLine("| Option | Type | Default | Description |"); + sb.AppendLine("| --- | --- | --- | --- |"); + foreach (ConfigurationOption opt in opts.OrderBy(o => o.Name, StringComparer.OrdinalIgnoreCase)) + { + Option cli = opt.CliOption; + + string aliases = cli.Aliases.Count > 0 + ? string.Join(", ", cli.Aliases.OrderBy(a => a.Length).Select(a => $"`{a}`")) + : $"`--{cli.Name}`"; + + string typeName = FormatTypeName(cli.ValueType); + string defaultRendered = RenderDefault(opt.DefaultValue); + string description = string.IsNullOrEmpty(cli.Description) ? string.Empty : EscapeTableCell(cli.Description); + + sb.AppendLine($"| {aliases} | `{typeName}` | {defaultRendered} | {description} |"); + } + sb.AppendLine(); + } + + private static string RenderDefault(object? defaultValue) + { + if (defaultValue is null) + { + return "_(none)_"; + } + + if (defaultValue is string s) + { + return string.IsNullOrEmpty(s) ? "_(empty)_" : $"`{EscapeTableCell(s)}`"; + } + + if (defaultValue is System.Collections.IEnumerable enumerable and not string) + { + List items = []; + foreach (object? item in enumerable) + { + items.Add(item?.ToString() ?? "null"); + } + + return items.Count == 0 + ? "_(empty)_" + : $"`[{string.Join(", ", items)}]`"; + } + + return $"`{EscapeTableCell(defaultValue.ToString() ?? string.Empty)}`"; + } + + private static string FormatTypeName(Type type) + { + if (type == typeof(string)) + { + return "string"; + } + + if (type == typeof(bool)) + { + return "bool"; + } + + if (type == typeof(int)) + { + return "int"; + } + + if (type.IsArray) + { + return $"{FormatTypeName(type.GetElementType()!)}[]"; + } + + if (type.IsGenericType) + { + string genericName = type.Name; + int tickIndex = genericName.IndexOf('`'); + if (tickIndex > 0) + { + genericName = genericName[..tickIndex]; + } + + string args = string.Join(", ", type.GetGenericArguments().Select(FormatTypeName)); + return $"{genericName}<{args}>"; + } + + return type.Name; + } + + private static string EscapeTableCell(string value) + { + return value + .Replace("|", "\\|", StringComparison.Ordinal) + .Replace("\r\n", " ", StringComparison.Ordinal) + .Replace("\n", " ", StringComparison.Ordinal); + } +} diff --git a/src/fhir-codegen-shared/LaunchUtils.cs b/src/fhir-codegen-shared/LaunchUtils.cs index a2338e061..1a2ccc6ee 100644 --- a/src/fhir-codegen-shared/LaunchUtils.cs +++ b/src/fhir-codegen-shared/LaunchUtils.cs @@ -52,7 +52,7 @@ internal record class PropertyOptionTuple public required Option CommandOpt { get; set; } } - private record class LaunchCommandRecord + internal record class LaunchCommandRecord { public required string Literal { get; init; } public required string Description { get; init; } @@ -108,8 +108,28 @@ private record class LaunchCommandRecord ConfigurationType = typeof(ConfigSql), Disabled = true, }, + new() + { + Literal = "docs", + Description = "Documentation tooling.", + ConfigurationType = typeof(ConfigDocs), + SubCommands = [ + ("cli", "Generate Markdown describing the CLI surface."), + ], + }, ]; + /// + /// Gets the enabled top-level commands in the order the parser exposes them. + /// + /// + /// Matches the filter and ordering at + /// (drops entries, sorts by + /// ). + /// + internal static IEnumerable EnabledCommands => + _commands.Where(c => !c.Disabled).OrderBy(c => c.Literal, StringComparer.Ordinal); + /// Parses the configuration based on the provided command and parse result. /// Thrown when the language type cannot be found, the configuration /// object cannot be created, or the configuration type does not implement @@ -193,6 +213,14 @@ internal static ICodeGenConfig ParseConfig( }; break; + case "docs": + config = new ConfigDocs() + { + LaunchCommand = command, + LogFactory = loggerFactory ?? LoggerFactory.Create(builder => builder.AddConsole()), + }; + break; + case "help": default: config = new ConfigRoot() diff --git a/src/fhir-codegen-shared/fhir-codegen-shared.projitems b/src/fhir-codegen-shared/fhir-codegen-shared.projitems index 2abb9a3c8..99a7a4a98 100644 --- a/src/fhir-codegen-shared/fhir-codegen-shared.projitems +++ b/src/fhir-codegen-shared/fhir-codegen-shared.projitems @@ -9,6 +9,7 @@ fhir_codegen_shared + \ No newline at end of file diff --git a/src/fhir-codegen.Tests/CliDocEmitterTests.cs b/src/fhir-codegen.Tests/CliDocEmitterTests.cs new file mode 100644 index 000000000..03ac44ebb --- /dev/null +++ b/src/fhir-codegen.Tests/CliDocEmitterTests.cs @@ -0,0 +1,88 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. +// + +using System.Text; +using Fhir.CodeGen.Lib.Language; +using fhir_codegen_shared; +using Shouldly; +using Xunit; + +namespace fhir_codegen.Tests; + +public class CliDocEmitterTests +{ + [Fact] + public void EmitMarkdown_ContainsAllRegisteredLanguages() + { + string markdown = CliDocEmitter.EmitMarkdown(); + + foreach (ILanguage language in LanguageManager.GetLanguages()) + { + string expectedHeading = $"### generate {language.Name}"; + markdown.ShouldContain(expectedHeading); + } + } + + [Fact] + public void EmitMarkdown_ContainsAllEnabledCommands() + { + string markdown = CliDocEmitter.EmitMarkdown(); + + foreach (LaunchUtils.LaunchCommandRecord rec in LaunchUtils.EnabledCommands) + { + markdown.ShouldContain($"## {rec.Literal} "); + } + + // sql is Disabled = true and must not appear. + markdown.ShouldNotContain("## sql "); + } + + [Fact] + public void EmitMarkdown_RendersOptionsForGenerateTypeScript() + { + string markdown = CliDocEmitter.EmitMarkdown(); + + // Pin down well-known TypeScript options to catch drift between the + // emitter and the live BuildCliOptions output. + markdown.ShouldContain("--namespace"); + markdown.ShouldContain("--min-ts-version"); + markdown.ShouldContain("--inline-enums"); + } + + [Fact] + public async Task WriteToFileAsync_WritesUtf8NoBomWithTrailingNewline() + { + string tempPath = Path.Combine(Path.GetTempPath(), $"fhir-codegen-cli-doc-{Guid.NewGuid():N}.md"); + + try + { + int code = await CliDocEmitter.WriteToFileAsync(tempPath); + code.ShouldBe(0); + + File.Exists(tempPath).ShouldBeTrue(); + + byte[] bytes = await File.ReadAllBytesAsync(tempPath); + bytes.Length.ShouldBeGreaterThan(0); + + // No UTF-8 BOM (EF BB BF). + bool hasBom = bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF; + hasBom.ShouldBeFalse(); + + // Trailing newline. + bytes[^1].ShouldBe((byte)'\n'); + + // Content round-trips as UTF-8. + string roundTripped = Encoding.UTF8.GetString(bytes); + roundTripped.ShouldContain("# Command Line Usage"); + } + finally + { + if (File.Exists(tempPath)) + { + File.Delete(tempPath); + } + } + } +} diff --git a/src/fhir-codegen.Tests/fhir-codegen.Tests.csproj b/src/fhir-codegen.Tests/fhir-codegen.Tests.csproj new file mode 100644 index 000000000..93c78ffae --- /dev/null +++ b/src/fhir-codegen.Tests/fhir-codegen.Tests.csproj @@ -0,0 +1,33 @@ + + + + + net9.0 + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/src/fhir-codegen/Program.cs b/src/fhir-codegen/Program.cs index b66ae93e9..ca1f78a3b 100644 --- a/src/fhir-codegen/Program.cs +++ b/src/fhir-codegen/Program.cs @@ -111,10 +111,58 @@ public static async Task Main(string[] args) //"interactive" => await DoInteractive(pr, command, subCommand); //"web" => await DoWeb(pr, command, subCommand); "sql" => await DoSql(pr, command, subCommand), + "docs" => await DoDocs(pr, command, subCommand), _ => await parser.InvokeAsync(args), }; } + /// Executes the docs command. + /// The parse result. + /// The top-level command name (always docs). + /// The sub-command name (e.g. cli). + /// The exit code (0 on success). + public static async Task DoDocs(ParseResult pr, string command, string? subCommand) + { + try + { + if (subCommand == null) + { + Console.WriteLine("Error: docs command requires a sub-command (e.g. 'cli')."); + return 1; + } + + ICodeGenConfig config = ParseConfig(pr, command, subCommand); + + if (config is not ConfigDocs docsConfig) + { + throw new Exception("Config type must inherit from ConfigDocs"); + } + + switch (subCommand) + { + case "cli": + { + string outputPath = Path.GetFullPath(docsConfig.OutputPath); + int code = await fhir_codegen_shared.CliDocEmitter.WriteToFileAsync(outputPath); + if (code == 0) + { + Console.WriteLine($"Wrote CLI documentation to: {outputPath}"); + } + return code; + } + + default: + Console.WriteLine($"Error: unknown docs sub-command '{subCommand}'."); + return 1; + } + } + catch (Exception ex) + { + Console.WriteLine($"DoDocs <<< caught: {ex.Message}"); + return 1; + } + } + public static async Task DoGenerate(ParseResult pr, string command, string? subCommand) { try diff --git a/src/fhir-codegen/fhir-codegen.csproj b/src/fhir-codegen/fhir-codegen.csproj index 4353d412e..d87c152fb 100644 --- a/src/fhir-codegen/fhir-codegen.csproj +++ b/src/fhir-codegen/fhir-codegen.csproj @@ -30,6 +30,10 @@ + + + + From 915464aa75127eb12431d8a87c681274e44fe3a3 Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Wed, 6 May 2026 11:20:59 -0500 Subject: [PATCH 6/8] chore: scrub microsoft/fhir-codegen URL references; add docs site metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4 of the docs-site restoration plan. The repo moved from microsoft/fhir-codegen to FHIR/fhir-codegen; this scrubs the remaining old URL references and points NuGet metadata at the new docs site. - fhir-codegen.props: now points at FHIR/fhir-codegen, and a new points at the published docs site (https://fhir.github.io/fhir-codegen/) so the 'Project URL' link on nuget.org takes consumers to the curated landing page rather than duplicating the source-discovery role of . - README.md: replaces the stale 'Apologies - the documentation for this project is currently quite stale… Soon(TM)' paragraph with a real Documentation section pointing at fhir.github.io and a brief summary of what's there. - CHANGELOG.md: under '### CURRENT', adds the docs-site-restoration note. The pre-existing 'Migrated from Microsoft/fhir-codegen to FHIR/fhir-codegen.' line is left intact as it documents the historical migration. - ShorthandIG.cs: the embedded generation-note URL is updated from microsoft/fhir-codegen to FHIR/fhir-codegen. - CrossVersionResolver.cs: matching comment URL update. Verification: - 'grep -rn microsoft/fhir-codegen' (excluding .git, scratch, bin, obj) returns zero hits, modulo the historical CHANGELOG migration line which intentionally records the rename. - 'dotnet build fhir-codegen.sln -c Release' is green. - 'dotnet test ... --filter "RequiresExternalRepo!=true"' baseline behaviour is unchanged: TestFirelyHashesR5(Conformance) was already failing before this change (verified by temporarily stashing the URL edits) and remains failing for the same pre-existing reason; all other 210/211 tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 1 + README.md | 13 ++++++++++--- fhir-codegen.props | 3 ++- src/Fhir.CodeGen.Lib.Tests/CrossVersionResolver.cs | 2 +- .../Language/Shorthand/ShorthandIG.cs | 2 +- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48c0a13b8..f31e8e2f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### CURRENT * Migrated from Microsoft/fhir-codegen to FHIR/fhir-codegen. +* Documentation site restored at https://fhir.github.io/fhir-codegen/. --- diff --git a/README.md b/README.md index 37735bfac..a6d965690 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,16 @@ To ensure a welcoming environment, we follow the [HL7 Code of Conduct](https://w # Documentation -Apologies - the documentation for this project is currently quite stale and was causing more issues than solving. - -Documentation updates are in progress, and will be updated Soon(TM). +Documentation is published at **** +and includes an introduction to the project, a guide to the supported +output languages, the cross-version mapping pipeline, the auto-generated +command-line reference, and the XMLDoc-driven API reference for the +`Fhir.CodeGen.*` library set. + +The site is rebuilt from `main` on every push by +[`.github/workflows/docs.yaml`](.github/workflows/docs.yaml). Local docs +authoring lives under [`docs/`](docs/); the build configuration lives +under [`docfx/`](docfx/). # Trademarks diff --git a/fhir-codegen.props b/fhir-codegen.props index ff9f3fd8f..15d9b39a0 100644 --- a/fhir-codegen.props +++ b/fhir-codegen.props @@ -14,7 +14,8 @@ Microsoft Corporation Copyright 2019-2026 git - https://github.com/Microsoft/fhir-codegen + https://github.com/FHIR/fhir-codegen + https://fhir.github.io/fhir-codegen/ en diff --git a/src/Fhir.CodeGen.Lib.Tests/CrossVersionResolver.cs b/src/Fhir.CodeGen.Lib.Tests/CrossVersionResolver.cs index 95e38f1c3..f04be0fb8 100644 --- a/src/Fhir.CodeGen.Lib.Tests/CrossVersionResolver.cs +++ b/src/Fhir.CodeGen.Lib.Tests/CrossVersionResolver.cs @@ -247,7 +247,7 @@ public static string ConvertCanonical(string uri) // http://hl7.org/fhir/StructureDefinition/Account|3.0 // http://hl7.org/fhir/StructureDefinition/Account|3.0.1 // http://hl7.org/fhir/StructureDefinition/Account|4.0.1 - // i.e. https://github.com/microsoft/fhir-codegen/blob/dev/src/Microsoft.Health.Fhir.SpecManager/Manager/FhirPackageCommon.cs#L513 + // i.e. https://github.com/FHIR/fhir-codegen/blob/dev/src/Microsoft.Health.Fhir.SpecManager/Manager/FhirPackageCommon.cs#L513 // TODO: @brianpos - I would recommend using the functions in FhirReleases that I keep up to date with builds and versions diff --git a/src/Fhir.CodeGen.Lib/Language/Shorthand/ShorthandIG.cs b/src/Fhir.CodeGen.Lib/Language/Shorthand/ShorthandIG.cs index 594ad65f9..ca9c4aeac 100644 --- a/src/Fhir.CodeGen.Lib/Language/Shorthand/ShorthandIG.cs +++ b/src/Fhir.CodeGen.Lib/Language/Shorthand/ShorthandIG.cs @@ -378,7 +378,7 @@ private ExportStreamWriter GetCanonicalWriter( private void WriteHeader(ExportStreamWriter writer, string? name = null, string? description = null) { - string generationNote = $"Generated {DateTime.Now.ToString("yyyy-mm-dd HH:mm")} by fhir-codegen: https://github.com/microsoft/fhir-codegen"; + string generationNote = $"Generated {DateTime.Now.ToString("yyyy-mm-dd HH:mm")} by fhir-codegen: https://github.com/FHIR/fhir-codegen"; if (!string.IsNullOrEmpty(name)) { From d4bab01ab5b817d4ea101b61d9fad62cc359c3a8 Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Wed, 6 May 2026 11:22:44 -0500 Subject: [PATCH 7/8] ci(docs): replace docs workflow with modern Pages deploy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 5 of the docs-site restoration plan. Replaces the disabled, Chocolatey-based, upload-artifact@v1 workflow with a current GitHub Pages deploy flow: - Triggers on push to main, pull_request to main, and workflow_dispatch, all narrowed to docs-relevant paths. - Uses ubuntu-latest, dotnet-install, and 'dotnet tool install -g docfx' (no Chocolatey). - Build job restores + builds the solution, runs the new 'fhir-codegen docs cli' emitter to write docs/articles/cli.md, then runs 'docfx --warningsAsErrors' over the freshly populated site source. - Deploy job uses actions/configure-pages@v5 + actions/upload-pages-artifact@v3 + actions/deploy-pages@v4 (the official Pages deploy flow), gated to push events on main only. PR runs validate the build but skip the deploy. - Permissions are scoped to {contents: read, pages: write, id-token: write} per the Pages-deploy contract; concurrency is grouped by 'pages' so successive deploys serialise cleanly. Note: emitter output goes to docs/articles/cli.md (per the Phase 3 deviation), not docfx/cli-generated/cli.md as the original plan sketched. Precondition (cannot be code-reviewed): the FHIR/fhir-codegen repo must have GitHub Pages set to 'Source: GitHub Actions' under Settings → Pages. If it is not, the deploy job's first run will fail with a permissions error; fix is purely a settings change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/docs.yaml | 103 +++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 142ede0d8..8e9074f1b 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -2,55 +2,74 @@ name: Docs on: push: - branches: - - main-disabled + branches: [main] paths: - - src/** - - docfx/** - - .github/workflows/docs.yml + - 'src/**' + - 'docs/**' + - 'docfx/**' + - '.github/workflows/docs.yaml' + pull_request: + branches: [main] + paths: + - 'src/**' + - 'docs/**' + - 'docfx/**' + - '.github/workflows/docs.yaml' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false env: - DOTNET_VERSION: '9' # The .NET SDK version to use + DOTNET_VERSION: '9' jobs: - generate-docs: - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - name: Setup .NET Core - uses: actions/setup-dotnet@v3 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - - name: Setup DocFX - uses: crazy-max/ghaction-chocolatey@v1 - with: - args: install docfx - - - name: DocFX Build - run: docfx ./docfx/docfx.json - continue-on-error: false - - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: site - path: docfx/_site - - deploy: - concurrency: ci-${{ github.ref }} - needs: [generate-docs] + build: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Download Artifact - uses: actions/download-artifact@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 with: - name: site + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Install DocFX + run: dotnet tool install -g docfx + + - name: Restore + build solution (needed for metadata + CLI emitter) + run: dotnet build fhir-codegen.sln -c Release - - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4 + - name: Generate CLI Markdown into docs content path + run: | + dotnet run --no-build --configuration Release \ + --project src/fhir-codegen/fhir-codegen.csproj -- \ + docs cli --output docs/articles/cli.md + + - name: Build site + run: docfx ./docfx/docfx.json --warningsAsErrors + + - name: Configure Pages + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: actions/configure-pages@v5 + + - name: Upload Pages artifact + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@v3 with: - folder: 'site' + path: docfx/_site + + deploy: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 From 72ce9d8fdf831e4e2af6ee3c6afe67ea26d5e3a3 Mon Sep 17 00:00:00 2001 From: Gino Canessa Date: Wed, 6 May 2026 11:23:38 -0500 Subject: [PATCH 8/8] docs(readme): add Pages build status badge for the docs workflow Phase 6 of the docs-site restoration plan. Adds a CI status badge to the README header that links to the new Docs workflow (.github/workflows/docs.yaml, rewritten in Phase 5). The badge will turn green on the first successful 'main' run after the docs workflow is enabled and GitHub Pages is configured to deploy from GitHub Actions. Note: Phase 6's other planned steps (smoke-testing the live site, filing follow-up issues for any link/content gaps surfaced during that smoke-test) require the deploy workflow to actually run on 'main', which is outside the scope of a pre-merge local change. Those steps are tracked as follow-ups in the plan's Progress Log. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a6d965690..12884d428 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # fhir-codegen +[![Docs](https://github.com/FHIR/fhir-codegen/actions/workflows/docs.yaml/badge.svg)](https://github.com/FHIR/fhir-codegen/actions/workflows/docs.yaml) + A .Net application, library, and related utilities to work with FHIR specifications. ## FHIR Foundation Project Statement