Compare commits

..

No commits in common. "c62e9815ac93e14104ac2527cbe28fd79bba5201" and "3fb7f0926e53d9562be2fcfbe8b8bb9a8208b5ad" have entirely different histories.

3 changed files with 105 additions and 203 deletions

View File

@ -1,160 +1,110 @@
param ( [cmdletbinding()]
[Parameter(Mandatory)] Param(
[ValidateScript({ [Parameter(
Test-Path $_ -PathType Leaf Mandatory= $true
})] )]
[string]$Path [ValidateScript({Test-Path $_ -PathType Leaf})]
[string]$Path
) )
process { begin
Add-Type -AssemblyName System.Management.Automation {
$script_path_raw = Get-Item $Path $system_types = @('Parameter','ValidatePattern','ValidateScript','ValidateSet')
}
process
{
$script_path_raw = Get-Item $Path
$script_name = $script_path_raw.Name $script_name = $script_path_raw.Name
$script_path = $script_path_raw | Select-Object -ExpandProperty FullName $script_path = $script_path_raw | Select-Object -ExpandProperty FullName
$tokens = $null
$errors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile($script_path, [ref]$tokens, [ref]$errors)
if ($errors.Count -gt 0) { $parse_errors = @()
throw "Parse errors found: $($errors | ForEach-Object { $_.Message })"
} $AST = [System.Management.Automation.Language.Parser]::ParseFile($script_path, [ref]$null, [ref]$parse_errors)
$paramBlock = $ast.ParamBlock if($null -eq $AST.ParamBlock)
if (-not $paramBlock) { {
throw "No param() block found at the script level." throw "No 'Param(...)' block found: $($Path)"
} }
$cmdletBindingAttr = $paramBlock.Attributes | Where-Object { $_.TypeName.Name -eq 'CmdletBinding' } $parameters = @()
$defaultParamSet = $cmdletBindingAttr.NamedArguments | foreach($param in $AST.ParamBlock.Parameters)
Where-Object { $_.ArgumentName -eq 'DefaultParameterSetName' } | {
Select-Object -ExpandProperty Argument | $param_name = $param.Name.Extent.Text
Select-Object -ExpandProperty Value $param_type = $null
$param_mandatory = $false
$parameters = @() $param_parameters = @()
$param_validations = @()
foreach ($param in $paramBlock.Parameters) {
$paramName = $param.Name.VariablePath.UserPath foreach($attr in $param.Attributes)
{
# Fix the type name if($system_types -contains $attr.TypeName.Name)
$staticType = $param.StaticType {
if ($staticType.IsGenericType -and $staticType.Name -eq 'Nullable`1') {
$innerType = $staticType.GenericTypeArguments[0].Name switch -Wildcard ($attr.TypeName.Name)
$paramType = "Nullable[$innerType]" {
} else { "Parameter"
$paramType = $staticType.Name {
} foreach($named_argument in $attr.NamedArguments)
{
$aliases = @() if($named_argument.ArgumentName -eq 'Mandatory')
$validations = @() {
$parameterSets = @() $param_mandatory = $named_argument.Argument.Extent.Text -eq '$true'
$description = $null } else
$helpMessage = $null {
foreach ($attr in $param.Attributes) { $param_parameters += [pscustomobject]@{
switch ($attr.TypeName.Name) { name = $named_argument.ArgumentName
'Parameter' { value = $named_argument.Argument.Extent.Text
}
$mandatory = $false }
$parametersetname = 'Default' }
$position = $null }
$frompipeline = $null "Validate*"
$frompipeline_by_property = $null {
$helpmessage = $null foreach($positional_argument in $attr.PositionalArguments)
{
foreach ($arg in $attr.NamedArguments) { if($positional_argument.ScriptBlock)
switch ($arg.ArgumentName) { {
'Mandatory' { $value = $positional_argument.ScriptBlock.Extent.Text
$mandatory = $arg.Argument.Extent.Text -eq '$true' } else
} {
'Position' { $value = $positional_argument.Value
$position = $arg.Argument.Value }
} $param_validations +=
'ParameterSetName' { [pscustomobject]@{
$parametersetname = $arg.Argument.Value name = $attr.TypeName.Name
} value = $value
'ValueFromPipeline' { }
$frompipeline = $arg.Argument.Extent.Text -eq '$true' }
} }
'ValueFromPipelineByPropertyName' { }
$frompipeline_by_property = $arg.Argument.Extent.Text -eq '$true' } else
} {
'HelpMessage' { if($attr.Extent.Text -like '`[*`]')
$helpMessage = $arg.Argument.Value {
} if($param_type -ne $null)
} {
} Write-Warning "Multiple Types found for Parameter: $($attr.TypeName.Name) ($($Path))"
continue
$paramInfo = @{ }
name = $parametersetname $param_type = $attr.TypeName.Name
mandatory = $mandatory }
} }
}
if($null -ne $position) { $parameters += [pscustomobject]@{
$paramInfo.position = $position name = $param_name
} type = $param_type
mandatory = $param_mandatory
if($null -ne $frompipeline) { arguments = $param_parameters
$paramInfo.valueFromPipeline = $frompipeline validations = $param_validations
} }
if($null -ne $frompipeline_by_property) { }
$paramInfo.valueFromPipelineByPropertyName = $frompipeline_by_property return [pscustomobject]@{
} name = $script_name
path = $script_path
$parameterSets += [pscustomobject]$paramInfo parameters = $parameters
break }
}
'Alias' {
$aliases += $attr.PositionalArguments.Value
break
}
{ $_ -like 'Validate*' } {
$val = @{
type = $attr.TypeName.Name
}
if ($attr.TypeName.Name -eq 'ValidateRange') {
$val.min = $attr.PositionalArguments[0].Value
$val.max = $attr.PositionalArguments[1].Value
} elseif ($attr.TypeName.Name -eq 'ValidateSet') {
$val.values = $attr.PositionalArguments.Value
} elseif ($attr.TypeName.Name -eq 'ValidateScript') {
$val.script = $attr.PositionalArguments.ScriptBlock.Extent.Text
}
$validations += [pscustomobject]$val
break
}
}
}
if ($parameterSets.Count -eq 0) {
$parameterSets += [pscustomobject]@{
name = "Default"
mandatory = $false
}
}
$parameters += [pscustomobject]@{
name = $paramName
type = $paramType
aliases = $aliases
description = $description
helpMessage = $helpMessage
validations = $validations
parameterSets = $parameterSets
}
}
$result = [pscustomobject]@{
name = $script_name
path = $script_path
parameters = $parameters
cmdletBinding = [pscustomobject]@{
defaultParameterSetName = $defaultParamSet ?? "Default"
}
}
return $result
} }

