-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Hierarchical Parameter Scripting #13746
Comments
In general I like the idea to enhance the parameter defining - What about additional level? I mean an optional parameter could require some mandatory/optional subparameters. |
The main reason I'm unsure about this style of declaring params is that you have declare the same parameter multiple times if it happens to be in multiple sets. This creates a greater possibility of mistakes and more confusing UX if a parameter by the same name appears to behave multiple different ways depending on the other parameters specified with it. I would love to see a rework of parameter declaration, but I don't think this is the right direction to go. 🤔 |
Looking at the command syntax it looks like this cmdlet is trying to do too much. A good rule of thumb that I've seen with PowerShell parameter set best practices is that if you're getting this many, maybe its time to create dedicated cmdlets. This many parameter sets is also confusing to the user as the syntax diagram is too complex. For your example the cmdlet could be broken down into multiple cmdlets:
Dedicated color cmdlets can be created to define either of the two color schemes. Then a parameter set can be added to
This can take the 12 parameter sets down to just a couple by going this route. There was also an old RFC that defined mutually exclusive parameters without needing a new parameter set. |
I added more info in #12818. |
@vexx32 and @ThomasNieto, the 'Draw-Shape' is just an extreme example which two mutually exclusive parameter sets almost at the root of the main set.
Yes, there are about 22 (sub)sets in the Taking the parameter-set of the current function WhereObject {
[CmdletBinding()] param()
DynamicParam {
$MandatoryOperators = @(
'CEQ', 'NE', 'CNE', 'GT', 'CGT', 'LT', 'CLT', 'GE', 'CGE', 'LE', 'CLE',
'Like', 'CLike', 'NotLike', 'CNotLike', 'Match', 'CMatch', 'NotMatch', 'CNotMatch',
'Contains', 'CContains', 'NotContains', 'CNotContains',
'In', 'CIn', 'NotIn', 'CNotIn', 'Is', 'IsNot'
)
New-ParamSet @(
New-ParamSet @(
New-ParamSet @(
New-Param 0 ([scriptblock]) FilterScript -Mandatory
New-Param ([psobject]) InputObject
)
)
New-ParamSet @(
New-Param 0 ([string]) Property -Mandatory
New-ParamSet @(
New-Param 1 ([object]) Value
New-Param ([switch]) EQ
New-Param ([psobject]) InputObject
)
foreach ($Operator in $MandatoryOperators) {
New-ParamSet @(
New-Param 1 ([object]) Value
New-Param ([switch]) $Operator -Mandatory
New-Param ([psobject]) InputObject
)
}
)
New-ParamSet @(
New-Param 0 ([string]) Property -Mandatory
New-ParamSet @(
New-Param ([switch]) Not -Mandatory
New-Param ([psobject]) InputObject
)
)
)
}
} |
Yeah, you can do that with Also... just in general, dynamicparam tends to cause more problems that it solves, so IMO any design based on it is generally best avoided (even when prototyping other designs). YMMV I suppose, but I don't think this is an approachable angle for users. |
I have updated the module (see also below the design definitions) which allows a for the intuitive function Test {
[CmdletBinding()] param()
DynamicParam {
New-ParamSet @(
New-Param ([string]) Opt1
New-ParamSet @(
New-Param ([string]) Man1 -Mandatory
New-Param ([string]) Opt2
)
)
}
}
|
Agree, it is not in the intention to align the current
I don't think you can make a fair comparison (yet) between using the the current |
I'd expect symmetric behavior for all levels.
Script and binary developers should get the same capabilities otherwise your work will be only partial research. |
That depends on the actual implementation. In this purpose, I trying to follow the syntax diagram¹, where subsets (
See also below the design definitions and above reworked "What about additional level? I mean an optional parameter could require some mandatory/optional subparameters." answer to @iSazonov. |
I have updated the prototype module to better support optional parameters (see the updated answer to @iSazonov "an optional parameter could require some mandatory/optional subparameters" comment) which also results in a more symmetric behavior (see the updated answer to @vex32 "I'd expect symmetric behavior for all levels" comment). (Sub)set designBelow is the description how the
Note that with each subset iteration, the whole parameter set (including the containing parameter attributes) is cloned. This is to support parameter sets supplied in variable (which eventually require an unique (Sub)set usage:The basic idea of this purpose is to follow the standard parameter syntax diagram similar to the Help (
|
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
2 similar comments
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes. |
Summary of the new feature/enhancement
To complement Feature Idea: Revisiting and extending the ParameterSet Experience #12818
I would like to raise two dissenting ideas:
1. Reverse the set/parameter containment
Personally, I think that the current parameter notation is inside out
Currently, parameters contain parameters sets (each Parameter holds multiple attributes with a
ParametersSetName
)but it should be visa versa: a parameter set should contain parameters.
By turning this around, you might also support (recursive) parameter subsets.
With all respect, adding additional configuration items (like groups and ParameterMutexName) might help to reduce the redundancy but eventually adds up to the complicity when combining them with the existing configuration items.
I even believe that naming parameters sets is inessential if using subsets.
2. Use PowerShell to build parameter sets.
Developers creating cmdlets are already quiet known with PowerShell and need to learn a complete different parameter syntax to get them straight for their functions.
Apart from the fact that you might reduce the redundancy and complexity by using variables and subsets, there is also another advantage in moving to PowerShell scripting: I guess that changes to the current parameter notification (like e.g. groups) will require an update of the PowerShell engine therefor engineers who like to supply some backwards compatibility (with e.g. Windows PowerShell) for their cmdlets/functions might be reluctant to use any new parameter features provided through the current parameter notation. A PowerShell framework using the
DynamicParam
section, might only require installing a module to supply backwards compatibility in customer scripts.Proposed technical implementation details
Let's assume a
Draw-Shape
cmdlet that requires the following parameter (set) constrains:Radius
parameter)Width
and aHeight
parameter)Side1
,Side2
andSide3
- parameters)Transparency
Opacity
Red
Green
Blue
Hue
Sat
Lum
Using the current parameter notation, this requires:
a lot of parameter definitions...
Using this prototype
ParameterFunctions
module, it requires the following knowledge. Sorry, there is no readme yet, but you can use the-?
option to get the syntax and the description below:There are 2 functions included in the module to create parameters and parameter-sets:
New-Parameter
(aliasNew-Param
, orNPM
)This function has 5 main parameters:
[int]$Position
[type]$Type
[string]$Name
[object]$Default
[switch]$Mandatory
Besides has a few parameters like
HelpMessage
to set certain parameter attributes.It has no
ParameterSetName
option!New-ParameterSet
(aliasNew-ParamSet
, orNPS
)Which has two parameters:
[RuntimeDefinedParameterDictionary[]]$ParameterSets
[String]$SetName
(Optional)There can only be one root (default) parameter set (or a single parameter which is quiet pointless).
Each set might contain multiple (optional or mandatory) parameters or multiple (recursive) parameter sets.
Syntax
The basic syntax notation:
[x]
Optional parameter. The command runs whether or not you enter optional parameters.
[x|y]
Select between optional parameters.
<x>
Required option. If you omit a required option, the command line program returns an error message.
<x|y>
Select between required options. For the command to run, you must select from the listed options. If you omit a required option, the command line program returns an error message.
Further steps to come to the final result below you can find in the
Parameters.Test.ps1
:Draw-Shape -?
Caveats
-Static
option which caches theRuntimeDefinedParameterDictionary
)The text was updated successfully, but these errors were encountered: