From 26818b3bf370fffab9fe0f43d7734c49000a1bfe Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Mon, 28 Jun 2021 09:24:14 -0500 Subject: [PATCH 01/15] Added BundledModulesPath to HostStartupInfo object and if it is valid, use it. --- .../Internal/EditorServicesRunner.cs | 3 ++- .../Hosting/HostStartupInfo.cs | 10 +++++-- .../PowerShellContextService.cs | 27 +++++++++++++++---- .../PowerShellContextFactory.cs | 6 ++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs b/src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs index b4dbf7c63..e49da8527 100644 --- a/src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs +++ b/src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs @@ -292,7 +292,8 @@ private HostStartupInfo CreateHostStartupInfo() _config.LogPath, (int)_config.LogLevel, consoleReplEnabled: _config.ConsoleRepl != ConsoleReplKind.None, - usesLegacyReadLine: _config.ConsoleRepl == ConsoleReplKind.LegacyReadLine); + usesLegacyReadLine: _config.ConsoleRepl == ConsoleReplKind.LegacyReadLine, + bundledModulePath: _config.BundledModulePath); } private void WriteStartupBanner() diff --git a/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs b/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs index 5f3ae7647..13f0ae77a 100644 --- a/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs +++ b/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs @@ -106,7 +106,10 @@ public sealed class HostStartupInfo /// cref="Serilog.Events.LogEventLevel"/>, hence it is an int. /// public int LogLevel { get; } - + /// + /// The path to find the Bundled Modules /// + /// + public string BundledModulePath { get; } #endregion #region Constructors @@ -135,6 +138,7 @@ public sealed class HostStartupInfo /// The minimum log event level. /// Enable console if true. /// Use PSReadLine if false, otherwise use the legacy readline implementation. + /// The path to the Modules folder, helps with loading the bundled PSReadLine and other included modules public HostStartupInfo( string name, string profileId, @@ -147,7 +151,9 @@ public HostStartupInfo( string logPath, int logLevel, bool consoleReplEnabled, - bool usesLegacyReadLine) + bool usesLegacyReadLine, + string bundledModulePath + ) { Name = name ?? DefaultHostName; ProfileId = profileId ?? DefaultHostProfileId; diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index a6ea9ee45..67c782694 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -32,10 +32,18 @@ namespace Microsoft.PowerShell.EditorServices.Services /// internal class PowerShellContextService : IHostSupportsInteractiveSession { - private static readonly string s_commandsModulePath = Path.GetFullPath( + private static string s_bundledModulesPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", ".."); + + private static string s_commandsModulePath => Path.GetFullPath( + Path.Combine( + s_bundledModulesPath, + "PowerShellEditorServices", + "Commands", + "PowerShellEditorServices.Commands.psd1")); + private static string _psReadLineModulePath => Path.GetFullPath( Path.Combine( - Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), - "../../Commands/PowerShellEditorServices.Commands.psd1")); + s_bundledModulesPath, + "PSReadLine")); private static readonly Action s_runspaceApartmentStateSetter; private static readonly PropertyInfo s_writeStreamProperty; @@ -190,7 +198,10 @@ public static PowerShellContextService Create( HostStartupInfo hostStartupInfo) { Validate.IsNotNull(nameof(hostStartupInfo), hostStartupInfo); - + s_bundledModulesPath = !string.IsNullOrEmpty(hostStartupInfo.BundledModulePath) && Directory.Exists(hostStartupInfo.BundledModulePath) + ? hostStartupInfo.BundledModulePath + : s_bundledModulesPath = hostStartupInfo.BundledModulePath; + var logger = factory.CreateLogger(); bool shouldUsePSReadLine = hostStartupInfo.ConsoleReplEnabled @@ -220,7 +231,13 @@ public static PowerShellContextService Create( // TODO: This can be moved to the point after the $psEditor object // gets initialized when that is done earlier than LanguageServer.Initialize - foreach (string module in hostStartupInfo.AdditionalModules) + var modulesToImport = new List(); + if(hostStartupInfo.ConsoleReplEnabled) + { + modulesToImport.Add(_psReadLineModulePath); + } + modulesToImport.AddRange(hostStartupInfo.AdditionalModules); + foreach (string module in modulesToImport) { var command = new PSCommand() diff --git a/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs b/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs index c08142ebd..7ade7c758 100644 --- a/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs +++ b/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs @@ -31,6 +31,9 @@ internal static class PowerShellContextFactory TestUtilities.NormalizePath("../../../../PowerShellEditorServices.Test.Shared/Test.PowerShellEditorServices_profile.ps1")), Path.GetFullPath( TestUtilities.NormalizePath("../../../../PowerShellEditorServices.Test.Shared/ProfileTest.ps1"))); + public static readonly string BundledModulesPath = + Path.GetFullPath( + TestUtilities.NormalizePath("../../../../../module")); public static PowerShellContextService Create(ILogger logger) { @@ -48,7 +51,8 @@ public static PowerShellContextService Create(ILogger logger) null, 0, consoleReplEnabled: false, - usesLegacyReadLine: false); + usesLegacyReadLine: false, + bundledModulePath: BundledModulesPath); powerShellContext.Initialize( From 28880452c848a73c47764e2eca0bc1917a398adb Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Wed, 30 Jun 2021 14:06:28 -0500 Subject: [PATCH 02/15] Fixed s_bundledModulesPath assignment. --- .../Services/PowerShellContext/PowerShellContextService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 67c782694..812f39338 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -200,7 +200,7 @@ public static PowerShellContextService Create( Validate.IsNotNull(nameof(hostStartupInfo), hostStartupInfo); s_bundledModulesPath = !string.IsNullOrEmpty(hostStartupInfo.BundledModulePath) && Directory.Exists(hostStartupInfo.BundledModulePath) ? hostStartupInfo.BundledModulePath - : s_bundledModulesPath = hostStartupInfo.BundledModulePath; + : s_bundledModulesPath; var logger = factory.CreateLogger(); From e590fadc7bedd0f0cf88ef37832a2b3c5a746495 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 06:52:08 -0500 Subject: [PATCH 03/15] Fixed missing BundledModulesPath parameter assignment --- .../{PowerShellEditorServices.Commands.psd1 => Commands.psd1} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename module/PowerShellEditorServices/Commands/{PowerShellEditorServices.Commands.psd1 => Commands.psd1} (100%) diff --git a/module/PowerShellEditorServices/Commands/PowerShellEditorServices.Commands.psd1 b/module/PowerShellEditorServices/Commands/Commands.psd1 similarity index 100% rename from module/PowerShellEditorServices/Commands/PowerShellEditorServices.Commands.psd1 rename to module/PowerShellEditorServices/Commands/Commands.psd1 From 52b16ca9d44afe8ca8a55aea43ac13bab67effc3 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 06:55:33 -0500 Subject: [PATCH 04/15] Restored PowerShellEditorServices.Commands.psd1 --- .../{Commands.psd1 => PowerShellEditorServices.Commands.psd1} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename module/PowerShellEditorServices/Commands/{Commands.psd1 => PowerShellEditorServices.Commands.psd1} (100%) diff --git a/module/PowerShellEditorServices/Commands/Commands.psd1 b/module/PowerShellEditorServices/Commands/PowerShellEditorServices.Commands.psd1 similarity index 100% rename from module/PowerShellEditorServices/Commands/Commands.psd1 rename to module/PowerShellEditorServices/Commands/PowerShellEditorServices.Commands.psd1 From d8738f044d45f1c017011a57863f6e5404e27111 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 07:07:52 -0500 Subject: [PATCH 05/15] removed #if TEST from PowerShellContextService.cs and instead provided the path as a parameter to PowerShellContextService.TryGetPSReadLineProxy() --- .../PowerShellContextService.cs | 8 ++++---- .../Session/PSReadLinePromptContext.cs | 16 ++-------------- .../Session/PowerShellContextTests.cs | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 9036efbf8..ab58ec7e1 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -226,7 +226,7 @@ public static PowerShellContextService Create( logger.LogTrace("Creating initial PowerShell runspace"); Runspace initialRunspace = PowerShellContextService.CreateRunspace(psHost, hostStartupInfo.LanguageMode); - powerShellContext.Initialize(hostStartupInfo.ProfilePaths, initialRunspace, true, hostUserInterface); + powerShellContext.Initialize(hostStartupInfo, initialRunspace, true, hostUserInterface); powerShellContext.ImportCommandsModuleAsync(); // TODO: This can be moved to the point after the $psEditor object @@ -322,7 +322,7 @@ public static Runspace CreateRunspace(PSHost psHost, PSLanguageMode languageMode /// If true, the PowerShellContext owns this runspace. /// An IHostOutput implementation. Optional. public void Initialize( - ProfilePathInfo profilePaths, + HostStartupInfo hostStartupInfo, Runspace initialRunspace, bool ownsInitialRunspace, IHostOutput consoleHost) @@ -376,7 +376,7 @@ public void Initialize( this.ConfigureRunspaceCapabilities(this.CurrentRunspace); // Set the $profile variable in the runspace - this.profilePaths = profilePaths; + this.profilePaths = hostStartupInfo.ProfilePaths; if (profilePaths != null) { this.SetProfileVariableInCurrentRunspace(profilePaths); @@ -413,7 +413,7 @@ public void Initialize( if (powerShellVersion.Major >= 5 && this.isPSReadLineEnabled && - PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, out PSReadLineProxy proxy)) + PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, hostStartupInfo.BundledModulePath, out PSReadLineProxy proxy)) { this.PromptContext = new PSReadLinePromptContext( this, diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs index 5f4931854..71455e4d5 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs @@ -17,20 +17,6 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShellContext internal class PSReadLinePromptContext : IPromptContext { - private static readonly string _psReadLineModulePath = Path.Combine( - Path.GetDirectoryName(typeof(PSReadLinePromptContext).Assembly.Location), - "..", - "..", - "..", -#if TEST - // When using xUnit (dotnet test) the assemblies are deployed to the - // test project folder, invalidating our relative path assumption. - "..", - "..", - "module", -#endif - "PSReadLine"); - private static readonly Lazy s_lazyInvokeReadLineForEditorServicesCmdletInfo = new Lazy(() => { var type = Type.GetType("Microsoft.PowerShell.EditorServices.Commands.InvokeReadLineForEditorServicesCommand, Microsoft.PowerShell.EditorServices.Hosting"); @@ -79,9 +65,11 @@ internal PSReadLinePromptContext( internal static bool TryGetPSReadLineProxy( ILogger logger, Runspace runspace, + string bundledModulePath, out PSReadLineProxy readLineProxy) { readLineProxy = null; + string _psReadLineModulePath = Path.Combine(bundledModulePath, "PSReadLine"); logger.LogTrace("Attempting to load PSReadLine"); using (var pwsh = PowerShell.Create()) { diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 4cf1fef8c..5eb6e3cf6 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Management.Automation; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.Extensions.Logging.Abstractions; @@ -152,10 +153,18 @@ await this.powerShellContext.ExecuteCommandAsync( public async Task CanGetPSReadLineProxy() { Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); + string s_bundledModulesPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + "..", + "..", + "..", + "..", + "module" + ); Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy( - NullLogger.Instance, - PowerShellContextFactory.initialRunspace, - out PSReadLineProxy proxy)); + NullLogger.Instance, + PowerShellContextFactory.initialRunspace, + s_bundledModulesPath, + out PSReadLineProxy proxy)); } #region Helper Methods From ee154b0445f612f137baaa74f159c091e7a10a4e Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 07:07:52 -0500 Subject: [PATCH 06/15] removed #if TEST from PowerShellContextService.cs and instead provided the path as a parameter to PowerShellContextService.TryGetPSReadLineProxy() --- .../PowerShellContextService.cs | 8 ++++---- .../Session/PSReadLinePromptContext.cs | 16 ++-------------- .../PowerShellContextFactory.cs | 2 +- .../Session/PowerShellContextTests.cs | 15 ++++++++++++--- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 9036efbf8..ab58ec7e1 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -226,7 +226,7 @@ public static PowerShellContextService Create( logger.LogTrace("Creating initial PowerShell runspace"); Runspace initialRunspace = PowerShellContextService.CreateRunspace(psHost, hostStartupInfo.LanguageMode); - powerShellContext.Initialize(hostStartupInfo.ProfilePaths, initialRunspace, true, hostUserInterface); + powerShellContext.Initialize(hostStartupInfo, initialRunspace, true, hostUserInterface); powerShellContext.ImportCommandsModuleAsync(); // TODO: This can be moved to the point after the $psEditor object @@ -322,7 +322,7 @@ public static Runspace CreateRunspace(PSHost psHost, PSLanguageMode languageMode /// If true, the PowerShellContext owns this runspace. /// An IHostOutput implementation. Optional. public void Initialize( - ProfilePathInfo profilePaths, + HostStartupInfo hostStartupInfo, Runspace initialRunspace, bool ownsInitialRunspace, IHostOutput consoleHost) @@ -376,7 +376,7 @@ public void Initialize( this.ConfigureRunspaceCapabilities(this.CurrentRunspace); // Set the $profile variable in the runspace - this.profilePaths = profilePaths; + this.profilePaths = hostStartupInfo.ProfilePaths; if (profilePaths != null) { this.SetProfileVariableInCurrentRunspace(profilePaths); @@ -413,7 +413,7 @@ public void Initialize( if (powerShellVersion.Major >= 5 && this.isPSReadLineEnabled && - PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, out PSReadLineProxy proxy)) + PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, hostStartupInfo.BundledModulePath, out PSReadLineProxy proxy)) { this.PromptContext = new PSReadLinePromptContext( this, diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs index 5f4931854..71455e4d5 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs @@ -17,20 +17,6 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShellContext internal class PSReadLinePromptContext : IPromptContext { - private static readonly string _psReadLineModulePath = Path.Combine( - Path.GetDirectoryName(typeof(PSReadLinePromptContext).Assembly.Location), - "..", - "..", - "..", -#if TEST - // When using xUnit (dotnet test) the assemblies are deployed to the - // test project folder, invalidating our relative path assumption. - "..", - "..", - "module", -#endif - "PSReadLine"); - private static readonly Lazy s_lazyInvokeReadLineForEditorServicesCmdletInfo = new Lazy(() => { var type = Type.GetType("Microsoft.PowerShell.EditorServices.Commands.InvokeReadLineForEditorServicesCommand, Microsoft.PowerShell.EditorServices.Hosting"); @@ -79,9 +65,11 @@ internal PSReadLinePromptContext( internal static bool TryGetPSReadLineProxy( ILogger logger, Runspace runspace, + string bundledModulePath, out PSReadLineProxy readLineProxy) { readLineProxy = null; + string _psReadLineModulePath = Path.Combine(bundledModulePath, "PSReadLine"); logger.LogTrace("Attempting to load PSReadLine"); using (var pwsh = PowerShell.Create()) { diff --git a/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs b/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs index 7a5a99272..5fd8ecbd1 100644 --- a/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs +++ b/test/PowerShellEditorServices.Test/PowerShellContextFactory.cs @@ -63,7 +63,7 @@ public static PowerShellContextService Create(ILogger logger) logger); powerShellContext.Initialize( - TestProfilePaths, + testHostDetails, initialRunspace, ownsInitialRunspace: true, consoleHost: null); diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 4cf1fef8c..5eb6e3cf6 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Management.Automation; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.Extensions.Logging.Abstractions; @@ -152,10 +153,18 @@ await this.powerShellContext.ExecuteCommandAsync( public async Task CanGetPSReadLineProxy() { Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); + string s_bundledModulesPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + "..", + "..", + "..", + "..", + "module" + ); Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy( - NullLogger.Instance, - PowerShellContextFactory.initialRunspace, - out PSReadLineProxy proxy)); + NullLogger.Instance, + PowerShellContextFactory.initialRunspace, + s_bundledModulesPath, + out PSReadLineProxy proxy)); } #region Helper Methods From 77186f0d0aa663faba48a704fe5244d2fe25ce46 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 09:26:39 -0500 Subject: [PATCH 07/15] Added logging to CanGetPSReadLineProxy test --- .../Session/PowerShellContextTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 5eb6e3cf6..41d2f9c4e 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -160,6 +160,7 @@ public async Task CanGetPSReadLineProxy() "..", "module" ); + System.Console.WriteLine($"Attempting to import {s_bundledModulesPath}"); Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy( NullLogger.Instance, PowerShellContextFactory.initialRunspace, From 48d1a96d2993b5eeddd666597ad0dd23b18db557 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 16:54:52 -0500 Subject: [PATCH 08/15] Adjusted BundledModulesPath, re-enabled Windows test. --- .../Session/PowerShellContextTests.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 41d2f9c4e..6b9a08db6 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -152,15 +152,16 @@ await this.powerShellContext.ExecuteCommandAsync( [SkippableFact] public async Task CanGetPSReadLineProxy() { - Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); - string s_bundledModulesPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + //Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); + string s_bundledModulesPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + "..", "..", "..", "..", "..", "module" - ); - System.Console.WriteLine($"Attempting to import {s_bundledModulesPath}"); + )); + System.Console.WriteLine($"Attempting to import {s_bundledModulesPath}\\PSReadLine"); Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy( NullLogger.Instance, PowerShellContextFactory.initialRunspace, From 7037115c8e070d6fab4844299dcd06f89348333f Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 17:29:59 -0500 Subject: [PATCH 09/15] Added more logging to tests, implemented additional mechanism to find PSReadLine --- .../Session/PSReadLinePromptContext.cs | 18 +++++++++++++++++- .../Session/PowerShellContextTests.cs | 11 ++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs index 71455e4d5..8e39b14bf 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs @@ -83,9 +83,24 @@ internal static bool TryGetPSReadLineProxy( if (psReadLineType == null) { logger.LogWarning("PSConsoleReadline type not found: {Reason}", pwsh.HadErrors ? pwsh.Streams.Error[0].ToString() : ""); - return false; + System.Console.WriteLine("psReadLineType is null, searching loaded assemblies..."); + + var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = allAssemblies.FirstOrDefault(a => a.FullName.Contains("Microsoft.PowerShell.PSReadLine2")); + var type = assemblies?.ExportedTypes?.FirstOrDefault(a => a.FullName == "Microsoft.PowerShell.PSConsoleReadLine"); + if(type is not null) + { + System.Console.WriteLine("Found PSConsoleReadLine in loaded assemblies."); + psReadLineType = type; + } + else + { + Console.WriteLine("Unable to find PSConsoleReadLine in loaded assembles."); + return false; + } } + try { readLineProxy = new PSReadLineProxy(psReadLineType, logger); @@ -96,6 +111,7 @@ internal static bool TryGetPSReadLineProxy( // Could be an older version, a custom build, or something a newer version with // breaking changes. logger.LogWarning("PSReadLineProxy unable to be initialized: {Reason}", e); + System.Console.WriteLine("PSReadLineProxy unable to be initialized"); return false; } } diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 6b9a08db6..64ac16cbb 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -153,7 +153,13 @@ await this.powerShellContext.ExecuteCommandAsync( public async Task CanGetPSReadLineProxy() { //Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); - string s_bundledModulesPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + var executingAssembly = Assembly.GetExecutingAssembly().Location; + System.Console.WriteLine($"executingAssembly {executingAssembly}"); + var directory = Path.GetDirectoryName(executingAssembly); + System.Console.WriteLine($"directory: {directory}"); + System.Console.WriteLine($"{Directory.GetDirectories(directory)}"); + System.Console.WriteLine($"{Directory.GetFiles(directory)}"); + string s_bundledModulesPath = Path.GetFullPath(Path.Combine(directory, "..", "..", "..", @@ -161,6 +167,9 @@ public async Task CanGetPSReadLineProxy() "..", "module" )); + System.Console.WriteLine($"s_bundledModulesPath: {s_bundledModulesPath}"); + System.Console.WriteLine($"{Directory.GetDirectories(s_bundledModulesPath)}"); + System.Console.WriteLine($"{Directory.GetFiles(s_bundledModulesPath)}"); System.Console.WriteLine($"Attempting to import {s_bundledModulesPath}\\PSReadLine"); Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy( NullLogger.Instance, From a0fa3c5e5bd7be3367a9873805ddb4683dd3ea8a Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 17:44:34 -0500 Subject: [PATCH 10/15] Implemented fix to find the non VSS cached location of the executing DLL on Windows --- .../Session/PowerShellContextTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 64ac16cbb..16000ea90 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -153,7 +153,7 @@ await this.powerShellContext.ExecuteCommandAsync( public async Task CanGetPSReadLineProxy() { //Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); - var executingAssembly = Assembly.GetExecutingAssembly().Location; + var executingAssembly = Assembly.GetExecutingAssembly().GetName().CodeBase; System.Console.WriteLine($"executingAssembly {executingAssembly}"); var directory = Path.GetDirectoryName(executingAssembly); System.Console.WriteLine($"directory: {directory}"); From 1443baa1d15a3ff9ca831575f8b61e60bef8fd1d Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 17:44:34 -0500 Subject: [PATCH 11/15] Implemented fix to find the non VSS cached location of the executing DLL on Windows --- .../Session/PowerShellContextTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 64ac16cbb..622e9259f 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -152,10 +152,7 @@ await this.powerShellContext.ExecuteCommandAsync( [SkippableFact] public async Task CanGetPSReadLineProxy() { - //Skip.If(IsWindows, "This test doesn't work on Windows for some reason."); - var executingAssembly = Assembly.GetExecutingAssembly().Location; - System.Console.WriteLine($"executingAssembly {executingAssembly}"); - var directory = Path.GetDirectoryName(executingAssembly); + var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.RelativeSearchPath ?? ""); System.Console.WriteLine($"directory: {directory}"); System.Console.WriteLine($"{Directory.GetDirectories(directory)}"); System.Console.WriteLine($"{Directory.GetFiles(directory)}"); From bda40eafcef2da9b80e56fe4da6547af13813a07 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 18:35:53 -0500 Subject: [PATCH 12/15] Cleaned up logging --- .../PowerShellContext/Session/PSReadLinePromptContext.cs | 9 ++++----- .../Session/PowerShellContextTests.cs | 7 ------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs index 8e39b14bf..3633ad1d3 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs @@ -82,20 +82,19 @@ internal static bool TryGetPSReadLineProxy( if (psReadLineType == null) { - logger.LogWarning("PSConsoleReadline type not found: {Reason}", pwsh.HadErrors ? pwsh.Streams.Error[0].ToString() : ""); - System.Console.WriteLine("psReadLineType is null, searching loaded assemblies..."); - + logger.LogWarning("PSConsoleReadline type not found using Type.GetType(): {Reason}", pwsh.HadErrors ? pwsh.Streams.Error[0].ToString() : ""); + logger.LogWarning("Searching loaded assemblies..."); var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); var assemblies = allAssemblies.FirstOrDefault(a => a.FullName.Contains("Microsoft.PowerShell.PSReadLine2")); var type = assemblies?.ExportedTypes?.FirstOrDefault(a => a.FullName == "Microsoft.PowerShell.PSConsoleReadLine"); if(type is not null) { - System.Console.WriteLine("Found PSConsoleReadLine in loaded assemblies."); + logger.LogInformation("Found PSConsoleReadLine in loaded assemblies."); psReadLineType = type; } else { - Console.WriteLine("Unable to find PSConsoleReadLine in loaded assembles."); + logger.LogError("Unable to find PSConsoleReadLine in loaded assembles."); return false; } } diff --git a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs index 622e9259f..16043aaac 100644 --- a/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs +++ b/test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs @@ -153,9 +153,6 @@ await this.powerShellContext.ExecuteCommandAsync( public async Task CanGetPSReadLineProxy() { var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.RelativeSearchPath ?? ""); - System.Console.WriteLine($"directory: {directory}"); - System.Console.WriteLine($"{Directory.GetDirectories(directory)}"); - System.Console.WriteLine($"{Directory.GetFiles(directory)}"); string s_bundledModulesPath = Path.GetFullPath(Path.Combine(directory, "..", "..", @@ -164,10 +161,6 @@ public async Task CanGetPSReadLineProxy() "..", "module" )); - System.Console.WriteLine($"s_bundledModulesPath: {s_bundledModulesPath}"); - System.Console.WriteLine($"{Directory.GetDirectories(s_bundledModulesPath)}"); - System.Console.WriteLine($"{Directory.GetFiles(s_bundledModulesPath)}"); - System.Console.WriteLine($"Attempting to import {s_bundledModulesPath}\\PSReadLine"); Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy( NullLogger.Instance, PowerShellContextFactory.initialRunspace, From 01957e62d2ead76d2ff7b35ef472d27e8eca330c Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 19:02:21 -0500 Subject: [PATCH 13/15] Removed TEST property. Moved Set-ExecutionPolicy to before attempted PSReadLine load --- PowerShellEditorServices.Common.props | 1 - PowerShellEditorServices.build.ps1 | 136 ++++++++---------- .../PowerShellContextService.cs | 9 +- 3 files changed, 64 insertions(+), 82 deletions(-) diff --git a/PowerShellEditorServices.Common.props b/PowerShellEditorServices.Common.props index 2ab30ebc7..cdb72f19d 100644 --- a/PowerShellEditorServices.Common.props +++ b/PowerShellEditorServices.Common.props @@ -11,6 +11,5 @@ git https://github.com/PowerShell/PowerShellEditorServices portable - $(DefineConstants);$(ExtraDefineConstants) diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index 8df6c5fc1..3c90b8a75 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -23,9 +23,9 @@ $script:PsesCommonProps = [xml](Get-Content -Raw "$PSScriptRoot/PowerShellEditor $script:IsPreview = [bool]($script:PsesCommonProps.Project.PropertyGroup.VersionSuffix) $script:NetRuntime = @{ - PS7 = 'netcoreapp3.1' - PS72 = 'net6.0' - Desktop = 'net461' + PS7 = 'netcoreapp3.1' + PS72 = 'net6.0' + Desktop = 'net461' Standard = 'netstandard2.0' } @@ -42,11 +42,11 @@ if (Get-Command git -ErrorAction SilentlyContinue) { function Invoke-WithCreateDefaultHook { param([scriptblock]$ScriptBlock) - try - { + try { $env:PSES_TEST_USE_CREATE_DEFAULT = 1 & $ScriptBlock - } finally { + } + finally { Remove-Item env:PSES_TEST_USE_CREATE_DEFAULT } } @@ -69,25 +69,22 @@ function Install-Dotnet { Invoke-WebRequest "https://dot.net/v1/$installScript" -OutFile $installScriptPath # Download and install the different .NET channels - foreach ($dotnetChannel in $Channel) - { + foreach ($dotnetChannel in $Channel) { Write-Host "`n### Installing .NET CLI $Version...`n" if ($script:IsNix) { chmod +x $installScriptPath } - $params = if ($script:IsNix) - { + $params = if ($script:IsNix) { @('-Channel', $dotnetChannel, '-InstallDir', $env:DOTNET_INSTALL_DIR, '-NoPath', '-Verbose') } - else - { + else { @{ - Channel = $dotnetChannel + Channel = $dotnetChannel InstallDir = $env:DOTNET_INSTALL_DIR - NoPath = $true - Verbose = $true + NoPath = $true + Verbose = $true } } @@ -108,13 +105,12 @@ task SetupDotNet -Before Clean, Build, TestServerWinPS, TestServerPS7, TestServe if (!(Test-Path $dotnetExePath)) { # TODO: Test .NET 5 with PowerShell 7.1 - Install-Dotnet -Channel '3.1','5.0','6.0' + Install-Dotnet -Channel '3.1', '5.0', '6.0' } # This variable is used internally by 'dotnet' to know where it's installed $script:dotnetExe = Resolve-Path $dotnetExePath - if (!$env:DOTNET_INSTALL_DIR) - { + if (!$env:DOTNET_INSTALL_DIR) { $dotnetExeDir = [System.IO.Path]::GetDirectoryName($script:dotnetExe) $env:PATH = $dotnetExeDir + [System.IO.Path]::PathSeparator + $env:PATH $env:DOTNET_INSTALL_DIR = $dotnetExeDir @@ -129,7 +125,7 @@ task BinClean { Remove-Item $PSScriptRoot\module\PowerShellEditorServices.VSCode\bin -Recurse -Force -ErrorAction Ignore } -task Clean BinClean,{ +task Clean BinClean, { exec { & $script:dotnetExe restore } exec { & $script:dotnetExe clean } Get-ChildItem -Recurse $PSScriptRoot\src\*.nupkg | Remove-Item -Force -ErrorAction Ignore @@ -140,9 +136,9 @@ task Clean BinClean,{ $moduleJsonPath = "$PSScriptRoot\modules.json" if (Test-Path $moduleJsonPath) { Get-Content -Raw $moduleJsonPath | - ConvertFrom-Json | - ForEach-Object { $_.PSObject.Properties.Name } | - ForEach-Object { Remove-Item -Path "$PSScriptRoot/module/$_" -Recurse -Force -ErrorAction Ignore } + ConvertFrom-Json | + ForEach-Object { $_.PSObject.Properties.Name } | + ForEach-Object { Remove-Item -Path "$PSScriptRoot/module/$_" -Recurse -Force -ErrorAction Ignore } } } @@ -180,9 +176,11 @@ task CreateBuildInfo -Before Build { if ($env:TF_BUILD) { if ($env:BUILD_BUILDNUMBER -like "PR-*") { $buildOrigin = "PR" - } elseif ($env:BUILD_DEFINITIONNAME -like "*-CI") { + } + elseif ($env:BUILD_DEFINITIONNAME -like "*-CI") { $buildOrigin = "CI" - } else { + } + else { $buildOrigin = "Release" } @@ -190,8 +188,7 @@ task CreateBuildInfo -Before Build { $propsBody = $propsXml.Project.PropertyGroup $buildVersion = $propsBody.VersionPrefix - if ($propsBody.VersionSuffix) - { + if ($propsBody.VersionSuffix) { $buildVersion += '-' + $propsBody.VersionSuffix } } @@ -230,17 +227,15 @@ task SetupHelpForTests { Write-Host "Updating help for tests" Update-Help -Module Microsoft.PowerShell.Utility -Force -Scope CurrentUser } - else - { + else { Write-Host "Write-Host help found -- Update-Help skipped" } } -task Build BinClean,{ +task Build BinClean, { exec { & $script:dotnetExe publish -c $Configuration .\src\PowerShellEditorServices\PowerShellEditorServices.csproj -f $script:NetRuntime.Standard } exec { & $script:dotnetExe publish -c $Configuration .\src\PowerShellEditorServices.Hosting\PowerShellEditorServices.Hosting.csproj -f $script:NetRuntime.PS7 } - if (-not $script:IsNix) - { + if (-not $script:IsNix) { exec { & $script:dotnetExe publish -c $Configuration .\src\PowerShellEditorServices.Hosting\PowerShellEditorServices.Hosting.csproj -f $script:NetRuntime.Desktop } } @@ -250,29 +245,29 @@ task Build BinClean,{ function DotNetTestFilter { # Reference https://docs.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests - if ($TestFilter) { @("--filter",$TestFilter) } else { "" } + if ($TestFilter) { @("--filter", $TestFilter) } else { "" } } -task Test SetupHelpForTests,TestServer,TestE2E +task Test SetupHelpForTests, TestServer, TestE2E -task TestServer TestServerWinPS,TestServerPS7,TestServerPS72 +task TestServer TestServerWinPS, TestServerPS7, TestServerPS72 task TestServerWinPS -If (-not $script:IsNix) { Set-Location .\test\PowerShellEditorServices.Test\ - exec { & $script:dotnetExe test -p:ExtraDefineConstants=TEST --logger trx -f $script:NetRuntime.Desktop (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:NetRuntime.Desktop (DotNetTestFilter) } } task TestServerPS7 -If (-not $script:IsRosetta) { Set-Location .\test\PowerShellEditorServices.Test\ Invoke-WithCreateDefaultHook -NewModulePath $script:PSCoreModulePath { - exec { & $script:dotnetExe test -p:ExtraDefineConstants=TEST --logger trx -f $script:NetRuntime.PS7 (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:NetRuntime.PS7 (DotNetTestFilter) } } } task TestServerPS72 { Set-Location .\test\PowerShellEditorServices.Test\ Invoke-WithCreateDefaultHook -NewModulePath $script:PSCoreModulePath { - exec { & $script:dotnetExe test -p:ExtraDefineConstants=TEST --logger trx -f $script:NetRuntime.PS72 (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:NetRuntime.PS72 (DotNetTestFilter) } } } @@ -281,14 +276,15 @@ task TestE2E { $env:PWSH_EXE_NAME = if ($IsCoreCLR) { "pwsh" } else { "powershell" } $NetRuntime = if ($IsRosetta) { $script:NetRuntime.PS72 } else { $script:NetRuntime.PS7 } - exec { & $script:dotnetExe test -p:ExtraDefineConstants=TEST --logger trx -f $NetRuntime (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $NetRuntime (DotNetTestFilter) } # Run E2E tests in ConstrainedLanguage mode. if (!$script:IsNix) { try { [System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "0x80000007", [System.EnvironmentVariableTarget]::Machine); - exec { & $script:dotnetExe test -p:ExtraDefineConstants=TEST --logger trx -f $script:NetRuntime.PS7 (DotNetTestFilter) } - } finally { + exec { & $script:dotnetExe test --logger trx -f $script:NetRuntime.PS7 (DotNetTestFilter) } + } + finally { [System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", $null, [System.EnvironmentVariableTarget]::Machine); } } @@ -303,8 +299,7 @@ task LayoutModule -After Build { $psesCoreHostPath = "$psesBinOutputPath/Core" $psesDeskHostPath = "$psesBinOutputPath/Desktop" - foreach ($dir in $psesDepsPath,$psesCoreHostPath,$psesDeskHostPath,$psesVSCodeBinOutputPath) - { + foreach ($dir in $psesDepsPath, $psesCoreHostPath, $psesDeskHostPath, $psesVSCodeBinOutputPath) { New-Item -Force -Path $dir -ItemType Directory } @@ -317,37 +312,29 @@ task LayoutModule -After Build { [void]$includedDlls.Add('System.Management.Automation.dll') # PSES/bin/Common - foreach ($psesComponent in Get-ChildItem $script:PsesOutput) - { + foreach ($psesComponent in Get-ChildItem $script:PsesOutput) { if ($psesComponent.Name -eq 'System.Management.Automation.dll' -or - $psesComponent.Name -eq 'System.Runtime.InteropServices.RuntimeInformation.dll') - { + $psesComponent.Name -eq 'System.Runtime.InteropServices.RuntimeInformation.dll') { continue } - if ($psesComponent.Extension) - { + if ($psesComponent.Extension) { [void]$includedDlls.Add($psesComponent.Name) Copy-Item -Path $psesComponent.FullName -Destination $psesDepsPath -Force } } # PSES/bin/Core - foreach ($hostComponent in Get-ChildItem $script:HostCoreOutput) - { - if (-not $includedDlls.Contains($hostComponent.Name)) - { + foreach ($hostComponent in Get-ChildItem $script:HostCoreOutput) { + if (-not $includedDlls.Contains($hostComponent.Name)) { Copy-Item -Path $hostComponent.FullName -Destination $psesCoreHostPath -Force } } # PSES/bin/Desktop - if (-not $script:IsNix) - { - foreach ($hostComponent in Get-ChildItem $script:HostDeskOutput) - { - if (-not $includedDlls.Contains($hostComponent.Name)) - { + if (-not $script:IsNix) { + foreach ($hostComponent in Get-ChildItem $script:HostDeskOutput) { + if (-not $includedDlls.Contains($hostComponent.Name)) { Copy-Item -Path $hostComponent.FullName -Destination $psesDeskHostPath -Force } } @@ -355,10 +342,8 @@ task LayoutModule -After Build { # Assemble the PowerShellEditorServices.VSCode module - foreach ($vscodeComponent in Get-ChildItem $script:VSCodeOutput) - { - if (-not $includedDlls.Contains($vscodeComponent.Name)) - { + foreach ($vscodeComponent in Get-ChildItem $script:VSCodeOutput) { + if (-not $includedDlls.Contains($vscodeComponent.Name)) { Copy-Item -Path $vscodeComponent.FullName -Destination $psesVSCodeBinOutputPath -Force } } @@ -374,16 +359,15 @@ task RestorePsesModules -After Build { (Get-Content -Raw $ModulesJsonPath | ConvertFrom-Json).PSObject.Properties | ForEach-Object { $name = $_.Name $body = @{ - Name = $name - MinimumVersion = $_.Value.MinimumVersion - MaximumVersion = $_.Value.MaximumVersion + Name = $name + MinimumVersion = $_.Value.MinimumVersion + MaximumVersion = $_.Value.MaximumVersion AllowPrerelease = $script:IsPreview - Repository = if ($_.Value.Repository) { $_.Value.Repository } else { $DefaultModuleRepository } - Path = $submodulePath + Repository = if ($_.Value.Repository) { $_.Value.Repository } else { $DefaultModuleRepository } + Path = $submodulePath } - if (-not $name) - { + if (-not $name) { throw "EditorServices module listed without name in '$ModulesJsonPath'" } @@ -398,10 +382,8 @@ task RestorePsesModules -After Build { } # Save each module in the modules.json file - foreach ($moduleName in $moduleInfos.Keys) - { - if (Test-Path -Path (Join-Path -Path $submodulePath -ChildPath $moduleName)) - { + foreach ($moduleName in $moduleInfos.Keys) { + if (Test-Path -Path (Join-Path -Path $submodulePath -ChildPath $moduleName)) { Write-Host "`tModule '${moduleName}' already detected. Skipping" continue } @@ -409,10 +391,10 @@ task RestorePsesModules -After Build { $moduleInstallDetails = $moduleInfos[$moduleName] $splatParameters = @{ - Name = $moduleName - AllowPrerelease = $moduleInstallDetails.AllowPrerelease - Repository = if ($moduleInstallDetails.Repository) { $moduleInstallDetails.Repository } else { $DefaultModuleRepository } - Path = $submodulePath + Name = $moduleName + AllowPrerelease = $moduleInstallDetails.AllowPrerelease + Repository = if ($moduleInstallDetails.Repository) { $moduleInstallDetails.Repository } else { $DefaultModuleRepository } + Path = $submodulePath } # Only add Min and Max version if we're doing a stable release. diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index ab58ec7e1..b98754951 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -411,6 +411,11 @@ public void Initialize( this.versionSpecificOperations); this.InvocationEventQueue = InvocationEventQueue.Create(this, this.PromptNest); + if (VersionUtils.IsWindows) + { + this.SetExecutionPolicy(); + } + if (powerShellVersion.Major >= 5 && this.isPSReadLineEnabled && PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, hostStartupInfo.BundledModulePath, out PSReadLineProxy proxy)) @@ -426,10 +431,6 @@ public void Initialize( this.PromptContext = new LegacyReadLineContext(this); } - if (VersionUtils.IsWindows) - { - this.SetExecutionPolicy(); - } } /// From 9a045d9a71f8674e676f5cb52e1011d0a6cd9853 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Tue, 6 Jul 2021 19:15:16 -0500 Subject: [PATCH 14/15] Fixed formatting in PowerShellEditorServices.build.ps1 --- PowerShellEditorServices.build.ps1 | 126 ++++++++++++++++------------- 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index 3c90b8a75..fbd126708 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -23,9 +23,9 @@ $script:PsesCommonProps = [xml](Get-Content -Raw "$PSScriptRoot/PowerShellEditor $script:IsPreview = [bool]($script:PsesCommonProps.Project.PropertyGroup.VersionSuffix) $script:NetRuntime = @{ - PS7 = 'netcoreapp3.1' - PS72 = 'net6.0' - Desktop = 'net461' + PS7 = 'netcoreapp3.1' + PS72 = 'net6.0' + Desktop = 'net461' Standard = 'netstandard2.0' } @@ -42,11 +42,11 @@ if (Get-Command git -ErrorAction SilentlyContinue) { function Invoke-WithCreateDefaultHook { param([scriptblock]$ScriptBlock) - try { + try + { $env:PSES_TEST_USE_CREATE_DEFAULT = 1 & $ScriptBlock - } - finally { + } finally { Remove-Item env:PSES_TEST_USE_CREATE_DEFAULT } } @@ -69,22 +69,25 @@ function Install-Dotnet { Invoke-WebRequest "https://dot.net/v1/$installScript" -OutFile $installScriptPath # Download and install the different .NET channels - foreach ($dotnetChannel in $Channel) { + foreach ($dotnetChannel in $Channel) + { Write-Host "`n### Installing .NET CLI $Version...`n" if ($script:IsNix) { chmod +x $installScriptPath } - $params = if ($script:IsNix) { + $params = if ($script:IsNix) + { @('-Channel', $dotnetChannel, '-InstallDir', $env:DOTNET_INSTALL_DIR, '-NoPath', '-Verbose') } - else { + else + { @{ - Channel = $dotnetChannel + Channel = $dotnetChannel InstallDir = $env:DOTNET_INSTALL_DIR - NoPath = $true - Verbose = $true + NoPath = $true + Verbose = $true } } @@ -105,12 +108,13 @@ task SetupDotNet -Before Clean, Build, TestServerWinPS, TestServerPS7, TestServe if (!(Test-Path $dotnetExePath)) { # TODO: Test .NET 5 with PowerShell 7.1 - Install-Dotnet -Channel '3.1', '5.0', '6.0' + Install-Dotnet -Channel '3.1','5.0','6.0' } # This variable is used internally by 'dotnet' to know where it's installed $script:dotnetExe = Resolve-Path $dotnetExePath - if (!$env:DOTNET_INSTALL_DIR) { + if (!$env:DOTNET_INSTALL_DIR) + { $dotnetExeDir = [System.IO.Path]::GetDirectoryName($script:dotnetExe) $env:PATH = $dotnetExeDir + [System.IO.Path]::PathSeparator + $env:PATH $env:DOTNET_INSTALL_DIR = $dotnetExeDir @@ -125,7 +129,7 @@ task BinClean { Remove-Item $PSScriptRoot\module\PowerShellEditorServices.VSCode\bin -Recurse -Force -ErrorAction Ignore } -task Clean BinClean, { +task Clean BinClean,{ exec { & $script:dotnetExe restore } exec { & $script:dotnetExe clean } Get-ChildItem -Recurse $PSScriptRoot\src\*.nupkg | Remove-Item -Force -ErrorAction Ignore @@ -136,9 +140,9 @@ task Clean BinClean, { $moduleJsonPath = "$PSScriptRoot\modules.json" if (Test-Path $moduleJsonPath) { Get-Content -Raw $moduleJsonPath | - ConvertFrom-Json | - ForEach-Object { $_.PSObject.Properties.Name } | - ForEach-Object { Remove-Item -Path "$PSScriptRoot/module/$_" -Recurse -Force -ErrorAction Ignore } + ConvertFrom-Json | + ForEach-Object { $_.PSObject.Properties.Name } | + ForEach-Object { Remove-Item -Path "$PSScriptRoot/module/$_" -Recurse -Force -ErrorAction Ignore } } } @@ -176,11 +180,9 @@ task CreateBuildInfo -Before Build { if ($env:TF_BUILD) { if ($env:BUILD_BUILDNUMBER -like "PR-*") { $buildOrigin = "PR" - } - elseif ($env:BUILD_DEFINITIONNAME -like "*-CI") { + } elseif ($env:BUILD_DEFINITIONNAME -like "*-CI") { $buildOrigin = "CI" - } - else { + } else { $buildOrigin = "Release" } @@ -188,7 +190,8 @@ task CreateBuildInfo -Before Build { $propsBody = $propsXml.Project.PropertyGroup $buildVersion = $propsBody.VersionPrefix - if ($propsBody.VersionSuffix) { + if ($propsBody.VersionSuffix) + { $buildVersion += '-' + $propsBody.VersionSuffix } } @@ -227,15 +230,17 @@ task SetupHelpForTests { Write-Host "Updating help for tests" Update-Help -Module Microsoft.PowerShell.Utility -Force -Scope CurrentUser } - else { + else + { Write-Host "Write-Host help found -- Update-Help skipped" } } -task Build BinClean, { +task Build BinClean,{ exec { & $script:dotnetExe publish -c $Configuration .\src\PowerShellEditorServices\PowerShellEditorServices.csproj -f $script:NetRuntime.Standard } exec { & $script:dotnetExe publish -c $Configuration .\src\PowerShellEditorServices.Hosting\PowerShellEditorServices.Hosting.csproj -f $script:NetRuntime.PS7 } - if (-not $script:IsNix) { + if (-not $script:IsNix) + { exec { & $script:dotnetExe publish -c $Configuration .\src\PowerShellEditorServices.Hosting\PowerShellEditorServices.Hosting.csproj -f $script:NetRuntime.Desktop } } @@ -245,12 +250,12 @@ task Build BinClean, { function DotNetTestFilter { # Reference https://docs.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests - if ($TestFilter) { @("--filter", $TestFilter) } else { "" } + if ($TestFilter) { @("--filter",$TestFilter) } else { "" } } -task Test SetupHelpForTests, TestServer, TestE2E +task Test SetupHelpForTests,TestServer,TestE2E -task TestServer TestServerWinPS, TestServerPS7, TestServerPS72 +task TestServer TestServerWinPS,TestServerPS7,TestServerPS72 task TestServerWinPS -If (-not $script:IsNix) { Set-Location .\test\PowerShellEditorServices.Test\ @@ -283,8 +288,7 @@ task TestE2E { try { [System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "0x80000007", [System.EnvironmentVariableTarget]::Machine); exec { & $script:dotnetExe test --logger trx -f $script:NetRuntime.PS7 (DotNetTestFilter) } - } - finally { + } finally { [System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", $null, [System.EnvironmentVariableTarget]::Machine); } } @@ -299,7 +303,8 @@ task LayoutModule -After Build { $psesCoreHostPath = "$psesBinOutputPath/Core" $psesDeskHostPath = "$psesBinOutputPath/Desktop" - foreach ($dir in $psesDepsPath, $psesCoreHostPath, $psesDeskHostPath, $psesVSCodeBinOutputPath) { + foreach ($dir in $psesDepsPath,$psesCoreHostPath,$psesDeskHostPath,$psesVSCodeBinOutputPath) + { New-Item -Force -Path $dir -ItemType Directory } @@ -312,29 +317,37 @@ task LayoutModule -After Build { [void]$includedDlls.Add('System.Management.Automation.dll') # PSES/bin/Common - foreach ($psesComponent in Get-ChildItem $script:PsesOutput) { + foreach ($psesComponent in Get-ChildItem $script:PsesOutput) + { if ($psesComponent.Name -eq 'System.Management.Automation.dll' -or - $psesComponent.Name -eq 'System.Runtime.InteropServices.RuntimeInformation.dll') { + $psesComponent.Name -eq 'System.Runtime.InteropServices.RuntimeInformation.dll') + { continue } - if ($psesComponent.Extension) { + if ($psesComponent.Extension) + { [void]$includedDlls.Add($psesComponent.Name) Copy-Item -Path $psesComponent.FullName -Destination $psesDepsPath -Force } } # PSES/bin/Core - foreach ($hostComponent in Get-ChildItem $script:HostCoreOutput) { - if (-not $includedDlls.Contains($hostComponent.Name)) { + foreach ($hostComponent in Get-ChildItem $script:HostCoreOutput) + { + if (-not $includedDlls.Contains($hostComponent.Name)) + { Copy-Item -Path $hostComponent.FullName -Destination $psesCoreHostPath -Force } } # PSES/bin/Desktop - if (-not $script:IsNix) { - foreach ($hostComponent in Get-ChildItem $script:HostDeskOutput) { - if (-not $includedDlls.Contains($hostComponent.Name)) { + if (-not $script:IsNix) + { + foreach ($hostComponent in Get-ChildItem $script:HostDeskOutput) + { + if (-not $includedDlls.Contains($hostComponent.Name)) + { Copy-Item -Path $hostComponent.FullName -Destination $psesDeskHostPath -Force } } @@ -342,8 +355,10 @@ task LayoutModule -After Build { # Assemble the PowerShellEditorServices.VSCode module - foreach ($vscodeComponent in Get-ChildItem $script:VSCodeOutput) { - if (-not $includedDlls.Contains($vscodeComponent.Name)) { + foreach ($vscodeComponent in Get-ChildItem $script:VSCodeOutput) + { + if (-not $includedDlls.Contains($vscodeComponent.Name)) + { Copy-Item -Path $vscodeComponent.FullName -Destination $psesVSCodeBinOutputPath -Force } } @@ -359,15 +374,16 @@ task RestorePsesModules -After Build { (Get-Content -Raw $ModulesJsonPath | ConvertFrom-Json).PSObject.Properties | ForEach-Object { $name = $_.Name $body = @{ - Name = $name - MinimumVersion = $_.Value.MinimumVersion - MaximumVersion = $_.Value.MaximumVersion + Name = $name + MinimumVersion = $_.Value.MinimumVersion + MaximumVersion = $_.Value.MaximumVersion AllowPrerelease = $script:IsPreview - Repository = if ($_.Value.Repository) { $_.Value.Repository } else { $DefaultModuleRepository } - Path = $submodulePath + Repository = if ($_.Value.Repository) { $_.Value.Repository } else { $DefaultModuleRepository } + Path = $submodulePath } - if (-not $name) { + if (-not $name) + { throw "EditorServices module listed without name in '$ModulesJsonPath'" } @@ -382,8 +398,10 @@ task RestorePsesModules -After Build { } # Save each module in the modules.json file - foreach ($moduleName in $moduleInfos.Keys) { - if (Test-Path -Path (Join-Path -Path $submodulePath -ChildPath $moduleName)) { + foreach ($moduleName in $moduleInfos.Keys) + { + if (Test-Path -Path (Join-Path -Path $submodulePath -ChildPath $moduleName)) + { Write-Host "`tModule '${moduleName}' already detected. Skipping" continue } @@ -391,10 +409,10 @@ task RestorePsesModules -After Build { $moduleInstallDetails = $moduleInfos[$moduleName] $splatParameters = @{ - Name = $moduleName - AllowPrerelease = $moduleInstallDetails.AllowPrerelease - Repository = if ($moduleInstallDetails.Repository) { $moduleInstallDetails.Repository } else { $DefaultModuleRepository } - Path = $submodulePath + Name = $moduleName + AllowPrerelease = $moduleInstallDetails.AllowPrerelease + Repository = if ($moduleInstallDetails.Repository) { $moduleInstallDetails.Repository } else { $DefaultModuleRepository } + Path = $submodulePath } # Only add Min and Max version if we're doing a stable release. From e1e70cf02c3ce6727b67edad28fc4a1f0a2de219 Mon Sep 17 00:00:00 2001 From: dkattan <1424395+dkattan@users.noreply.github.com> Date: Wed, 7 Jul 2021 07:57:27 -0500 Subject: [PATCH 15/15] Fixed issue where BundledModulePath was _not_ actually getting set. --- src/PowerShellEditorServices/Hosting/HostStartupInfo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs b/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs index 13f0ae77a..7612cd5a0 100644 --- a/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs +++ b/src/PowerShellEditorServices/Hosting/HostStartupInfo.cs @@ -167,6 +167,7 @@ string bundledModulePath LogLevel = logLevel; ConsoleReplEnabled = consoleReplEnabled; UsesLegacyReadLine = usesLegacyReadLine; + BundledModulePath = bundledModulePath; } #endregion