View File

@ -1,48 +0,0 @@
[CmdletBinding(DefaultParameterSetName = 'Set1')]
param (
# Mandatory string with alias and validation, positional
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'Set1')]
[Parameter(Position = 2, Mandatory = $false, ParameterSetName = 'Set2')]
[Alias('n')]
[ValidateNotNullOrEmpty()]
[ValidateScript({
$_ -notlike 'undefined'
})]
[string]$Name,
# Optional int with default value, validated range
[Parameter(ParameterSetName = 'Set1')]
[ValidateRange(1, 100)]
[int]$Count = 10,
# Switch parameter
[Parameter(ParameterSetName = 'Set1')]
[switch]$VerboseMode,
# Accepts pipeline input by value
[Parameter(ValueFromPipeline = $true, ParameterSetName = 'Set2')]
[string]$InputObject,
# Accepts pipeline input by property name
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Set2')]
[string]$Property,
# Parameter that takes an array
[Parameter(ParameterSetName = 'Set1')]
[string[]]$Tags,
# Optional parameter with script block default
[Parameter(ParameterSetName = 'Set1')]
[datetime]$StartTime = (Get-Date),
# Mandatory parameter in a different parameter set
[Parameter(Mandatory = $true, ParameterSetName = 'Set3')]
[ValidateSet('Low', 'Medium', 'High')]
[string]$Priority,
# Nullable type
[Parameter(ParameterSetName = 'Set1')]
[Nullable[bool]]$IsEnabled
)
process {}

View File

@ -32,7 +32,7 @@ mod test {
#[test] #[test]
fn test_parse_powershell_file() { fn test_parse_powershell_file() {
let got = parse_powershell_file("powershell/test-script.ps1"); let got = parse_powershell_file("powershell/get-metadata.ps1");
assert!(got.is_ok()); assert!(got.is_ok());
} }
} }