Skip to content

Commit d95eb27

Browse files
authored
Next batch of OPS changes - multiple bug fixes (#697)
* Implement Show-PreviewHelp and New-HelpCabinetFile in psm1. update psd1 for psm1. add tests borrowed from v1. * Fix markdown parser to handle empty alias section. Fix for issue 391 Add tests for same. Add a helper for identifying an about_Topic in ProbeInfo. Add Get-Date.V2.md as an asset. * Revamp Update cmdlets - refactor into mergeutil class. - Both Update-CommandHelp and Update-MarkdownCommandHelp use same routine. - fix cmdlet transformer to not mess up the parameter order. - Don't abbreviate switch parameter. - Change parameter type to use PowerShell style '[' rather than c# '<' for generic types. * use constants rather than strings in the transformer. * Change type of cmdlet alias property. - It is now a string rather than a list of strings. - Update tests to handle the change. Support example title with markdown changes. - Add test for example title which includes emphasized text. * Fix up some issues in the cab builder. Also add tests for Show-HelpPreview * Remove references to System.Text.Json. Use the deserialization message to help the user locate the bad yaml. * Fix tsaoptions areaPath.
1 parent 05ea3b8 commit d95eb27

27 files changed

+1769
-472
lines changed

.config/tsaoptions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"instanceUrl": "https://msazure.visualstudio.com",
33
"projectName": "One",
4-
"areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell",
4+
"areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core\\Platyps",
55
"codebaseName": "TFSMSAzure_platyPS",
66
"notificationAliases": [ "jimtru@microsoft.com", "slee@microsoft.com" ],
77
"tools": [ "CredScan", "PoliCheck", "BinSkim" ]

build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if ($PSCmdlet.ParameterSetName -eq 'Build') {
6666
$moduleRoot = New-Item -Item Directory -Path "$OutputDir/${ModuleName}" -Force
6767
$depsFolder = New-Item -Item Directory -Path "$moduleRoot/Dependencies" -Force
6868

69-
$moduleFiles = "$PSScriptRoot/src/${ModuleName}.psd1", "$PSScriptRoot/src/${ModuleName}.Format.ps1xml",$expectedDllPath
69+
$moduleFiles = "$PSScriptRoot/src/${ModuleName}.psd1", "${PSScriptRoot}/src/${ModuleName}.psm1", "$PSScriptRoot/src/${ModuleName}.Format.ps1xml",$expectedDllPath
7070
if ($configuration -eq "debug") {
7171
$moduleFiles += $expectedPdbPath
7272
}

src/Command/Update-CommandHelp.cs

Lines changed: 1 addition & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,7 @@ protected override void ProcessRecord()
8080
continue;
8181
}
8282

83-
var mergedCommandHelp = Merge(commandHelpObject, helpObjectFromCmdlet);
84-
if (mergedCommandHelp.Metadata is not null)
85-
{
86-
mergedCommandHelp.Metadata["ms.date"] = DateTime.Now.ToString("MM/dd/yyyy");
87-
}
83+
var mergedCommandHelp = MergeUtils.MergeCommandHelp(commandHelpObject, helpObjectFromCmdlet);
8884

8985
WriteObject(mergedCommandHelp);
9086
}
@@ -94,210 +90,6 @@ protected override void ProcessRecord()
9490
}
9591
}
9692
}
97-
98-
/// <summary>
99-
/// Merge the new data found in the cmdlet object.
100-
/// </summary>
101-
/// <param name="fromMarkdown"></param>
102-
/// <param name="fromCmdlet"></param>
103-
/// <returns></returns>
104-
CommandHelp Merge(CommandHelp fromMarkdown, CommandHelp fromCmdlet)
105-
{
106-
CommandHelp helpCopy = new (fromMarkdown);
107-
// Syntax
108-
if (TryGetMergedSyntax(helpCopy.Syntax, fromCmdlet.Syntax, out var mergedSyntaxList, out var syntaxDiagnostics))
109-
{
110-
helpCopy.Syntax.Clear();
111-
helpCopy.Syntax.AddRange(mergedSyntaxList);
112-
}
113-
syntaxDiagnostics.ForEach(d => helpCopy.Diagnostics.TryAddDiagnostic(d));
114-
115-
// Alias - there are no aliases to be found in the cmdlet, but we shouldn't add the boiler plate.
116-
// If the boiler plate is found, we'll clear the aliases.
117-
helpCopy.AliasHeaderFound = true;
118-
if (helpCopy.Aliases.Any(s => s.IndexOf(Constants.AliasMessage2, StringComparison.OrdinalIgnoreCase) >= 0))
119-
{
120-
helpCopy.Aliases?.Clear();
121-
}
122-
123-
124-
// Parameters
125-
if (TryGetMergedParameters(helpCopy.Parameters, fromCmdlet.Parameters, out var mergedParametersList, out var paramDiagnostics))
126-
{
127-
helpCopy.Parameters.Clear();
128-
helpCopy.Parameters.AddRange(mergedParametersList);
129-
}
130-
paramDiagnostics.ForEach(d => helpCopy.Diagnostics.TryAddDiagnostic(d));
131-
132-
// Input
133-
if (TryGetMergedInputOutputs(fromMarkdown.Inputs, fromCmdlet.Inputs, out var mergedInputs, out var inputDiagnostics))
134-
{
135-
helpCopy.Inputs.Clear();
136-
helpCopy.Inputs.AddRange(mergedInputs);
137-
}
138-
inputDiagnostics.ForEach(d => helpCopy.Diagnostics.TryAddDiagnostic(d));
139-
140-
// Output
141-
if (TryGetMergedInputOutputs(fromMarkdown.Outputs, fromCmdlet.Outputs, out var mergedOutputs, out var outputDiagnostics))
142-
{
143-
helpCopy.Outputs.Clear();
144-
helpCopy.Outputs.AddRange(mergedOutputs);
145-
}
146-
outputDiagnostics.ForEach(d => helpCopy.Diagnostics.TryAddDiagnostic(d));
147-
148-
return helpCopy;
149-
}
150-
151-
/// <summary>
152-
/// Merge the syntaxes from the help and the command.
153-
/// In this case, we'll just replace the syntax for the parameter set we can identify.
154-
/// </summary>
155-
/// <param name="fromHelp"></param>
156-
/// <param name="fromCommand"></param>
157-
/// <param name="mergedSyntax"></param>
158-
/// <param name="diagnosticMessages"></param>
159-
/// <returns></returns>
160-
private bool TryGetMergedSyntax(List<SyntaxItem>fromHelp, List<SyntaxItem>fromCommand, out List<SyntaxItem>mergedSyntax, out List<DiagnosticMessage>diagnosticMessages)
161-
{
162-
diagnosticMessages = new();
163-
mergedSyntax = new List<SyntaxItem>();
164-
// They're the same, just return false
165-
if (fromHelp.SequenceEqual(fromCommand))
166-
{
167-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, "Syntaxes are the same", DiagnosticSeverity.Information, "TryGetMergedSyntax", -1));
168-
return false;
169-
}
170-
171-
// We believe the command as a source over the help.
172-
foreach (var syntax in fromHelp)
173-
{
174-
var cmdletSyntaxes = fromCommand.Where<SyntaxItem>(s => string.Compare(s.ParameterSetName, syntax.ParameterSetName) == 0);
175-
var cmdletSyntax = cmdletSyntaxes.Count() > 0 ? cmdletSyntaxes.First() : null;
176-
if (cmdletSyntax is null)
177-
{
178-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"Syntax for {syntax.ParameterSetName} is not found.", DiagnosticSeverity.Information, "TryGetMergedSyntax", -1));
179-
mergedSyntax.Add(syntax);
180-
}
181-
else
182-
{
183-
if (cmdletSyntax == syntax)
184-
{
185-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"Syntaxes for {syntax.ParameterSetName} are the same.", DiagnosticSeverity.Information, "TryGetMergedSyntax", -1));
186-
mergedSyntax.Add(syntax);
187-
}
188-
else
189-
{
190-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"Updating syntax for {cmdletSyntax.ParameterSetName}.", DiagnosticSeverity.Information, "TryGetMergedSyntax", -1));
191-
mergedSyntax.Add(cmdletSyntax);
192-
}
193-
}
194-
}
195-
196-
var missingList = fromCommand.Where(c => ! fromHelp.Any(h => string.Compare(c.ParameterSetName, h.ParameterSetName) == 0));
197-
if (missingList is not null)
198-
{
199-
foreach(var missing in missingList)
200-
{
201-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"Adding missing syntax for {missing.ParameterSetName}", DiagnosticSeverity.Information, "TryGetMergedSyntax", -1));
202-
mergedSyntax.Add(missing);
203-
}
204-
}
205-
206-
return true;
207-
}
208-
209-
private bool TryGetMergedParameters(List<Parameter>fromHelp, List<Parameter>fromCommand, out List<Parameter>mergedParameters, out List<DiagnosticMessage>diagnosticMessages)
210-
{
211-
diagnosticMessages = new();
212-
mergedParameters = new();
213-
// They're the same, just return false
214-
if (fromHelp.SequenceEqual(fromCommand))
215-
{
216-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, "Parameters are the same", DiagnosticSeverity.Information, "TryGetMergedParameters", -1));
217-
return false;
218-
}
219-
220-
// dynamic parameters are currently unhandled on the command side.
221-
// They will still be copied if they are in the help.
222-
foreach(var param in fromCommand)
223-
{
224-
// We should find 0 or 1 parameters that have the same name as the parameter in the cmdlet.
225-
var foundParams = fromHelp.Where(x => string.Compare(x.Name, param.Name) == 0);
226-
var helpParam = foundParams.Count() > 0 ? foundParams.First() : null;
227-
if (helpParam is null)
228-
{
229-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"updating {param.Name}, not found in help.", DiagnosticSeverity.Information, "TryGetMergedParameters", -1));
230-
var newParameter = new Parameter(param)
231-
{
232-
Description = "**FILL IN DESCRIPTION**"
233-
};
234-
mergedParameters.Add(param);
235-
}
236-
else if (helpParam == param)
237-
{
238-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"No change to {param.Name}.", DiagnosticSeverity.Information, "TryGetMergedParameters", -1));
239-
mergedParameters.Add(helpParam);
240-
}
241-
else
242-
{
243-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"updating {param.Name}.", DiagnosticSeverity.Information, "TryGetMergedParameters", -1));
244-
var newParameter = new Parameter(param)
245-
{
246-
Description = helpParam.Description
247-
};
248-
mergedParameters.Add(newParameter);
249-
}
250-
}
251-
252-
253-
// Be sure that any parameters documented (which may not be in the command) are included.
254-
var missingList = fromHelp.Where(c => ! fromCommand.Any(h => string.Compare(c.Name, h.Name) == 0));
255-
foreach (var param in missingList)
256-
{
257-
diagnosticMessages.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"adding {param.Name}, parameter found in help.", DiagnosticSeverity.Information, "TryGetMergedParameters", -1));
258-
mergedParameters.Add(param);
259-
}
260-
261-
return true;
262-
}
263-
264-
private bool TryGetMergedInputOutputs(List<InputOutput>fromHelp, List<InputOutput>fromCommand, out List<InputOutput>mergedInputOutput, out List<DiagnosticMessage>diagnostics)
265-
{
266-
diagnostics = new();
267-
mergedInputOutput = new(fromCommand);
268-
if (fromHelp.SequenceEqual(fromCommand))
269-
{
270-
diagnostics.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, "Input/Output are the same", DiagnosticSeverity.Information, "TryGetMergedInputOutput", -1));
271-
return false;
272-
}
273-
274-
var newList = fromCommand.Where(c => ! fromHelp.Any(h => string.Compare(c.Typename, h.Typename, StringComparison.CurrentCultureIgnoreCase) == 0));
275-
if (newList.Count() == 0)
276-
{
277-
diagnostics.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, "Input/Output names are the same", DiagnosticSeverity.Information, "TryGetMergedInputOutput", -1));
278-
return false;
279-
}
280-
281-
mergedInputOutput = new(fromHelp);
282-
foreach(var newIO in newList)
283-
{
284-
diagnostics.Add(new DiagnosticMessage(DiagnosticMessageSource.Merge, $"Adding {newIO.Typename}", DiagnosticSeverity.Information, "TryGetMergedInputOutput", -1));
285-
mergedInputOutput.Add(newIO);
286-
}
287-
288-
return true;
289-
}
290-
291-
Encoding GetFileEncoding(string filePath)
292-
{
293-
Encoding encoding;
294-
using (var reader = new StreamReader(filePath, Encoding.UTF8, true))
295-
{
296-
reader.Peek();
297-
encoding = reader.CurrentEncoding;
298-
}
299-
return encoding;
300-
}
30193
}
30294

30395
}

0 commit comments

Comments
 (0)