-
Notifications
You must be signed in to change notification settings - Fork 234
Run new PSReadLine test on Windows #1522
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
Conversation
088fdb6
to
85e60dd
Compare
This reverts commit 75a7175. We are reverting this in favor of using a runtime condition set by the test itself because this was fragile (for one, it did not work with OmniSharp running tests).
d41e90e
to
d03f3d0
Compare
Finally stole your code @dkattan |
e615399
to
ed5f1ba
Compare
var psReadLineType = Type.GetType("Microsoft.PowerShell.PSConsoleReadLine, Microsoft.PowerShell.PSReadLine2"); | ||
|
||
if (psReadLineType == null) | ||
{ | ||
logger.LogWarning("PSConsoleReadline type not found: {Reason}", pwsh.HadErrors ? pwsh.Streams.Error[0].ToString() : "<Unknown reason>"); | ||
return false; | ||
logger.LogTrace("PSConsoleReadline type not found using Type.GetType(), searching all loaded assemblies..."); |
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.
@rjmholt This should only happen in the case that it needs to. When Type.GetType
works, then this logic is skipped. So it feels fine, though I still wish I knew why it was necessary.
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.
Not saying it's "right" but I keep seeing code similar to this come up when I research the issue. I think we will get to the bottom of it as we continue to refactor but this works.
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.
My suspicion is that this always worked in script because it always runs on the pipeline thread and through PowerShell's own type search logic. When we sift through the whole AppDomain (which is kind of a dead concept) for a type, we ignore assembly load contexts, and so that might be why the direction reflection query fails but the search succeeds. Just a theory though. An ALC shouldn't be thread-dependent though and I don't think anyone is using something like EnterContextualReflection()
{ | ||
Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); |
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.
For so many reasons 😆
5e350a3
to
06893e7
Compare
@@ -2129,75 +2144,6 @@ private static string GetStringForPSCommand(PSCommand psCommand) | |||
return stringBuilder.ToString(); | |||
} | |||
|
|||
private void SetExecutionPolicy() |
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.
Huge fan of removing this and relying on the initialSessionState. I look forward to bringing the entire InitialSessionState in instead of just the LanguageMode so we more accurately create runspaces similar to the parent.
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.
Looks good!
src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs
Outdated
Show resolved
Hide resolved
@rjmholt I've been looking at |
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); | ||
var assemblies = allAssemblies.FirstOrDefault(a => a.FullName.Contains("Microsoft.PowerShell.PSReadLine2")); | ||
psReadLineType = assemblies?.ExportedTypes?.FirstOrDefault(a => a.FullName == "Microsoft.PowerShell.PSConsoleReadLine"); |
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.
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); | |
var assemblies = allAssemblies.FirstOrDefault(a => a.FullName.Contains("Microsoft.PowerShell.PSReadLine2")); | |
psReadLineType = assemblies?.ExportedTypes?.FirstOrDefault(a => a.FullName == "Microsoft.PowerShell.PSConsoleReadLine"); | |
Type psrlType = AppDomain.CurrentDomain | |
.GetAssemblies() | |
.FirstOrDefault(asm => asm.GetName().Name.Equals("Microsoft.PowerShell.PSReadLine2")) | |
?.ExportedTypes | |
?.FirstOrDefault(type => type.FullName.Equals("Microsoft.PowerShell.PSConsoleReadLine")); |
var psReadLineType = Type.GetType("Microsoft.PowerShell.PSConsoleReadLine, Microsoft.PowerShell.PSReadLine2"); | ||
|
||
if (psReadLineType == null) | ||
{ | ||
logger.LogWarning("PSConsoleReadline type not found: {Reason}", pwsh.HadErrors ? pwsh.Streams.Error[0].ToString() : "<Unknown reason>"); | ||
return false; | ||
logger.LogTrace("PSConsoleReadline type not found using Type.GetType(), searching all loaded assemblies..."); |
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.
My suspicion is that this always worked in script because it always runs on the pipeline thread and through PowerShell's own type search logic. When we sift through the whole AppDomain (which is kind of a dead concept) for a type, we ignore assembly load contexts, and so that might be why the direction reflection query fails but the search succeeds. Just a theory though. An ALC shouldn't be thread-dependent though and I don't think anyone is using something like EnterContextualReflection()
338c3f4
to
19a9a8f
Compare
This eliminates the need to have `SetExecutionPolicy` which is a slow function that first queries a bunch of policies and then within PowerShell itself (as in, using a cmdlet) sets it to `Bypass`. However, we just want the process scope (AKA runspace scope) to have the execution policy set to `Bypass` all the time so that we can import our bundled modules, such as PSReadLine.
xUnit infuriatingly defaults to using its own custom app domains (and thus shadow copying of assemblies), which completely messes up our assembly locations, our ability to find modules such as PSReadLine, and resolving types from PSReadLine too. We were not actually configuing xUnit correctly either.
This is sometimes necessary (especially in CI). Co-authored-by: Andrew Schwartzmeyer <[email protected]>
This also simplifies our testing scenario where that path needs to be configured at runtime, too. Co-authored-by: Andrew Schwartzmeyer <[email protected]>
19a9a8f
to
f911ef1
Compare
So to actually assert that we now respect "powershell.developer.bundledModulesPath": "/Users/andschwa/Downloads/PowerShellEditorServices" Two things have to be true: 1. the extension must be run in the VS Code debugger (such that "developer" is honored) and 2. a previous dev was "smart" and added silent fallback logic to use the extension's path if the supplied |
// behavior for consistency such that unit tests can pass in a similar environment. | ||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
{ | ||
initialSessionState.ExecutionPolicy = ExecutionPolicy.Bypass; |
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.
@dkattan So we resurrected the SetExecutionPolicy()
function because on closer inspection, the actual issue was that in the unit test scenario we weren't having Bypass
set (because the codebase's expectation is that the startup script is run with -ExecutionPolicy Bypass
, like what the extension does), and the SetExecutionPolicy()
actually sets the execution policy back to the original inherited scoped policy, not the process policy. That is, it override's the process/runspace's policy after everything is loaded to be equivalent to the user's machine/user policy.
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.
@rjmholt I might rename that function ResetExecutionPolicy()
😆
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.
That works. I'm a fan of removing large chunks of code, as long as it doesn't change expected functionality :D
This redoes prior work that was lost during the rewrite. Specifically this actually respects the user configuration of `BundledModulePath` (also used by unit tests to provide compatibililty with xUnit), and forces the use of only our bundled PSReadLine dependency. Essentially this redoes #1514 and #1522.
This redoes prior work that was lost during the rewrite. Specifically this actually respects the user configuration of `BundledModulePath` (also used by unit tests to provide compatibililty with xUnit), and forces the use of only our bundled PSReadLine dependency. Essentially this redoes #1514 and #1522.
Finishing #1514. Also replaces #1516.