Add new AvoidDynamicallyCreatingVariableNames rule#2178
Add new AvoidDynamicallyCreatingVariableNames rule#2178iRon7 wants to merge 11 commits intoPowerShell:mainfrom
Conversation
|
👋 I get that this rule is warning against using New-\Set-Variable with a non-constant name. What's the issue with dynamic variable names? Could someone use the variable drive and I think I have one bit of code in an internal module that this rule would flag. It basically hoists a bunch of variables into a caller-visible scope. I think it's perfectly legitimate? The gist of it is: foreach ($name in $NamesToExpose) {
Set-Variable -Scope Script -Name $name -Value $data[$name]
}That aside... This misses alias-based creation and update calls. e.g. There's a helper function for this: PSScriptAnalyzer/Engine/Helper.cs Lines 216 to 233 in a143b9f And a sample usage here: PSScriptAnalyzer/Rules/AvoidGlobalAliases.cs Lines 95 to 96 in a143b9f You have the same copy-pasta in the class and I know it works as you're statically invoking parameter binding - but perhaps a test which uses positional binding |
|
Thank you for your feedback, |
Co-authored-by: Copilot <copilot@github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new built-in PSScriptAnalyzer rule intended to discourage dynamically created variable names (favoring hashtables/dictionaries), along with documentation and Pester coverage.
Changes:
- Add new
AvoidDynamicallyCreatingVariableNamesrule implementation and localized strings. - Add rule documentation page and include it in the rules index.
- Add Pester tests covering violations, compliant cases, and suppression.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/Rules/README.md | Adds the new rule to the published rules list. |
| docs/Rules/AvoidDynamicallyCreatingVariableNames.md | Introduces end-user documentation and examples for the new rule. |
| Tests/Rules/AvoidDynamicallyCreatingVariableNames.tests.ps1 | Adds test coverage for rule detection and suppression behavior. |
| Rules/Strings.resx | Adds name/common name/description/error strings for the rule. |
| Rules/AvoidDynamicallyCreatingVariableNames.cs | Implements the new analyzer rule logic for detecting dynamic New-Variable -Name usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
It is meant as a best practice guidance for users that are not known with hash tables, as in e.g. https://stackoverflow.com/q/68827910/1701026. There are probably a lot of ways around it but I am not trying to completely close the door on dynamically creating variable names, but only want to prevent beginners from unknowingly choosing the wrong direction and possibly run into a pitfall. I don't think that the audience I am trying to reach with this rule will use something like
Yes, your example of
Implemented
Changed
Added And now Copilot also kicks in with suggestions... will I ever be able to finish this? 😆 |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
There was a problem hiding this comment.
Thanks @iRon7, and thanks @liamjpeters for the deep review on this one — I think your back-and-forth genuinely improved the rule (narrowing scope to New-Variable, picking up the alias coverage via Helper.CmdletNameAndAliases, dropping severity to Information). All of Liam's points look addressed.
Two follow-ups before I'm comfortable merging:
Opt-in by default. This rule is still derived from IScriptRule, which means it's enabled-by-default for everyone. For a new rule — especially one at Information severity that is going to flag any New-Variable -Name $name in dynamic-config / metaprogramming-style scripts — our convention is to ship it opt-in via ConfigurableRule with Enable = false. Same recipe as AvoidExclaimOperator. Could you switch the base class and update docs/Rules/README.md accordingly?
Second maintainer read. Now that the scope is narrowed to just New-Variable, I'd like @bergmeister or @michaeltlombardi to weigh in on whether the rule still earns its keep at this scope, or whether it would be better recombined with the dynamic Set-Item Variable:\… form. Either answer is fine with me — just want a second pair of eyes on the design question before we land it.
Drafted by Copilot (Claude Opus 4.7)
PR Summary
New rule to push for the use of hash tables rather than dynamically creating vriables in the general variable pool.
See also: https://stackoverflow.com/a/68830451/1701026
PR Checklist
.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.