Skip to content

Commit 06893e7

Browse files
Respect BundledModulePath user option
This also simplifies our testing scenario where that path needs to be configured at runtime, too. Co-authored-by: Andrew Schwartzmeyer <[email protected]>
1 parent 30f0156 commit 06893e7

File tree

6 files changed

+46
-40
lines changed

6 files changed

+46
-40
lines changed

src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ private HostStartupInfo CreateHostStartupInfo()
292292
_config.LogPath,
293293
(int)_config.LogLevel,
294294
consoleReplEnabled: _config.ConsoleRepl != ConsoleReplKind.None,
295-
usesLegacyReadLine: _config.ConsoleRepl == ConsoleReplKind.LegacyReadLine);
295+
usesLegacyReadLine: _config.ConsoleRepl == ConsoleReplKind.LegacyReadLine,
296+
bundledModulePath: _config.BundledModulePath);
296297
}
297298

298299
private void WriteStartupBanner()

src/PowerShellEditorServices/Hosting/HostStartupInfo.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public sealed class HostStartupInfo
107107
/// </remarks>
108108
public int LogLevel { get; }
109109

110+
/// <summary>
111+
/// The path to find the bundled modules. User configurable for advanced usage.
112+
/// </summary>
113+
public string BundledModulePath { get; }
114+
110115
#endregion
111116

