From e32c510108a455aae6018dccebe9b5c9e8ad4e9c Mon Sep 17 00:00:00 2001 From: Sean Wheeler Date: Wed, 30 Jul 2025 08:08:15 -0500 Subject: [PATCH] Update v0.14 schema docs and add code design doc --- docs/CODE-LAYOUT.md | 138 +++++++++++++++++++++ docs/platyPS.schema.md | 265 +++++++++++++++++++++-------------------- 2 files changed, 275 insertions(+), 128 deletions(-) create mode 100644 docs/CODE-LAYOUT.md diff --git a/docs/CODE-LAYOUT.md b/docs/CODE-LAYOUT.md new file mode 100644 index 00000000..c0a901cd --- /dev/null +++ b/docs/CODE-LAYOUT.md @@ -0,0 +1,138 @@ +# Contributing to platyPS + +## Get the code + +``` +git clone https://github.com/PowerShell/platyPS +``` + +## Understand code layout + +There are two parts: + +- `Markdown.MAML.dll`, a .NET library written in C#. It does the heavy lifting, like parsing + Markdown, transforming it into XML, and so on. You can open `.\Markdown.MAML.sln` in Visual Studio + on any platform. +- A PowerShell module in `.\src\platyPS`. This module provides the user CLI. + +## Build + +To build the whole project, use the `build.ps1` helper script. It depends on the [dotnet cli][01] +build tool. + +On Windows you would also need to [install full dotnet framework][02] if it's not installed already. + +```powershell +.\build.ps1 +``` + +As part of the build, platyPS generates help for itself. The output of the build is placed in +`out\Microsoft.PowerShell.PlatyPS`. + +`build.ps1` also imports the module from `out\platyPS` and generates help itself. + +> [!NOTE] +> If you changed C# code, `build.ps1` will try to overwrite a DLL in use. You will then need to +> re-open your PowerShell session. If you know a better workflow, please suggest it in the Issues. + +## Tests + +Each part of the project has a test set: + +- The C# part has xUnit tests. You can run them from Visual Studio or from command line with + `dotnet test ./test/Markdown.MAML.Test`. +- The PowerShell part has [Pester][03] tests. You can run them with `Invoke-Pester`. + +> [!NOTE] +> Pester tests always force-import the module from the output location of `.\build.ps1`. + +## Schema + +If you have ideas or concerns about the Markdown schema, feel free to open a GitHub Issue to discuss +it. + +## Repo structure + +- **src\platyPS** - sources to create the final PowerShell module. +- **src\Markdown.MAML, Markdown.MAML.sln** - source code for C# Markdown to MAML converter. +- **[platyPS.schema.md][04]** - description of Markdown that platyPS expects. + +## Data transformations + +Data transformations are the core of platyPS. A user has content in some form and she wants to +transform it into another form. E.g. transform existing module help (in MAML) to Markdown and use it +in the future to generate the external help (MAML) and static HTML for online references. + +platyPS provides APIs in the form of cmdlets for end-user scenarios. These scenarios are assembled +from simple transformations. This chart describes these simple transformations: + +``` + +----------+ + | | + | HTML | + | | + +------^---+ + | + +------+------------+ +-----------------+ + | | | Markdown Model | + | Markdown file +-----------> | + | | +-+---------------+ + | | | + +---------------^---+ | + | | + | | + | | + +--+-----------------v--+ + | MAML Model | + | (= Generic Help model)| + | | + +--+-------------------^+ + | | + | | + | | ++----------------v-----+ ++--------------------------+ +| MAML XML file | | Help Object in PowerShell | +| (External help file) +------------> (+ Get-Command object) | ++----------------------+ +---------------------------+ +``` + +### Example `New-MarkdownHelp` + +A user creates a platyPS Markdown for the first time with `New-MarkdownHelp`: + +```powershell +New-MarkdownHelp -Command New-MyCommandHelp +``` + +Under the hood, the following tranformations happen: + +``` +[MAML XML file] --> [Help Object + Get-Command object] --> [MAML Model] --> [Markdown file] +``` + +# Making a new release + +1. Make sure that `CHANGELOG.md` is up-to-date, move section from `UNRELEASED` to new section + ``. +1. Make sure platyPS help itself (content in .\docs folder) is up to date. + `Update-MarkdownHelp -Path .\docs` should result in no changes. +1. Do not change the version in platyps.psd1. Git tag will update this version for release. +1. From master, tag the release. +1. Push tag to GitHub. +1. Find the corresponding build on AppVeyor. +1. Download ZIP archive with the module from Appveyor's Artifacts tab. +1. Unblock the ZIP archive (`Unblock-File foo.zip`), and copy the ZIP's contents to + `$env:PSMODULEPATH` so it's available to `Publish-Module`. +1. Publish the module to the Gallery: + `Publish-Module -RequiredVersion -Verbose -NuGetApiKey $apiKey`. +1. Check that https://www.powershellgallery.com/packages/platyPS/ updated. +1. Publish a new github release from https://github.com/PowerShell/platyPS/releases to move "Latest + release" label to the new tag. + +Congratulations! You just made a release. + + +[01]: https://docs.microsoft.com/en-us/dotnet/core/tools/ +[02]: https://docs.microsoft.com/en-us/dotnet/framework/install/guide-for-developers +[03]: https://github.com/pester/Pester +[04]: platyPS.schema.md diff --git a/docs/platyPS.schema.md b/docs/platyPS.schema.md index 25b8d7f5..9dd3878a 100644 --- a/docs/platyPS.schema.md +++ b/docs/platyPS.schema.md @@ -5,98 +5,151 @@ It closely resembles output of `Get-Help`. ## Legend -* `{string}` - single-line string value -* `{{text}}` - multi-line text -* `//` - line comment in schema -* tabs show the scopes of `// for` statements; they should not be included in the Markdown output. +- `{string}` - single-line string value +- `{{text}}` - multi-line text +- `//` - line comment in schema +- tabs show the scopes of `// for` statements; they should not be included in the Markdown output. ### Version 2.0.0 - - // Every cmdlet help placed in it's own `Command-Name.md` file in one folder. - // We sometimes reference to this folder as "HelpModule". - - // Top-level metadata. You can put your own "key: value" statements there - // unknown values would be ignored by platyPS - // You can query this data from markdown file with `Get-MarkdownMetadata` - // - // Keys that have meaning for platyPS have separate entries - --- - schema: 2.0.0 - external help file: {file name for `New-ExternalHelp`}.xml - online version: {url for `Get-Help -Online`} - applicable: {comma-separated list of tags where this cmdlet exists} // if omitted then applicable for any tag - {{ User-specific key-value pairs }} - --- +``` +// Every cmdlet help placed in it's own `Command-Name.md` file in one folder. +// We sometimes reference to this folder as "HelpModule". + +// Top-level metadata. You can put your own "key: value" statements there +// unknown values would be ignored by platyPS +// You can query this data from markdown file with `Get-MarkdownMetadata` +// +// Keys that have meaning for platyPS have separate entries +--- +schema: 2.0.0 +external help file: {file name for `New-ExternalHelp`}.xml +online version: {url for `Get-Help -Online`} +applicable: {comma-separated list of tags where this cmdlet exists} // if omitted then applicable for any tag +{{ User-specific key-value pairs }} +--- + +# {Command name} + +// following level-2 headers sections can go in any order +// here is the recommended order + +## SYNOPSIS +{{Synopsis text}} + +## SYNTAX +// for each parameter set + ### {Parameter Set Name, if default parameter set, followed by "(Default)"} + // i.e.: FromPath (Default) + // This syntax would be ignored during maml generation. + // syntax would be generated from parameters metadata + ``` + {{Output of Get-Command -Syntax}} + ``` + +## DESCRIPTION +{{Description text}} + +## EXAMPLES +// for every example + ### {Example Name} + + {{Example introduction text}} + + // one or more times, codesnippet + // it's useful to put the ```powershell code + // before the plain text command execution output + ```{Syntax language, i.e. PowerShell or nothing for plain text} + {{Example body}} + ``` + + {{Example remarks}} // not a mandatory, i.e. TechNet articles don't use remarks + +## PARAMETERS + +// for every parameter + // default value is non-mandatory + ### -{Parameter name} + {{Parameter description text. It can also include codesnippets, but they could not be ```yaml}} + + // parameter metadata + // for every unique parameter metadata set + // Note: two Parameter Sets can have the same parameter as mandatory and non-mandatory + // then we put them in two yaml snippets. + // If they have the same metadata, we put them in one yaml snippet. + + ```yaml // this gives us key/value highlighting + Type: {Parameter type} // can be ommitted, then default assumed + Parameter sets: {comma-separated list of names, i.e. "SetName1, SetName2" or "(All)" + for all parameter sets} + Aliases: {comma-separated list of aliases, i.e. EA, ERR} // if ommitted => default + Accepted values: {ValidateSet, comma-separated list of valid values, i.e. Foo, Bar} + // if ommitted => everything is accepted + Applicable: {comma-separated list of tags where this cmdlet exists} + // if omitted then applicable for any tag + // break line to improve readability and separate metadata block + + Required: {true | false} + Position: {1..n} | named + Default value: {None | False (for switch parameters) | the actual default value} + Accept pipeline input: {false | true (ByValue, ByPropertyName)} + Accept wildcard characters: {true | false} + ``` + + // if supports workflow parameters + ### + {{ Workflow common parameters text, would be ignored during maml generation }} + + // if supports common parameters + ### + {{ Common parameters text, would be ignored during maml generation }} + +## INPUTS // for every input type +### {Input type} +{{Description text}} + +## OUTPUTS // for every output type + +### {Output type} +{{Description text}} + +## RELATED LINKS + +// for every link +[{link name}]({link url}) +``` + +### Version 1.0.0 (Deprecated) + +v0.7.6 is the last platyPS version that supports it. + +``` +// for every command: # {Command name} // following level-2 headers sections can go in any order // here is the recommended order - + ## SYNOPSIS {{Synopsis text}} - ## SYNTAX - // for each parameter set - ### {Parameter Set Name, if default parameter set, followed by "(Default)"} - // i.e.: FromPath (Default) - // This syntax would be ignored during maml generation. - // syntax would be generated from parameters metadata - ``` - {{Output of Get-Command -Syntax}} - ``` - ## DESCRIPTION {{Description text}} - ## EXAMPLES - // for every example - ### {Example Name} - - {{Example introduction text}} - - // one or more times, codesnippet - // it's useful to put the ```powershell code - // before the plain text command exectution output - ```{Syntax language, i.e. PowerShell or nothing for plain text} - {{Example body}} - ``` - - {{Example remarks}} // not a mandatory, i.e. TechNet articles don't use remarks - ## PARAMETERS // for every parameter - // default value is non-mandatory - ### -{Parameter name} - {{Parameter description text. It can also include codesnippets, but they could not be ```yaml}} + // type and default value are non-mandatory + ### {Parameter name} [{Parameter type}] = {Parameter default value} // parameter metadata - // for every unique parameter metadata set - // Note: two Parameter Sets can have the same parameter as mandatory and non-mandatory - // then we put them in two yaml snippets. - // If they have the same metadata, we put them in one yaml snippet. - ```yaml // this gives us key/value highlighting - Type: {Parameter type} // can be ommitted, then default assumed - Parameter sets: {comma-separated list of names, i.e. "SetName1, SetName2" or "(All)" for all parameter sets} - Aliases: {comma-separated list of aliases, i.e. EA, ERR} // if ommitted => default - Accepted values: {ValidateSet, comma-separated list of valid values, i.e. Foo, Bar} // if ommitted => everything is accepted - Applicable: {comma-separated list of tags where this cmdlet exists} // if omitted then applicable for any tag - // break line to improve readability and separate metadata block - - Required: {true | false} - Position: {1..n} | named - Default value: {None | False (for switch parameters) | the actual default value} - Accept pipeline input: {false | true (ByValue, ByPropertyName)} - Accept wildcard characters: {true | false} - ``` - // if supports workflow parameters - ### - {{ Workflow common parameters text, would be ingored during maml generation }} - - // if supports common parameters - ### - {{ Common parameters text, would be ingored during maml generation }} + ```powershell + {{Parameter attributes as specified in param() block in PowerShell functions + i.e. [Parameter(ParameterSetName = 'ByName')] + }} + ``` + + {{Parameter description text}} ## INPUTS // for every input type @@ -108,61 +161,17 @@ It closely resembles output of `Get-Help`. ### {Output type} {{Description text}} + ## EXAMPLES + // for every example + ### {Example Name} + + ```powershell + {{Example body}} + ``` + {{Example text explanation}} + ## RELATED LINKS // for every link [{link name}]({link url}) - -### Version 1.0.0 (Deprecated) -v0.7.6 is the last platyPS version that supports it. - - // for every command: - # {Command name} - - // following level-2 headers sections can go in any order - // here is the recommended order - - ## SYNOPSIS - {{Synopsis text}} - - ## DESCRIPTION - {{Description text}} - - ## PARAMETERS - - // for every parameter - // type and default value are non-mandatory - ### {Parameter name} [{Parameter type}] = {Parameter default value} - - // parameter metadata - ```powershell - {{Parameter attributes as specified in param() block in PowerShell functions - i.e. [Parameter(ParameterSetName = 'ByName')] - }} - ``` - - {{Parameter description text}} - - ## INPUTS - // for every input type - ### {Input type} - {{Description text}} - - ## OUTPUTS - // for every output type - ### {Output type} - {{Description text}} - - ## EXAMPLES - // for every example - ### {Example Name} - - ```powershell - {{Example body}} - ``` - {{Example text explanation}} - - ## RELATED LINKS - - // for every link - [{link name}]({link url}) +```