Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
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 <andrew@schwartzmeyer.com>
  • Loading branch information
dkattan and andyleejordan committed Jul 9, 2021
commit f911ef1f6c933fbc1700ac9eafdf9bd0eddea405
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
10 changes: 9 additions & 1 deletion src/PowerShellEditorServices/Hosting/HostStartupInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ public sealed class HostStartupInfo
/// </remarks>
public int LogLevel { get; }

/// <summary>
/// The path to find the bundled modules. User configurable for advanced usage.
/// </summary>
public string BundledModulePath { get; }

#endregion

#region Constructors
Expand Down Expand Up @@ -135,6 +140,7 @@ public sealed class HostStartupInfo
/// <param name="logLevel">The minimum log event level.</param>
/// <param name="consoleReplEnabled">Enable console if true.</param>
/// <param name="usesLegacyReadLine">Use PSReadLine if false, otherwise use the legacy readline implementation.</param>
/// <param name="bundledModulePath">A custom path to the expected bundled modules.</param>
public HostStartupInfo(
string name,
string profileId,
Expand All @@ -147,7 +153,8 @@ public HostStartupInfo(
string logPath,
int logLevel,
bool consoleReplEnabled,
bool usesLegacyReadLine)
bool usesLegacyReadLine,
string bundledModulePath)
{
Name = name ?? DefaultHostName;
ProfileId = profileId ?? DefaultHostProfileId;
Expand All @@ -161,6 +168,7 @@ public HostStartupInfo(
LogLevel = logLevel;
ConsoleReplEnabled = consoleReplEnabled;
UsesLegacyReadLine = usesLegacyReadLine;
BundledModulePath = bundledModulePath;
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,18 @@ namespace Microsoft.PowerShell.EditorServices.Services
/// </summary>
internal class PowerShellContextService : IHostSupportsInteractiveSession
{
private static readonly string s_commandsModulePath = Path.GetFullPath(
Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"../../Commands/PowerShellEditorServices.Commands.psd1"));
// This is a default that can be overriden at runtime by the user or tests.
private static string s_bundledModulePath = Path.GetFullPath(Path.Combine(
Path.GetDirectoryName(typeof(PowerShellContextService).Assembly.Location),
"..",
"..",
".."));

private static string s_commandsModulePath => Path.GetFullPath(Path.Combine(
s_bundledModulePath,
"PowerShellEditorServices",
"Commands",
"PowerShellEditorServices.Commands.psd1"));

private static readonly Action<Runspace, ApartmentState> s_runspaceApartmentStateSetter;
private static readonly PropertyInfo s_writeStreamProperty;
Expand Down Expand Up @@ -190,9 +198,16 @@ public static PowerShellContextService Create(
OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade languageServer,
HostStartupInfo hostStartupInfo)
{
var logger = factory.CreateLogger<PowerShellContextService>();

Validate.IsNotNull(nameof(hostStartupInfo), hostStartupInfo);

var logger = factory.CreateLogger<PowerShellContextService>();
// Respect a user provided bundled module path.
if (Directory.Exists(hostStartupInfo.BundledModulePath))
{
logger.LogTrace($"Using new bundled module path: {hostStartupInfo.BundledModulePath}");
s_bundledModulePath = hostStartupInfo.BundledModulePath;
}

bool shouldUsePSReadLine = hostStartupInfo.ConsoleReplEnabled
&& !hostStartupInfo.UsesLegacyReadLine;
Expand Down Expand Up @@ -406,7 +421,7 @@ public void Initialize(

if (powerShellVersion.Major >= 5 &&
this.isPSReadLineEnabled &&
PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, out PSReadLineProxy proxy))
PSReadLinePromptContext.TryGetPSReadLineProxy(logger, initialRunspace, s_bundledModulePath, out PSReadLineProxy proxy))
{
this.PromptContext = new PSReadLinePromptContext(
this,
Expand All @@ -430,15 +445,13 @@ public void Initialize(
/// the runspace. This method will be moved somewhere else soon.
/// </summary>
/// <returns></returns>
public Task ImportCommandsModuleAsync() => ImportCommandsModuleAsync(s_commandsModulePath);

public Task ImportCommandsModuleAsync(string path)
public Task ImportCommandsModuleAsync()
{
this.logger.LogTrace($"Importing PowershellEditorServices commands from {path}");
this.logger.LogTrace($"Importing PowershellEditorServices commands from {s_commandsModulePath}");

PSCommand importCommand = new PSCommand()
.AddCommand("Import-Module")
.AddArgument(path);
.AddArgument(s_commandsModulePath);

return this.ExecuteCommandAsync<PSObject>(importCommand, sendOutputToHost: false, sendErrorToHost: false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +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),
"..",
"..",
"..",
"PSReadLine");

// When using xUnit (dotnet test) the assemblies are deployed to the
// test project folder, invalidating our relative path assumption.
private static readonly string _psReadLineTestModulePath = Path.Combine(
Path.GetDirectoryName(typeof(PSReadLinePromptContext).Assembly.Location),
"..",
"..",
"..",
"..",
"..",
"module",
"PSReadLine");

private static readonly Lazy<CmdletInfo> s_lazyInvokeReadLineForEditorServicesCmdletInfo = new Lazy<CmdletInfo>(() =>
{
var type = Type.GetType("Microsoft.PowerShell.EditorServices.Commands.InvokeReadLineForEditorServicesCommand, Microsoft.PowerShell.EditorServices.Hosting");
Expand Down Expand Up @@ -84,16 +65,16 @@ internal PSReadLinePromptContext(
internal static bool TryGetPSReadLineProxy(
ILogger logger,
Runspace runspace,
out PSReadLineProxy readLineProxy,
bool testing = false)
string bundledModulePath,
out PSReadLineProxy readLineProxy)
{
readLineProxy = null;
logger.LogTrace("Attempting to load PSReadLine");
using (var pwsh = PowerShell.Create())
{
pwsh.Runspace = runspace;
pwsh.AddCommand("Microsoft.PowerShell.Core\\Import-Module")
.AddParameter("Name", testing ? _psReadLineTestModulePath : _psReadLineModulePath)
.AddParameter("Name", Path.Combine(bundledModulePath, "PSReadLine"))
.Invoke();

if (pwsh.HadErrors)
Expand Down
12 changes: 8 additions & 4 deletions test/PowerShellEditorServices.Test/PowerShellContextFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ internal static class PowerShellContextFactory
Path.GetFullPath(
TestUtilities.NormalizePath("../../../../PowerShellEditorServices.Test.Shared/ProfileTest.ps1")));

public static System.Management.Automation.Runspaces.Runspace initialRunspace;
public static readonly string BundledModulePath = Path.GetFullPath(
TestUtilities.NormalizePath("../../../../../module"));

public static System.Management.Automation.Runspaces.Runspace InitialRunspace;

public static PowerShellContextService Create(ILogger logger)
{
Expand All @@ -52,17 +55,18 @@ public static PowerShellContextService Create(ILogger logger)
null,
0,
consoleReplEnabled: false,
usesLegacyReadLine: false);
usesLegacyReadLine: false,
bundledModulePath: BundledModulePath);

initialRunspace = PowerShellContextService.CreateRunspace(
InitialRunspace = PowerShellContextService.CreateRunspace(
testHostDetails,
powerShellContext,
new TestPSHostUserInterface(powerShellContext, logger),
logger);

powerShellContext.Initialize(
TestProfilePaths,
initialRunspace,
InitialRunspace,
ownsInitialRunspace: true,
consoleHost: null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ public void CanGetPSReadLineProxy()
{
Assert.True(PSReadLinePromptContext.TryGetPSReadLineProxy(
NullLogger.Instance,
PowerShellContextFactory.initialRunspace,
out PSReadLineProxy proxy,
true));
PowerShellContextFactory.InitialRunspace,
PowerShellContextFactory.BundledModulePath,
out PSReadLineProxy proxy));
}

#region Helper Methods
Expand Down