Skip to content

Commit aaad6f3

Browse files
authored
Merge pull request #368 from PowerShell/daviwil/console-redux
Add integrated console support via custom host implementation
2 parents 1f5ec67 + ef35db7 commit aaad6f3

40 files changed

+3068
-1030
lines changed

.vscode/tasks.json

+1-6
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,7 @@
2828
"taskName": "Build",
2929
"suppressTaskName": true,
3030
"isBuildCommand": true,
31-
"args": [ "Invoke-Build BuildHost" ]
32-
},
33-
{
34-
"taskName": "Full Build",
35-
"suppressTaskName": true,
36-
"args": [ "Invoke-Build" ]
31+
"args": [ "Invoke-Build Build" ]
3732
},
3833
{
3934
"taskName": "Test",

PowerShellEditorServices.build.ps1

+8-13
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ if ($PSVersionTable.PSEdition -ne "Core") {
1818
Add-Type -Assembly System.IO.Compression.FileSystem
1919
}
2020

21-
task SetupDotNet -Before Restore, Clean, Build, BuildHost, Test, TestPowerShellApi, PackageNuGet {
21+
task SetupDotNet -Before Restore, Clean, Build, Test, TestPowerShellApi, PackageNuGet {
2222

23-
# Fetch the SDK version from global.json
2423
$requiredSdkVersion = "1.0.0-rc4-004771"
2524

2625
$needsInstall = $true
@@ -92,7 +91,7 @@ function NeedsRestore($rootPath) {
9291
return ($projectAssets -eq $null) -or ((Get-ChildItem $rootPath).Length -gt $projectAssets.Length)
9392
}
9493

95-
task Restore -If { "Restore" -in $BuildTask -or (NeedsRestore(".\src")) -or (NeedsRestore(".\test")) } -Before Clean, Build, BuildHost, Test {
94+
task Restore -If { "Restore" -in $BuildTask -or (NeedsRestore(".\src")) -or (NeedsRestore(".\test")) } -Before Clean, Build, Test {
9695
exec { & $script:dotnetExe restore }
9796
}
9897

@@ -136,17 +135,13 @@ task TestPowerShellApi -If { !$script:IsUnix } {
136135
exec { & $script:dotnetExe restore .\src\PowerShellEditorServices\PowerShellEditorServices.csproj }
137136
}
138137

139-
task BuildHost {
140-
exec { & $script:dotnetExe build -c $Configuration .\src\PowerShellEditorServices.Host\PowerShellEditorServices.Host.csproj $script:TargetFrameworksParam }
141-
}
142-
143138
task Build {
144-
exec { & $script:dotnetExe build -c $Configuration .\PowerShellEditorServices.sln $script:TargetFrameworksParam }
139+
exec { & $script:dotnetExe build -c $Configuration .\src\PowerShellEditorServices.Host\PowerShellEditorServices.Host.csproj $script:TargetFrameworksParam }
145140
}
146141

147142
function UploadTestLogs {
148143
if ($script:IsCIBuild) {
149-
$testLogsPath = "$PSScriptRoot/test/PowerShellEditorServices.Test.Host/bin/$Configuration/net451/logs"
144+
$testLogsPath = "$PSScriptRoot/test/PowerShellEditorServices.Test.Host/bin/$Configuration/net452/logs"
150145
$testLogsZipPath = "$PSScriptRoot/TestLogs.zip"
151146

152147
if (Test-Path $testLogsPath) {
@@ -163,9 +158,9 @@ function UploadTestLogs {
163158
}
164159

165160
task Test -If { !$script:IsUnix } {
166-
exec { & $script:dotnetExe test -c $Configuration -f net451 .\test\PowerShellEditorServices.Test\PowerShellEditorServices.Test.csproj }
167-
exec { & $script:dotnetExe test -c $Configuration -f net451 .\test\PowerShellEditorServices.Test.Protocol\PowerShellEditorServices.Test.Protocol.csproj }
168-
exec { & $script:dotnetExe test -c $Configuration -f net451 .\test\PowerShellEditorServices.Test.Host\PowerShellEditorServices.Test.Host.csproj }
161+
exec { & $script:dotnetExe test -c $Configuration -f net452 .\test\PowerShellEditorServices.Test\PowerShellEditorServices.Test.csproj }
162+
exec { & $script:dotnetExe test -c $Configuration -f net452 .\test\PowerShellEditorServices.Test.Protocol\PowerShellEditorServices.Test.Protocol.csproj }
163+
exec { & $script:dotnetExe test -c $Configuration -f net452 .\test\PowerShellEditorServices.Test.Host\PowerShellEditorServices.Test.Host.csproj }
169164
}
170165

171166
task CITest (job Test -Safe), {
@@ -177,7 +172,7 @@ task CITest (job Test -Safe), {
177172
}
178173
}
179174

180-
task LayoutModule -After Build, BuildHost {
175+
task LayoutModule -After Build {
181176
New-Item -Force $PSScriptRoot\module\PowerShellEditorServices\bin\ -Type Directory | Out-Null
182177
New-Item -Force $PSScriptRoot\module\PowerShellEditorServices\bin\Desktop -Type Directory | Out-Null
183178
New-Item -Force $PSScriptRoot\module\PowerShellEditorServices\bin\Core -Type Directory | Out-Null

module/PowerShellEditorServices/PowerShellEditorServices.psm1

+15-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ function Start-EditorServicesHost {
4646
[ValidateSet("Normal", "Verbose", "Error")]
4747
$LogLevel = "Normal",
4848

49+
[switch]
50+
$EnableConsoleRepl,
51+
52+
[string]
53+
$DebugServiceOnly,
54+
4955
[switch]
5056
$WaitForDebugger
5157
)
@@ -58,6 +64,7 @@ function Start-EditorServicesHost {
5864
New-Object Microsoft.PowerShell.EditorServices.Host.EditorServicesHost @(
5965
$hostDetails,
6066
$BundledModulesPath,
67+
$EnableConsoleRepl.IsPresent,
6168
$WaitForDebugger.IsPresent)
6269

6370
# Build the profile paths using the root paths of the current $profile variable
@@ -67,8 +74,14 @@ function Start-EditorServicesHost {
6774
[System.IO.Path]::GetDirectoryName($profile.CurrentUserAllHosts));
6875

6976
$editorServicesHost.StartLogging($LogPath, $LogLevel);
70-
$editorServicesHost.StartLanguageService($LanguageServicePort, $profilePaths);
71-
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths);
77+
78+
if ($DebugServiceOnly.IsPresent) {
79+
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $false);
80+
}
81+
else {
82+
$editorServicesHost.StartLanguageService($LanguageServicePort, $profilePaths);
83+
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $true);
84+
}
7285
}
7386
catch {
7487
Write-Error "PowerShell Editor Services host initialization failed, terminating."

src/PowerShellEditorServices.Host/EditorServicesHost.cs

+40-13
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class EditorServicesHost
2929
{
3030
#region Private Fields
3131

32+
private bool enableConsoleRepl;
3233
private HostDetails hostDetails;
3334
private string bundledModulesPath;
3435
private DebugAdapter debugAdapter;
@@ -58,11 +59,13 @@ public class EditorServicesHost
5859
public EditorServicesHost(
5960
HostDetails hostDetails,
6061
string bundledModulesPath,
62+
bool enableConsoleRepl,
6163
bool waitForDebugger)
6264
{
6365
Validate.IsNotNull(nameof(hostDetails), hostDetails);
6466

6567
this.hostDetails = hostDetails;
68+
this.enableConsoleRepl = enableConsoleRepl;
6669
this.bundledModulesPath = bundledModulesPath;
6770

6871
#if DEBUG
@@ -143,6 +146,7 @@ public void StartLanguageService(int languageServicePort, ProfilePaths profilePa
143146
new LanguageServer(
144147
hostDetails,
145148
profilePaths,
149+
this.enableConsoleRepl,
146150
new TcpSocketServerChannel(languageServicePort));
147151

148152
this.languageServer.Start().Wait();
@@ -158,23 +162,46 @@ public void StartLanguageService(int languageServicePort, ProfilePaths profilePa
158162
/// Starts the debug service with the specified TCP socket port.
159163
/// </summary>
160164
/// <param name="debugServicePort">The port number for the debug service.</param>
161-
public void StartDebugService(int debugServicePort, ProfilePaths profilePaths)
165+
public void StartDebugService(
166+
int debugServicePort,
167+
ProfilePaths profilePaths,
168+
bool useExistingSession)
162169
{
163-
this.debugAdapter =
164-
new DebugAdapter(
165-
hostDetails,
166-
profilePaths,
167-
new TcpSocketServerChannel(debugServicePort),
168-
this.languageServer?.EditorOperations);
170+
if (this.enableConsoleRepl && useExistingSession)
171+
{
172+
this.debugAdapter =
173+
new DebugAdapter(
174+
this.languageServer.EditorSession,
175+
new TcpSocketServerChannel(debugServicePort));
176+
}
177+
else
178+
{
179+
this.debugAdapter =
180+
new DebugAdapter(
181+
hostDetails,
182+
profilePaths,
183+
new TcpSocketServerChannel(debugServicePort),
184+
this.languageServer?.EditorOperations);
185+
}
169186

170187
this.debugAdapter.SessionEnded +=
171188
(obj, args) =>
172189
{
173-
Logger.Write(
174-
LogLevel.Normal,
175-
"Previous debug session ended, restarting debug service...");
176-
177-
this.StartDebugService(debugServicePort, profilePaths);
190+
// Only restart if we're reusing the existing session
191+
// or if we're not using the console REPL, otherwise
192+
// the process should terminate
193+
if (useExistingSession)
194+
{
195+
Logger.Write(
196+
LogLevel.Normal,
197+
"Previous debug session ended, restarting debug service...");
198+
199+
this.StartDebugService(debugServicePort, profilePaths, true);
200+
}
201+
else if (!this.enableConsoleRepl)
202+
{
203+
this.StartDebugService(debugServicePort, profilePaths, false);
204+
}
178205
};
179206

180207
this.debugAdapter.Start().Wait();
@@ -222,7 +249,7 @@ public void WaitForCompletion()
222249

223250
#if !CoreCLR
224251
static void CurrentDomain_UnhandledException(
225-
object sender,
252+
object sender,
226253
UnhandledExceptionEventArgs e)
227254
{
228255
// Log the exception

0 commit comments

Comments
 (0)