Skip to content
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

Add UseUsingScopeModifierInNewRunspaces rule #1419

Merged
merged 59 commits into from
Mar 24, 2020

Conversation

Jawz84
Copy link
Contributor

@Jawz84 Jawz84 commented Feb 17, 2020

PR Summary

Fixes #1410

  • write tests
  • write documentation
  • draft rudimentary rule
  • tune rule until all tests for this rule pass (except the test for built-in vars)
  • adapt other rules that start failing
  • add support for built-in variable detection
  • expand functionality to other commands /situations where this check makes sense
    • added support for InlineScript, Start-(Thread)Job and Invoke-Command
  • finetune
  • implement suggested correction (Replace $var with $using:var)
    • add test for suggested correction
  • refactor to AstVisitor/AstVisitor2
  • add support for DSC Script Resource (SetScript, GetScript, TestScript)

PR Checklist

@bergmeister
Copy link
Collaborator

You are on the right track. I suggest to continue focusing on the code of the rule itself. Don't worry about the rest like docs or some other test failures at the moment, they will be easy to fix at the end.

@Jawz84
Copy link
Contributor Author

Jawz84 commented Feb 20, 2020

@bergmeister I've hit a milestone. At this point the code seems to be working as intended. I have added one minor feature which may need to be in a separate PR: I've added the option to use Test-ScriptAnalyzer with a -RuleToTest parameter, so I could easily make adjustments, run .\build.ps1, and run Test-ScriptAnalyzer -RuleToTest 'avoiduni' -ShowAll to check if the change made it worse or better :-).

Can we have a little brainstorm on where this rule may be applied to, other than just for Foreach-Object -Parallel? I'm thinking of maybe Invoke-Command, but other than that? [Edit: a list of commands where this could be applied to can be found here]

Would you like to start a review round at this point, or better after we have a clear picture of how to move forward?

@Jawz84
Copy link
Contributor Author

Jawz84 commented Feb 20, 2020

The failure in Ubuntu 1804 build is the same Authenticode glitch we saw earlier.

@Jawz84
Copy link
Contributor Author

Jawz84 commented Feb 21, 2020

// brainstorm

Other situations where this rule can be applied:

  • Start-Job/Start-ThreadJob -scriptBlock {$using:foo}
    Here the catch is, we need to be sure we check the right scriptblock. The rule does not apply to the -InitializationScript scriptblock parameter.

  • Invoke-Command -ComputerName "baz" -ScriptBlock {$using:foo}
    The catch here, is that the -ComputerName parameter has to be used, otherwise $using is prohibited.
    Also tricky; one can open a persistent session, and use subsequent invoke-command calls to that, where variables previous calls are still valid (more info here)

    $session = new-pssession -computername "baz"
    Invoke-Command -session $session -scriptblock {$foo = "foo" }
    Invoke-Command -session $session -scriptblock {Write-Output $foo} # works
  • workflow bar {$foo = 'foo'; inlinescript {$using:foo} }
    On Windows PowerShell only. (see get-help about_InlineScript)

@Jawz84
Copy link
Contributor Author

Jawz84 commented Feb 21, 2020

@mklement0 thanks for creating the powershell-docs PR for documenting this. That gave me the quick overview I needed. If you have any suggestions, I'd love to hear them, thanks.

@mklement0
Copy link

Thanks, @Jawz84, a great rule to add, and it would be great if it covered the other $using: contexts too (as you outline above).

One pending PR to watch out for: PowerShell/PowerShell#11829, which is trying to eliminate overzealous $using: checks for nested script blocks, as described in PowerShell/PowerShell#11817

As for the terminology in the rule documentation: about_Remote_Variables refers to $using: as the Using scope modifier - it's not a directive.

@Jawz84
Copy link
Contributor Author

Jawz84 commented Feb 21, 2020

Thanks for pointing these out @mklement0 !

@Jawz84 Jawz84 changed the title WIP: 1410 foreach parallel rule 1410 foreach parallel rule Feb 24, 2020
@Jawz84 Jawz84 changed the title 1410 foreach parallel rule WIP: 1410 foreach parallel rule Feb 24, 2020
@Jawz84
Copy link
Contributor Author

Jawz84 commented Feb 24, 2020

The rule is working now. I am not completely satisfied with what the implementation looks like, and I'm likely to do some cleanup and refactor. If @mklement0 or @bergmeister have insights how to best convert this to cleaner code, I'm all ears.

Second question: when starting out, I named the rule AvoidUnInitializedVarsInNewRunspaces Is that the best, most descriptive name for this rule?

@Jawz84
Copy link
Contributor Author

Jawz84 commented Mar 14, 2020

@rjmholt I've been thinking about what to optimize, and especially: how to measure if it has worked. When I run tests, most are around 15ms, but some stand out and take longer:
image
I have tried Visual Studios profiling tool and the diagnostic tools, but none the wiser really. How do I visualise which codepaths make the Non-DSC function with the name SetScript {} test take 156ms instead of the more typical 15ms?

@Jawz84
Copy link
Contributor Author

Jawz84 commented Mar 18, 2020

@rjmholt did you have a chance to look at this yet? I'm starting to fear we might be accidentally waiting for each other

Rules/Strings.resx Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Rules/UseUsingScopeModifierInNewRunspaces.cs Outdated Show resolved Hide resolved
Jawz84 and others added 4 commits March 19, 2020 20:26
Co-Authored-By: Robert Holt <rjmholt@gmail.com>
Co-Authored-By: Robert Holt <rjmholt@gmail.com>
Co-Authored-By: Robert Holt <rjmholt@gmail.com>
refactoring FindVarsInAssignmentAsts to return a dictionary in progress
@Jawz84
Copy link
Contributor Author

Jawz84 commented Mar 19, 2020

Really enjoying your feedback @rjmholt! I am learning a lot.

Jos Koelewijn added 3 commits March 20, 2020 14:31
refactoredFindVarsInAssignmentAsts to return a dictionary
…el_rule' into 1410_foreach_parallel_rule

fix merge conflict
@Jawz84
Copy link
Contributor Author

Jawz84 commented Mar 20, 2020

@rjmholt back over to you, all good here.

@Jawz84
Copy link
Contributor Author

Jawz84 commented Mar 24, 2020

@bergmeister, @rjmholt thanks for all the reviews. Is there anything more I can do here? I am uncertain what the next step is. Is this blocked on review from @JamesWTruher?
Thanks in advance for enlightening me 🙂

@bergmeister
Copy link
Collaborator

I think having at least one reviewer from Microsoft is good enough, this is our unwritten rule, so I'll therefore merge. Congrats and thanks for your hard work

@bergmeister bergmeister merged commit 791ee64 into PowerShell:master Mar 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New rule for ForEach-Object -Parallel that helps users pinpoint problems with their variable scoping
4 participants