-
Notifications
You must be signed in to change notification settings - Fork 393
WIP: restore GetCommandInfo to non-obsolete status #953
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9a6bc97
d59d931
0f562df
9ab158f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -399,7 +399,7 @@ public HashSet<string> GetExportedFunction(Ast ast) | |
IEnumerable<Ast> cmdAsts = ast.FindAll(item => item is CommandAst | ||
&& exportFunctionsCmdlet.Contains((item as CommandAst).GetCommandName(), StringComparer.OrdinalIgnoreCase), true); | ||
|
||
CommandInfo exportMM = Helper.Instance.GetCommandInfoLegacy("export-modulemember", CommandTypes.Cmdlet); | ||
CommandInfo exportMM = Helper.Instance.GetCommandInfo("export-modulemember", CommandTypes.Cmdlet); | ||
|
||
// switch parameters | ||
IEnumerable<ParameterMetadata> switchParams = (exportMM != null) ? exportMM.Parameters.Values.Where<ParameterMetadata>(pm => pm.SwitchParameter) : Enumerable.Empty<ParameterMetadata>(); | ||
|
@@ -614,7 +614,7 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio | |
return false; | ||
} | ||
|
||
var commandInfo = GetCommandInfoLegacy(cmdAst.GetCommandName()); | ||
var commandInfo = GetCommandInfo(cmdAst.GetCommandName()); | ||
if (commandInfo == null || (commandInfo.CommandType != System.Management.Automation.CommandTypes.Cmdlet)) | ||
{ | ||
return false; | ||
|
@@ -694,88 +694,71 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio | |
/// Get a CommandInfo object of the given command name | ||
/// </summary> | ||
/// <returns>Returns null if command does not exists</returns> | ||
private CommandInfo GetCommandInfoInternal(string cmdName, CommandTypes? commandType) | ||
private CommandInfo GetCommandInfoInternal(string cmdName, CommandTypes commandType) | ||
{ | ||
if (string.IsNullOrWhiteSpace(cmdName)) | ||
{ | ||
return null; | ||
} | ||
|
||
// Don't hold the lock during the pipeline call | ||
lock (getCommandLock) | ||
{ | ||
CommandInfo cmdletInfo; | ||
if (commandInfoCache.TryGetValue(cmdName, out cmdletInfo)) { | ||
return cmdletInfo; | ||
} | ||
} | ||
|
||
using (var ps = System.Management.Automation.PowerShell.Create()) | ||
{ | ||
var psCommand = ps.AddCommand("Get-Command") | ||
.AddParameter("Name", cmdName) | ||
.AddParameter("ErrorAction", "SilentlyContinue"); | ||
|
||
if(commandType!=null) | ||
{ | ||
psCommand.AddParameter("CommandType", commandType); | ||
} | ||
.AddParameter("ErrorAction", "SilentlyContinue") | ||
.AddParameter("CommandType", commandType); | ||
|
||
var commandInfo = psCommand.Invoke<CommandInfo>() | ||
.FirstOrDefault(); | ||
|
||
lock (getCommandLock) | ||
{ | ||
CommandInfo cmdletInfo; | ||
if (! commandInfoCache.TryGetValue(cmdName, out cmdletInfo) ) | ||
{ | ||
commandInfoCache.Add(cmdName, commandInfo); | ||
} | ||
} | ||
return commandInfo; | ||
} | ||
} | ||
|
||
/// <summary> | ||
|
||
/// Legacy method, new callers should use <see cref="GetCommandInfo"/> instead. | ||
/// Given a command's name, checks whether it exists. It does not use the passed in CommandTypes parameter, which is a bug. | ||
/// But existing method callers are already depending on this behaviour and therefore this could not be simply fixed. | ||
/// It also populates the commandInfoCache which can have side effects in some cases. | ||
/// Get a CommandInfo object of the given command name and type | ||
/// <param name="name"></param> | ||
/// <param name="commandType"></param> | ||
/// </summary> | ||
/// <param name="name">Command Name.</param> | ||
/// <param name="commandType">Not being used.</param> | ||
/// <returns></returns> | ||
[Obsolete] | ||
public CommandInfo GetCommandInfoLegacy(string name, CommandTypes? commandType = null) | ||
/// <returns>The first CommandInfo found based on the name and type or null if nothing was found</returns> | ||
public CommandInfo GetCommandInfo(string name, CommandTypes commandType) | ||
{ | ||
if (string.IsNullOrWhiteSpace(name)) | ||
{ | ||
return null; | ||
} | ||
|
||
// check if it is an alias | ||
string cmdletName = Helper.Instance.GetCmdletNameFromAlias(name); | ||
if (string.IsNullOrWhiteSpace(cmdletName)) | ||
{ | ||
cmdletName = name; | ||
} | ||
|
||
lock (getCommandLock) | ||
{ | ||
if (commandInfoCache.ContainsKey(cmdletName)) | ||
{ | ||
return commandInfoCache[cmdletName]; | ||
} | ||
|
||
var commandInfo = GetCommandInfoInternal(cmdletName, commandType); | ||
commandInfoCache.Add(cmdletName, commandInfo); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we do not add to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that is a big error - I meant to leave it in the Internal routine (where it belongs) - updated PR on the way |
||
return commandInfo; | ||
} | ||
// We don't check for alias in this case as the user has been explicit about | ||
// the CommandTypes desired | ||
return GetCommandInfoInternal(name, commandType); | ||
} | ||
|
||
/// <summary> | ||
/// Given a command's name, checks whether it exists. | ||
/// Given a command's name, retrieve its CommandInfo if it exists | ||
/// </summary> | ||
/// <param name="name"></param> | ||
/// <param name="commandType"></param> | ||
/// <returns></returns> | ||
public CommandInfo GetCommandInfo(string name, CommandTypes? commandType = null) | ||
/// <returns>The first CommandInfo found based on the name of any command type or null if nothing was found</returns> | ||
public CommandInfo GetCommandInfo(string name) | ||
{ | ||
if (string.IsNullOrWhiteSpace(name)) | ||
{ | ||
return null; | ||
} | ||
|
||
lock (getCommandLock) | ||
// check to see if it's an alias and use the resolved cmdlet name if it is | ||
string cmdletName = Helper.Instance.GetCmdletNameFromAlias(name); | ||
if ( string.IsNullOrWhiteSpace(cmdletName)) | ||
{ | ||
if (commandInfoCache.ContainsKey(name)) | ||
{ | ||
return commandInfoCache[name]; | ||
} | ||
|
||
var commandInfo = GetCommandInfoInternal(name, commandType); | ||
|
||
return commandInfo; | ||
cmdletName = name; | ||
} | ||
return GetCommandInfo(cmdletName, CommandTypes.All); | ||
} | ||
|
||
/// <summary> | ||
|
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,19 @@ | ||
Import-Module -Verbose PSScriptAnalyzer | ||
$violationMessage = "Cmdlet 'Write-Warning' may be used incorrectly. Please check that all mandatory parameters are supplied." | ||
$violationName = "PSUseCmdletCorrectly" | ||
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path | ||
$violations = Invoke-ScriptAnalyzer $directory\UseCmdletCorrectly.ps1 | Where-Object {$_.RuleName -eq $violationName} | ||
$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} | ||
|
||
| ||
Describe "UseCmdletCorrectly" { | ||
Context "When there are violations" { | ||
It "has 1 Use Cmdlet Correctly violation" { | ||
$violations.Count | Should -Be 1 | ||
} | ||
|
||
It "has the correct description message" { | ||
$violations[0].Message | Should -Match $violationMessage | ||
$violationName = "PSUseCmdletCorrectly" | ||
$violation = Invoke-ScriptAnalyzer -ScriptDefinition 'Write-Warning;Write-Warning -Message "a warning"' | ||
$violation.Count | Should -Be 1 | ||
$violation.RuleName | Should -Be $violationName | ||
} | ||
} | ||
|
||
Context "When there are no violations" { | ||
It "returns no violations" { | ||
$directory = $PSScriptRoot | ||
$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | ||
$noViolations.Count | Should -Be 0 | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ test_script: | |
- ps: | | ||
if ($env:PowerShellEdition -eq 'WindowsPowerShell') { | ||
$modulePath = $env:PSModulePath.Split([System.IO.Path]::PathSeparator) | Where-Object { Test-Path $_} | Select-Object -First 1 | ||
if ( Test-Path "$modulePath\PSScriptAnalyzer" ) { Remove-Item -recurse -force "$modulePath\PSScriptAnalyzer" } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you find that there was a |
||
Copy-Item "${env:APPVEYOR_BUILD_FOLDER}\out\PSScriptAnalyzer" "$modulePath\" -Recurse -Force | ||
$testResultsFile = ".\TestResults.xml" | ||
$testScripts = "${env:APPVEYOR_BUILD_FOLDER}\Tests\Engine","${env:APPVEYOR_BUILD_FOLDER}\Tests\Rules" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can we just remove the alias lookup?