112117
#region Constructors
@@ -135,6 +140,7 @@ public sealed class HostStartupInfo
135140
/// <param name="logLevel">The minimum log event level.</param>
136141
/// <param name="consoleReplEnabled">Enable console if true.</param>
137142
/// <param name="usesLegacyReadLine">Use PSReadLine if false, otherwise use the legacy readline implementation.</param>
143+
/// <param name="bundledModulePath">A custom path to the expected bundled modules.</param>
138144
public HostStartupInfo(
139145
string name,
140146
string profileId,
@@ -147,7 +153,8 @@ public HostStartupInfo(
147153
string logPath,
148154
int logLevel,
149155
bool consoleReplEnabled,
150-
bool usesLegacyReadLine)
156+
bool usesLegacyReadLine,
157+
string bundledModulePath)
151158
{
152159
Name = name ?? DefaultHostName;
153160
ProfileId = profileId ?? DefaultHostProfileId;
@@ -161,6 +168,7 @@ public HostStartupInfo(
161168
LogLevel = logLevel;
162169
ConsoleReplEnabled = consoleReplEnabled;
163170
UsesLegacyReadLine = usesLegacyReadLine;
171+
BundledModulePath = bundledModulePath;
164172
}
165173

166174
#endregion

src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,18 @@ namespace Microsoft.PowerShell.EditorServices.Services
3333
/// </summary>
3434
internal class PowerShellContextService : IHostSupportsInteractiveSession
3535
{
36-
private static readonly string s_commandsModulePath = Path.GetFullPath(
37-
Path.Combine(
36+
// This is a default that can be overriden at runtime by the user or tests.
37+
private static string s_bundledModulePath = Path.GetFullPath(Path.Combine(
3838
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
39-
"../../Commands/PowerShellEditorServices.Commands.psd1"));
39+
"..",
40+
"..",
41+
".."));
42+
43+
private static string s_commandsModulePath => Path.GetFullPath(Path.Combine(
44+
s_bundledModulePath,
45+
"PowerShellEditorServices",
46+
"Commands",
47+
"PowerShellEditorServices.Commands.psd1"));
4048

4149
private static readonly Action<Runspace, ApartmentState> s_runspaceApartmentStateSetter;
4250
private static readonly PropertyInfo s_writeStreamProperty;
@@ -192,6 +200,12 @@ public static PowerShellContextService Create(
192200
{
193201
Validate.IsNotNull(nameof(hostStartupInfo), hostStartupInfo);
194202

203+
// Respect a user provided bundled module path.
204+
if (Directory.Exists(hostStartupInfo.BundledModulePath))
205+
{
206+
s_bundledModulePath = hostStartupInfo.BundledModulePath;
207+
}
208+
195209
var logger = factory.CreateLogger<PowerShellContextService>();
196210

197211
bool shouldUsePSReadLine = hostStartupInfo.ConsoleReplEnabled
@@ -404,7 +418,7 @@ public void Initialize(
404418

405419
if (powerShellVersion.Major >= 5 &&
406420
this.isPSReadLineEnabled &&
407-
PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, out PSReadLineProxy proxy))
421+
PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, s_bundledModulePath, out PSReadLineProxy proxy))
408422
{
409423
this.PromptContext = new PSReadLinePromptContext(
410424
this,
@@ -423,15 +437,13 @@ public void Initialize(
423437
/// the runspace. This method will be moved somewhere else soon.
424438
/// </summary>
425439
/// <returns></returns>
426-
public Task ImportCommandsModuleAsync() => ImportCommandsModuleAsync(s_commandsModulePath);
427-
428-
public Task ImportCommandsModuleAsync(string path)
440+
public Task ImportCommandsModuleAsync()
429441
{
430-
this.logger.LogTrace($"Importing PowershellEditorServices commands from {path}");
442+
this.logger.LogTrace($"Importing PowershellEditorServices commands from {s_commandsModulePath}");
431443

432444
PSCommand importCommand = new PSCommand()
433445
.AddCommand("Import-Module")
434-
.AddArgument(path);
446+
.AddArgument(s_commandsModulePath);
435447

436448
return this.ExecuteCommandAsync<PSObject>(importCommand, sendOutputToHost: false, sendErrorToHost: false);
437449
}

src/PowerShellEditorServices/Services/PowerShellContext/Session/PSReadLinePromptContext.cs

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,6 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShellContext
1717

1818
internal class PSReadLinePromptContext : IPromptContext
1919
{
20-
private static readonly string _psReadLineModulePath = Path.Combine(
21-
Path.GetDirectoryName(typeof(PSReadLinePromptContext).Assembly.Location),
22-
"..",
23-
"..",
24-
"..",
25-
"PSReadLine");
26-
27-
// When using xUnit (dotnet test) the assemblies are deployed to the
28-
// test project folder, invalidating our relative path assumption.
29-
private static readonly string _psReadLineTestModulePath = Path.Combine(
30-
Path.GetDirectoryName(typeof(PSReadLinePromptContext).Assembly.Location),
31-
"..",
32-
"..",
33-
"..",
34-
"..",
35-
"..",
36-
"module",
37-
"PSReadLine");
38-
3920
private static readonly Lazy<CmdletInfo> s_lazyInvokeReadLineForEditorServicesCmdletInfo = new Lazy<CmdletInfo>(() =>
4021
{
4122
var type = Type.GetType("Microsoft.PowerShell.EditorServices.Commands.InvokeReadLineForEditorServicesCommand, Microsoft.PowerShell.EditorServices.Hosting");
@@ -84,16 +65,16 @@ internal PSReadLinePromptContext(
8465
internal static bool TryGetPSReadLineProxy(
8566
ILogger logger,
8667
Runspace runspace,
87-
out PSReadLineProxy readLineProxy,
88-
bool testing = false)
68+
string bundledModulePath,
69+
out PSReadLineProxy readLineProxy)
8970
{
9071
readLineProxy = null;
9172
logger.LogTrace("Attempting to load PSReadLine");
9273
using (var pwsh = PowerShell.Create())
9374
{
9475
pwsh.Runspace = runspace;
9576
pwsh.AddCommand("Microsoft.PowerShell.Core\\Import-Module")
96-
.AddParameter("Name", testing ? _psReadLineTestModulePath : _psReadLineModulePath)
77+
.AddParameter("Name", Path.Combine(bundledModulePath, "PSReadLine"))
9778
.Invoke();
9879

9980
if (pwsh.HadErrors)

test/PowerShellEditorServices.Test/PowerShellContextFactory.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ internal static class PowerShellContextFactory
3232
Path.GetFullPath(
3333
TestUtilities.NormalizePath("../../../../PowerShellEditorServices.Test.Shared/ProfileTest.ps1")));
3434

35-
public static System.Management.Automation.Runspaces.Runspace initialRunspace;
35+
public static readonly string BundledModulePath = Path.GetFullPath(
36+
TestUtilities.NormalizePath("../../../../../module"));
37+
38+
public static System.Management.Automation.Runspaces.Runspace InitialRunspace;
3639

3740
public static PowerShellContextService Create(ILogger logger)
3841
{
@@ -50,17 +53,18 @@ public static PowerShellContextService Create(ILogger logger)
5053
null,
5154
0,
5255
consoleReplEnabled: false,
53-
usesLegacyReadLine: false);
56+
usesLegacyReadLine: false,
57+
bundledModulePath: BundledModulePath);
5458

55-
initialRunspace = PowerShellContextService.CreateRunspace(
59+
InitialRunspace = PowerShellContextService.CreateRunspace(
5660
testHostDetails,
5761
powerShellContext,
5862
new TestPSHostUserInterface(powerShellContext, logger),
5963
logger);
6064

6165
powerShellContext.Initialize(
6266
TestProfilePaths,
63-
initialRunspace,
67+
InitialRunspace,
6468
ownsInitialRunspace: true,
6569
consoleHost: null);
6670

test/PowerShellEditorServices.Test/Session/PowerShellContextTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ public void CanGetPSReadLineProxy()
152152
{
153153
Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy(
154154
NullLogger.Instance,
155-
PowerShellContextFactory.initialRunspace,
156-
out PSReadLineProxy proxy,
157-
true));
155+
PowerShellContextFactory.InitialRunspace,
156+
PowerShellContextFactory.BundledModulePath,
157+
out PSReadLineProxy proxy));
158158
}
159159

160160
#region Helper Methods

0 commit comments

Comments
 (0)