private void GatherSyntax(MamlCommand command) { var parameterSetNames = GetParameterSetNames(); if (parameterSetNames.Count == 0) { // special case: there are no parameters and hence there is only one parameter set MamlSyntax syntax = new MamlSyntax(); command.Syntax.Add(syntax); } foreach (var setName in parameterSetNames) { MamlSyntax syntax = new MamlSyntax(); if (setName == ALL_PARAM_SETS_MONIKER) { if (parameterSetNames.Count == 1) { // special case: there is only one parameter set and it's the deafult one // we don't specify the name in this case. } else { continue; } } else { syntax.ParameterSetName = setName; } FillUpSyntax(syntax, setName); command.Syntax.Add(syntax); } }
public void ReturnsSyntaxString() { var command = new MamlCommand() { Name = "Get-Foo", SupportCommonParameters = true }; var param1 = new MamlParameter() { Name = "Bar", Type = "BarObject" }; var syntax = new MamlSyntax() { IsDefault = true }; syntax.Parameters.Add(param1); string syntaxString = MarkdownV2Renderer.GetSyntaxString(command, syntax); Assert.Equal("Get-Foo [-Bar <BarObject>] [<CommonParameters>]", syntaxString); }
private void FillUpSyntax(MamlSyntax syntax, string name) { var parametersList = new List <MamlParameter>(); foreach (var pair in _parameterName2ParameterSetMap) { MamlParameter param = null; if (pair.Item2.ContainsKey(name)) { param = pair.Item2[name]; } else { if (pair.Item2.Count == 1 && pair.Item2.First().Key == ALL_PARAM_SETS_MONIKER) { param = pair.Item2.First().Value; } } if (param != null) { parametersList.Add(param); } } // order parameters based on position // User OrderBy instead of Sort for stable sort syntax.Parameters.AddRange(parametersList.OrderBy(x => x.Position)); }
private static YamlSyntax CreateSyntax(MamlSyntax syntax) { return(new YamlSyntax { IsDefault = syntax.IsDefault, ParameterValueGroup = syntax.ParameterSetName, Parameters = syntax.Parameters.Select(p => p.Name).ToList() }); }
private MamlCommand GetModel2() { MamlCommand command = new MamlCommand() { Name = "Get-Foo", Synopsis = new SectionBody("This is the synopsis"), Description = new SectionBody("This is a long description.\r\nWith two paragraphs."), Notes = new SectionBody("This is a multiline note.\r\nSecond line.\r\nSecond Command") }; command.Links.Add(new MamlLink(true) { LinkName = "[foo]()\r\n[bar]()", }); command.Examples.Add(new MamlExample() { Title = "Example 1", Code = new[] { new MamlCodeBlock("PS:> Get-Help -YouNeedIt") }, Remarks = "This does stuff!" } ); command.Inputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Foo" } ); var parameterName = new MamlParameter() { Type = "String", Name = "Name", Required = true, Description = "Parameter Description.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "1", DefaultValue = "trololo", Aliases = new string[] { "GF", "Foos", "Do" }, }; command.Parameters.Add(parameterName); var syntax1 = new MamlSyntax() { ParameterSetName = "ByName", }; syntax1.Parameters.Add(parameterName); command.Syntax.Add(syntax1); return(command); }
private MamlCommand GetModel1() { MamlCommand command = new MamlCommand() { Name = "Get-Foo", Synopsis = new SectionBody("This is the synopsis"), Description = new SectionBody("This is a long description.\r\nWith two paragraphs."), Notes = new SectionBody("This is a multiline note.\r\nSecond line.\r\nFirst Command") }; command.Links.Add(new MamlLink(true) { LinkName = "[foo]()\r\n", }); command.Inputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Foo" } ); command.Outputs.Add(new MamlInputOutput() { TypeName = "String", Description = null } ); var parameterName = new MamlParameter() { Type = "String", Name = "Name", Required = true, Description = "Parameter Description.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "1", DefaultValue = "trololo", Aliases = new string[] { "GF", "Foos", "Do" }, }; command.Parameters.Add(parameterName); var syntax1 = new MamlSyntax() { ParameterSetName = "ByName", }; syntax1.Parameters.Add(parameterName); command.Syntax.Add(syntax1); return(command); }
private MamlCommand GetRegenerated() { MamlCommand metadataCommand = new MamlCommand() { Name = "Get-Foo", Description = "This is a long description.\r\nWith two paragraphs.", Synopsis = "This is a old synopsis.", Notes = "These are old notes" }; var parameterName1 = new MamlParameter() { Type = "String[]", // DIFF!! Name = "Name", Description = "Old Description", Required = true, VariableLength = true, Globbing = false, // DIFF!! PipelineInput = "True (ByValue)", Position = "Named", // DIFF!! Aliases = new string[] { "GF", "Foo", "Bar" } }; var parameterNew = new MamlParameter() { Type = "String", Name = "NewParam", Description = "Old Param Description" }; metadataCommand.Parameters.Add(parameterName1); metadataCommand.Parameters.Add(parameterNew); var syntax3 = new MamlSyntax() { ParameterSetName = "AnotherName" }; syntax3.Parameters.Add(parameterName1); syntax3.Parameters.Add(parameterNew); metadataCommand.Syntax.Add(syntax3); var syntax4 = new MamlSyntax() { ParameterSetName = "SetNewName", IsDefault = true }; syntax4.Parameters.Add(parameterName1); metadataCommand.Syntax.Add(syntax4); return(metadataCommand); }
public void RendererLineBreakAfterParameter() { var renderer = new MarkdownV2Renderer(ParserMode.Full); MamlCommand command = new MamlCommand() { Name = "Test-LineBreak", Synopsis = new SectionBody("This is the synopsis"), Description = new SectionBody("This is a long description"), Notes = new SectionBody("This is a note") }; var parameter1 = new MamlParameter() { Type = "String", Name = "Name", Required = true, Description = "Name description.", Globbing = true }; var parameter2 = new MamlParameter() { Type = "String", Name = "Path", FormatOption = SectionFormatOption.LineBreakAfterHeader, Required = true, Description = "Path description.", Globbing = true }; command.Parameters.Add(parameter1); command.Parameters.Add(parameter2); var syntax1 = new MamlSyntax() { ParameterSetName = "ByName" }; syntax1.Parameters.Add(parameter1); syntax1.Parameters.Add(parameter2); command.Syntax.Add(syntax1); string markdown = renderer.MamlModelToString(command, null); // Does not use line break and should not be added Assert.Contains("### -Name\r\nName description.", markdown); // Uses line break and should be preserved Assert.Contains("### -Path\r\n\r\nPath description.", markdown); }
public void RendererProduceSyntaxAndParameter() { MamlRenderer renderer = new MamlRenderer(); MamlCommand command = new MamlCommand() { Name = "Get-Foo", }; var param1 = new MamlParameter() { Type = "String", Name = "Param1", Position = "" }; var param2 = new MamlParameter() { Type = "System.Int32", Name = "Param2", Position = "Named" }; command.Parameters.Add(param1); command.Parameters.Add(param2); var syntax = new MamlSyntax(); syntax.Parameters.Add(param1); syntax.Parameters.Add(param2); command.Syntax.Add(syntax); string maml = renderer.MamlModelToString(new[] { command }); string[] syntaxItemName = EndToEndTests.GetXmlContent(maml, "/msh:helpItems/command:command/command:syntax/command:syntaxItem/maml:name"); Assert.Single(syntaxItemName); Assert.Equal("Get-Foo", syntaxItemName[0]); string[] nameSyntax = EndToEndTests.GetXmlContent(maml, "/msh:helpItems/command:command/command:syntax/command:syntaxItem/command:parameter/maml:name"); Assert.Equal(2, nameSyntax.Length); Assert.Equal("Param1", nameSyntax[0]); Assert.Equal("Param2", nameSyntax[1]); string[] nameParam = EndToEndTests.GetXmlContent(maml, "/msh:helpItems/command:command/command:parameters/command:parameter/maml:name"); Assert.Equal(2, nameParam.Length); Assert.Equal("Param1", nameParam[0]); Assert.Equal("Param2", nameParam[1]); }
private void GatherSyntax(MamlCommand command) { var parameterSetNames = GetParameterSetNames(); var defaultSetName = string.Empty; if (command.Syntax.Count == 1 && command.Syntax[0].IsDefault) { //checks for existing IsDefault paramset and remove it while saving the name defaultSetName = command.Syntax[0].ParameterSetName; command.Syntax.Remove(command.Syntax[0]); } if (parameterSetNames.Count == 0) { // special case: there are no parameters and hence there is only one parameter set MamlSyntax syntax = new MamlSyntax(); command.Syntax.Add(syntax); } foreach (var setName in parameterSetNames) { MamlSyntax syntax = new MamlSyntax(); if (setName == ALL_PARAM_SETS_MONIKER) { if (parameterSetNames.Count == 1) { // special case: there is only one parameter set and it's the default one // we don't specify the name in this case. } else { continue; } } else { syntax.ParameterSetName = StringComparer.OrdinalIgnoreCase.Equals(syntax.ParameterSetName, defaultSetName) ? string.Format("{0}{1}", setName, MarkdownStrings.DefaultParameterSetModifier) : setName; } FillUpSyntax(syntax, setName); command.Syntax.Add(syntax); } }
protected MamlSyntax SyntaxEntryRule() { // grammar: // ### ParameterSetName // ``` // code // ``` MamlSyntax syntax; var node = GetNextNode(); if (node.NodeType == MarkdownNodeType.CodeBlock) { // if header is omitted syntax = new MamlSyntax() { ParameterSetName = ALL_PARAM_SETS_MONIKER, IsDefault = true }; } else { var headingNode = GetHeadingWithExpectedLevel(node, PARAMETERSET_NAME_HEADING_LEVEL); if (headingNode == null) { return(null); } bool isDefault = headingNode.Text.EndsWith(MarkdownStrings.DefaultParameterSetModifier); syntax = new MamlSyntax() { ParameterSetName = isDefault ? headingNode.Text.Substring(0, headingNode.Text.Length - MarkdownStrings.DefaultParameterSetModifier.Length) : headingNode.Text, IsDefault = isDefault }; var codeBlock = CodeBlockRule(); } // we don't use the output of it // TODO: we should capture syntax and verify that it's complient. return(syntax); }
protected MamlSyntax SyntaxEntryRule() { // grammar: // ### ParameterSetName // ``` // code // ``` MamlSyntax syntax; var node = GetNextNode(); if (node.NodeType == MarkdownNodeType.CodeBlock) { // if header is omitted syntax = new MamlSyntax() { ParameterSetName = "__AllParameterSets" }; } else { var headingNode = GetHeadingWithExpectedLevel(node, PARAMETERSET_NAME_HEADING_LEVEL); if (headingNode == null) { return(null); } syntax = new MamlSyntax() { ParameterSetName = headingNode.Text }; var codeBlock = CodeBlockRule(); } // we don't use the output of it // TODO: we should capture syntax and verify that it's complient. return(syntax); }
private MamlCommand GetModel2() { MamlCommand command = new MamlCommand() { Name = "Get-Foo", Synopsis = new SectionBody("This is the synopsis"), Description = new SectionBody("This is a long description.\r\nWith two paragraphs."), Notes = new SectionBody("This is a multiline note.\r\nSecond line.\r\nSecond Command") }; var parameterName = new MamlParameter() { Type = "String", Name = "Name2", Required = true, Description = "Parameter Description.\r\n", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "1", DefaultValue = "trololo", Aliases = new string[] { "GF", "Foos", "Do" }, }; command.Parameters.Add(parameterName); var syntax1 = new MamlSyntax() { IsDefault = true }; syntax1.Parameters.Add(parameterName); command.Syntax.Add(syntax1); return(command); }
private MamlCommand GetModel3() { MamlCommand command = new MamlCommand() { Name = "Get-Foo", Synopsis = "This is the synopsis 3", Description = "This is a long description.\r\nWith two paragraphs.", Notes = "This is a multiline note.\r\nSecond line.\r\nThird Command" }; command.Links.Add(new MamlLink(true) { LinkName = "[bar]()", }); command.Examples.Add(new MamlExample() { Title = "Example 1", Code = "PS:> Get-Help -YouNeedIt", Remarks = "This does stuff too!" } ); command.Inputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Foo 2" } ); command.Outputs.Add(new MamlInputOutput() { TypeName = "String", Description = null } ); var parameterName = new MamlParameter() { Type = "String", Name = "Name", Required = true, Description = "Parameter Description.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "1", DefaultValue = "trololo", Aliases = new string[] { "GF", "Foos", "Do" }, }; var parameterRemoved = new MamlParameter() { Type = "int", Name = "Remove", Required = true, Description = "Parameter Description 2.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "2", DefaultValue = "dodododo", Aliases = new string[] { "Pa1", "RemovedParam", "Gone" }, }; command.Parameters.Add(parameterName); command.Parameters.Add(parameterRemoved); var syntax1 = new MamlSyntax() { ParameterSetName = "ByName", }; syntax1.Parameters.Add(parameterName); syntax1.Parameters.Add(parameterRemoved); command.Syntax.Add(syntax1); var syntax2 = new MamlSyntax() { ParameterSetName = "BySomethingElse", IsDefault = true }; syntax2.Parameters.Add(parameterName); command.Syntax.Add(syntax2); return(command); }
private void GatherParameterDetails(MamlCommand command) { const string parameterFormatString = @" {0} ${1}"; const string docFunctionFormatString = @" function Get-AttributeDocFunction {{ param( {0} ) }} # $h = Get-Help Get-AttributeDocFunction {1} $h.parameters.parameter "; // this is a workaround for https://github.com/PowerShell/platyPS/issues/27 const string getHelpString = @" $isAdmin = (New-Object Security.Principal.WindowsPrincipal ([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) $prev = Get-ItemProperty -Name DisablePromptToUpdateHelp -path 'HKLM:\SOFTWARE\Microsoft\PowerShell' -ErrorAction SilentlyContinue try { if ($isAdmin) { Set-ItemProperty -Name DisablePromptToUpdateHelp -Value 1 -path 'HKLM:\SOFTWARE\Microsoft\PowerShell' } # this is an importent line that populates object $h = Get-Help Get-AttributeDocFunction } finally { if ($isAdmin) { if ($prev) { if ($prev.DisablePromptToUpdateHelp -ne 1) { Set-ItemProperty -Name DisablePromptToUpdateHelp -Value ($prev.DisablePromptToUpdateHelp) -path 'HKLM:\SOFTWARE\Microsoft\PowerShell' } } else { Remove-ItemProperty -Name DisablePromptToUpdateHelp -path 'HKLM:\SOFTWARE\Microsoft\PowerShell' } } } "; // Create the Runspace on demand if (this.runspace == null) { this.runspace = RunspaceFactory.CreateRunspace(); this.runspace.Open(); } using (PowerShell powerShell = PowerShell.Create()) { var parameterBlocks = command .Parameters .Select(p => string.Format(parameterFormatString, p.AttributesMetadata, ShiftName(p.Name))); var functionScript = string.Format( docFunctionFormatString, string.Join(",\r\n", parameterBlocks), getHelpString); // TODO: There could be some security concerns with executing arbitrary // text here, need to investigate safer ways to do it. JEA? powerShell.Runspace = this.runspace; powerShell.AddScript(functionScript); var parameterDetailses = powerShell.Invoke <PSObject>(); if (powerShell.Streams.Error.Any()) { throw new HelpSchemaException(command.Extent, "Errors when processing command " + command.Name + ":\n" + string.Join(";\n", powerShell.Streams.Error)); } foreach (PSObject parameterDetailsPsObject in parameterDetailses) { var parameter = command.Parameters.FirstOrDefault( p => string.Equals(p.Name, UndoShiftName((string)parameterDetailsPsObject.Properties["name"].Value))); FillUpParameterFromPSObject(parameter, parameterDetailsPsObject); } powerShell.Commands.Clear(); powerShell.Commands.AddScript("$h.Syntax.syntaxItem"); var syntaxDetailses = powerShell.Invoke <PSObject>(); if (powerShell.Streams.Error.Any()) { throw new HelpSchemaException(command.Extent, "Errors when processing command " + command.Name + ":\n" + string.Join(";\n", powerShell.Streams.Error)); } var sortedSyntaxItems = syntaxDetailses.ToList(); sortedSyntaxItems.Sort((si1, si2) => String.CompareOrdinal(GetParameterSetNameFromSyntaxItem(si1), GetParameterSetNameFromSyntaxItem(si2))); int count = 1; foreach (var syntaxDetails in sortedSyntaxItems) { MamlSyntax syntax = new MamlSyntax() { // HACK: we need a better solution ParameterSetName = "Set " + (count++) }; var syntaxParams = (object[])syntaxDetails.Properties["parameter"].Value; foreach (PSObject syntaxParamPsObject in syntaxParams.OfType <PSObject>()) { string paramName = UndoShiftName((string)syntaxParamPsObject.Properties["name"].Value); MamlParameter parametersParameter = command.Parameters.FirstOrDefault(p => string.Equals(p.Name, paramName)); if (parametersParameter == null) { throw new HelpSchemaException(command.Extent, "Cannot find corresponding parameter for syntax item " + paramName); } MamlParameter syntaxParameter = new MamlParameter() { Name = parametersParameter.Name, Type = parametersParameter.Type }; FillUpParameterFromPSObject(syntaxParameter, syntaxParamPsObject); syntax.Parameters.Add(syntaxParameter); } command.Syntax.Add(syntax); } } }
public void RenderesAllParameterSetMoniker() { var renderer = new MarkdownV2Renderer(ParserMode.Full); MamlCommand command = new MamlCommand() { Name = "Get-Foo", }; var commonParam = new MamlParameter() { Type = "String", Name = "Common", Required = true }; var parameter1 = new MamlParameter() { Type = "String", Name = "First", Required = true }; var parameter2 = new MamlParameter() { Type = "String", Name = "Second", Required = true }; command.Parameters.Add(commonParam); command.Parameters.Add(parameter1); command.Parameters.Add(parameter2); var syntax1 = new MamlSyntax() { ParameterSetName = "FirstSyntax" }; syntax1.Parameters.Add(commonParam); syntax1.Parameters.Add(parameter1); var syntax2 = new MamlSyntax() { ParameterSetName = "SecondSyntax", IsDefault = true }; syntax2.Parameters.Add(commonParam); syntax2.Parameters.Add(parameter2); command.Syntax.Add(syntax1); command.Syntax.Add(syntax2); string markdown = renderer.MamlModelToString(command, null); Assert.Equal(@"--- schema: 2.0.0 --- # Get-Foo ## SYNOPSIS ## SYNTAX ### FirstSyntax ``` Get-Foo -Common <String> -First <String> [<CommonParameters>] ``` ### SecondSyntax (Default) ``` Get-Foo -Common <String> -Second <String> [<CommonParameters>] ``` ## DESCRIPTION ## EXAMPLES ## PARAMETERS ### -Common ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: Named Default value: Accept pipeline input: false Accept wildcard characters: False ``` ### -First ```yaml Type: String Parameter Sets: FirstSyntax Aliases: Required: True Position: Named Default value: Accept pipeline input: false Accept wildcard characters: False ``` ### -Second ```yaml Type: String Parameter Sets: SecondSyntax Aliases: Required: True Position: Named Default value: Accept pipeline input: false Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES ## RELATED LINKS ", markdown); }
public void RendererProduceMarkdownV2Output() { var renderer = new MarkdownV2Renderer(ParserMode.Full); MamlCommand command = new MamlCommand() { Name = "Get-Foo", Synopsis = "This is the synopsis", Description = "This is a long description.\r\nWith two paragraphs. And the second one contains of few line! They should be auto-wrapped. Because, why not? We can do that kind of the things, no problem.\r\n\r\n-- Foo. Bar.\r\n-- Don't break. The list.\r\n-- Into. Pieces", Notes = "This is a multiline note.\r\nSecond line." }; var parameter = new MamlParameter() { Type = "String", Name = "Name", Required = true, Description = "Parameter Description.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "1", DefaultValue = "trololo", Aliases = new string[] { "GF", "Foos", "Do" }, }; parameter.ParameterValueGroup.AddRange(new string[] { "Value1", "Value2" }); command.Parameters.Add(parameter); var syntax1 = new MamlSyntax() { ParameterSetName = "ByName" }; syntax1.Parameters.Add(parameter); command.Syntax.Add(syntax1); command.Inputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Input <Description> goes here!" } ); command.Outputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Output Description goes here!" } ); command.Examples.Add(new MamlExample() { Title = "Example 1", Code = "PS:> Get-Help -YouNeedIt", Remarks = "This does stuff!" } ); command.Links.Add(new MamlLink() { LinkName = "PowerShell made by Microsoft Hackathon", LinkUri = "www.microsoft.com" }); command.Links.Add(new MamlLink() { LinkName = "", // if name is empty, it would be populated with uri LinkUri = "http://foo.com" }); // Note that the metadata should end up getting alphabetized. var metadata = new Hashtable(); metadata["foo"] = "bar"; metadata["null"] = null; string markdown = renderer.MamlModelToString(command, metadata); Assert.Equal(@"--- foo: bar null: schema: 2.0.0 --- # Get-Foo ## SYNOPSIS This is the synopsis ## SYNTAX ``` Get-Foo [-Name] <String> [<CommonParameters>] ``` ## DESCRIPTION This is a long description. With two paragraphs. And the second one contains of few line! They should be auto-wrapped. Because, why not? We can do that kind of the things, no problem. -- Foo. Bar. -- Don't break. The list. -- Into. Pieces ## EXAMPLES ### Example 1 ``` PS:> Get-Help -YouNeedIt ``` This does stuff! ## PARAMETERS ### -Name Parameter Description. ```yaml Type: String Parameter Sets: (All) Aliases: GF, Foos, Do Accepted values: Value1, Value2 Required: True Position: 1 Default value: trololo Accept pipeline input: True (ByValue) Accept wildcard characters: True ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### String Input \<Description\> goes here! ## OUTPUTS ### String Output Description goes here! ## NOTES This is a multiline note. Second line. ## RELATED LINKS [PowerShell made by Microsoft Hackathon](www.microsoft.com) [http://foo.com](http://foo.com) ", markdown); }
private MamlCommand GetOriginal() { MamlCommand originalCommand = new MamlCommand() { Name = "Get-Foo", Synopsis = new SectionBody("This is the synopsis"), Description = new SectionBody("This is a long description.\r\nWith two paragraphs."), Notes = new SectionBody("This is a multiline note.\r\nSecond line.") }; var parameterName = new MamlParameter() { Type = "String", Name = "Name", Required = true, Description = "Parameter Description.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "1", DefaultValue = "trololo", Aliases = new string[] { "GF", "Foos", "Do" }, }; var removedParameterName = new MamlParameter() { Type = "int", Name = "Remove", Required = true, Description = "Parameter Description 2.", VariableLength = true, Globbing = true, PipelineInput = "True (ByValue)", Position = "2", DefaultValue = "dodododo", Aliases = new string[] { "Pa1", "RemovedParam", "Gone" }, }; var parameterPath = new MamlParameter() { Type = "String", Name = "Path", Required = true, Description = "Parameter path description.", FormatOption = SectionFormatOption.LineBreakAfterHeader, Globbing = true }; originalCommand.Parameters.Add(parameterName); originalCommand.Parameters.Add(removedParameterName); originalCommand.Parameters.Add(parameterPath); var syntax1 = new MamlSyntax() { ParameterSetName = "ByName", }; syntax1.Parameters.Add(parameterName); syntax1.Parameters.Add(removedParameterName); syntax1.Parameters.Add(parameterPath); originalCommand.Syntax.Add(syntax1); var syntax2 = new MamlSyntax() { ParameterSetName = "SetOldName", IsDefault = true }; syntax2.Parameters.Add(parameterName); syntax2.Parameters.Add(parameterPath); originalCommand.Syntax.Add(syntax2); originalCommand.Inputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Input <Description> goes here!" } ); originalCommand.Outputs.Add(new MamlInputOutput() { TypeName = "String", Description = "Output Description goes here!" } ); originalCommand.Examples.Add(new MamlExample() { Title = "Example 1", Code = new[] { new MamlCodeBlock("PS:> Get-Help -YouNeedIt") }, Remarks = "This does stuff!" } ); originalCommand.Links.Add(new MamlLink() { LinkName = "PowerShell made by Microsoft Hackathon", LinkUri = "www.microsoft.com" }); originalCommand.Links.Add(new MamlLink() { LinkName = "", // if name is empty, it would be populated with uri LinkUri = "http://foo.com" }); return(originalCommand); }
private static XElement CreateSyntaxItem(MamlSyntax syntaxItem, MamlCommand command) { return(new XElement(commandNS + "syntaxItem", new XElement(mamlNS + "name", command.Name), syntaxItem.Parameters.Select(param => CreateParameter(param, isSyntax: true)))); }
private static MamlCommand CreateModel() { var command = new MamlCommand { Name = "Test-Unit", Description = "A test cmdlet", Synopsis = "A cmdlet to test", Notes = "This is just a test", ModuleName = "TestModule" }; command.Examples.Add(new MamlExample { Remarks = "Example 1 remarks", Code = "Example 1 code", Introduction = "Example 1 intro", Title = "Example 1 title" }); command.Inputs.Add(new MamlInputOutput { Description = "Input 1", TypeName = "System.String" }); command.Links.Add(new MamlLink { LinkUri = "https://docs.microsoft.com", LinkName = "Docs" }); var mamlOptionalParameter = new MamlParameter { Required = false, Name = "-TestParam", Globbing = true, Aliases = new [] { "-Alias1" }, DefaultValue = "Test", Description = "Test Parameter", PipelineInput = "false", Position = "1", Type = "System.String" }; mamlOptionalParameter.ParameterValueGroup.Add("TestGroup"); var mamlRequiredParameter = new MamlParameter { Required = true, Name = "-TestParam2", Globbing = false, Aliases = new[] { "-Alias2" }, DefaultValue = "Test2", Description = "Test Parameter 2", PipelineInput = "true", Position = "2", Type = "System.Boolean" }; mamlRequiredParameter.ParameterValueGroup.Add("TestGroup2"); command.Parameters.AddRange(new [] { mamlRequiredParameter, mamlOptionalParameter }); command.Outputs.Add(new MamlInputOutput { Description = "Output 1", TypeName = "System.String" }); var mamlSyntax = new MamlSyntax { ParameterSetName = "TestGroup", IsDefault = true }; mamlSyntax.Parameters.Add(mamlOptionalParameter); command.Syntax.Add(mamlSyntax); return(command); }
private void MergeParameters(MamlCommand result, Dictionary <string, MamlCommand> applicableTag2Model) { // First handle syntax. // To avoid dealing with complicated applicableTag + ParameterSetName pairs. // They already serve very similar purpose. // // We simply merge syntaxes of the same name. That way all possible parameter names from all applicable tags // apearing in the syntax. This is not ideal, but alternative would be introducing "applicable" for syntax. // That would make it even more complicated. var tagsModel = applicableTag2Model.ToList(); var syntaxes = tagsModel.SelectMany(pair => pair.Value.Syntax); var syntaxNames = syntaxes.Select(syntax => syntax.ParameterSetName).Distinct(StringComparer.OrdinalIgnoreCase); var defaultSyntaxNames = syntaxes.Where(syntax => syntax.IsDefault).Select(syntax => syntax.ParameterSetName).Distinct(StringComparer.OrdinalIgnoreCase); if (defaultSyntaxNames.Count() > 1) { // reporting warning and continue Report("Found conflicting default ParameterSets ({0}) in applicableTags ({1})", string.Join(", ", defaultSyntaxNames), string.Join(", ", applicableTag2Model.Keys)); } string defaultSyntaxName = defaultSyntaxNames.FirstOrDefault(); foreach (string syntaxName in syntaxNames) { var newSyntax = new MamlSyntax() { ParameterSetName = syntaxName, IsDefault = StringComparer.OrdinalIgnoreCase.Equals(defaultSyntaxName, syntaxName), }; var paramSetsToMerge = syntaxes.Where(syntax => StringComparer.OrdinalIgnoreCase.Equals(syntax.ParameterSetName, syntaxName)); newSyntax.Parameters.AddRange(MergeParameterList(paramSetsToMerge.Select(syntax => syntax.Parameters))); result.Syntax.Add(newSyntax); } // Then merge individual parameters var allNames = tagsModel.SelectMany(pair => pair.Value.Parameters).Select(p => p.Name).Distinct().ToList(); foreach (string name in allNames) { Dictionary <string, MamlParameter> paramsToMerge = new Dictionary <string, MamlParameter>(); foreach (var pair in tagsModel) { MamlParameter candidate = FindParameterByName(name, pair.Value.Parameters); if (candidate != null) { paramsToMerge[pair.Key] = candidate; } } string newDescription = MergeText(paramsToMerge.ToDictionary(pair => pair.Key, pair => pair.Value.Description)); var newParameter = paramsToMerge.First().Value.Clone(); newParameter.Description = newDescription; if (paramsToMerge.Count != applicableTag2Model.Count || !this._ignoreTagsIfAllApplicable) { // we should not update applicable tags, if it's applicable to everything and not explicitly specified newParameter.Applicable = paramsToMerge.Select(p => p.Key).ToArray(); } result.Parameters.Add(newParameter); } }
private void GatherParameterDetails(MamlCommand command) { const string parameterFormatString = @" {0} ${1}"; const string docFunctionFormatString = @" function Get-AttributeDocFunction {{ param( {0} ) }} $h = Get-Help Get-AttributeDocFunction $h.parameters.parameter "; // Create the Runspace on demand if (this.runspace == null) { this.runspace = RunspaceFactory.CreateRunspace(); this.runspace.Open(); } using (PowerShell powerShell = PowerShell.Create()) { var parameterBlocks = command .Parameters .Select(p => string.Format(parameterFormatString, p.AttributesText, ShiftName(p.Name))); var functionScript = string.Format( docFunctionFormatString, string.Join(",\r\n", parameterBlocks)); // TODO: There could be some security concerns with executing arbitrary // text here, need to investigate safer ways to do it. JEA? powerShell.Runspace = this.runspace; powerShell.AddScript(functionScript); var parameterDetailses = powerShell.Invoke <PSObject>(); if (powerShell.Streams.Error.Any()) { throw new HelpSchemaException(command.Extent, "Errors when processing command " + command.Name + ":\n" + string.Join(";\n", powerShell.Streams.Error)); } foreach (PSObject parameterDetailsPsObject in parameterDetailses) { var parameter = command.Parameters.FirstOrDefault( p => string.Equals(p.Name, UndoShiftName((string)parameterDetailsPsObject.Properties["name"].Value))); FillUpParameterFromPSObject(parameter, parameterDetailsPsObject); } powerShell.Commands.Clear(); powerShell.Commands.AddScript("$h.Syntax.syntaxItem"); var syntaxDetailses = powerShell.Invoke <PSObject>(); if (powerShell.Streams.Error.Any()) { throw new HelpSchemaException(command.Extent, "Errors when processing command " + command.Name + ":\n" + string.Join(";\n", powerShell.Streams.Error)); } var sortedSyntaxItems = syntaxDetailses.ToList(); sortedSyntaxItems.Sort((si1, si2) => String.CompareOrdinal(GetParameterSetNameFromSyntaxItem(si1), GetParameterSetNameFromSyntaxItem(si2))); foreach (var syntaxDetails in sortedSyntaxItems) { MamlSyntax syntax = new MamlSyntax(); var syntaxParams = (object[])syntaxDetails.Properties["parameter"].Value; foreach (PSObject syntaxParamPsObject in syntaxParams.OfType <PSObject>()) { string paramName = UndoShiftName((string)syntaxParamPsObject.Properties["name"].Value); MamlParameter parametersParameter = command.Parameters.FirstOrDefault(p => string.Equals(p.Name, paramName)); if (parametersParameter == null) { throw new HelpSchemaException(command.Extent, "Cannot find corresponding parameter for syntax item " + paramName); } MamlParameter syntaxParameter = new MamlParameter() { Name = parametersParameter.Name, Type = parametersParameter.Type }; FillUpParameterFromPSObject(syntaxParameter, syntaxParamPsObject); syntax.Parameters.Add(syntaxParameter); } command.Syntax.Add(syntax); } } }
public static string GetSyntaxString(MamlCommand command, MamlSyntax syntax) { return(GetSyntaxString(command, syntax, DEFAULT_SYNTAX_WIDTH)); }
public static string GetSyntaxString(MamlCommand command, MamlSyntax syntax, int maxSyntaxWidth) { // TODO: we may want to add ParameterValueGroup info here, // but it's fine for now var sb = new StringBuilder(); sb.Append(command.Name); var paramStrings = new List <string>(); // first we create list of param string we want to add foreach (var param in syntax.Parameters) { string paramStr; if (param.IsSwitchParameter()) { paramStr = string.Format("[-{0}]", param.Name); } else { paramStr = string.Format("-{0}", param.Name); if (!param.IsNamed()) { // for positional parameters, we can avoid specifying the name paramStr = string.Format("[{0}]", paramStr); } paramStr = string.Format("{0} <{1}>", paramStr, param.Type); if (!param.Required) { paramStr = string.Format("[{0}]", paramStr); } } paramStrings.Add(paramStr); } if (command.IsWorkflow) { paramStrings.Add("[<" + MarkdownStrings.WorkflowParametersToken + ">]"); } if (command.SupportCommonParameters) { paramStrings.Add("[<" + MarkdownStrings.CommonParametersToken + ">]"); } // then we format them properly with repsect to max width for window. int widthBeforeLastBreak = 0; foreach (string paramStr in paramStrings) { if (sb.Length - widthBeforeLastBreak + paramStr.Length > maxSyntaxWidth) { sb.AppendLine(); widthBeforeLastBreak = sb.Length; } sb.AppendFormat(" {0}", paramStr); } return(sb.ToString()); }