Skip to content

Release 0.7.0 #242

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

Merged
merged 2 commits into from
Aug 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# vscode-powershell Release History

## 0.7.0
### Thursday, August 18, 2016

#### Introducing support for Linux and macOS!

This release marks the beginning of our support for Linux and macOS via
the new [cross-platform release of PowerShell](https://github.com/PowerShell/PowerShell).
You can find installation and usage instructions at the [PowerShell GitHub repository](https://github.com/PowerShell/PowerShell).

## 0.6.2
### Friday, August 12, 2016

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ how to use them.

This folder can be found at the following path:
```
$env:USERPROFILE\.vscode\extensions\ms-vscode.PowerShell-<version>\examples
c:\Users\<yourusername>\.vscode\extensions\ms-vscode.PowerShell-<version>\examples
```
To open/view the extension's examples Visual Studio Code, run the following from your PowerShell command prompt:
```
Expand Down
2 changes: 1 addition & 1 deletion examples/StopTest.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. .\Stop-Process2.ps1
. ./Stop-Process2.ps1

notepad.exe
notepad.exe
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "PowerShell",
"displayName": "PowerShell",
"version": "0.6.2",
"version": "0.7.0",
"publisher": "ms-vscode",
"description": "Develop PowerShell scripts in Visual Studio Code!",
"engines": {
Expand Down Expand Up @@ -182,6 +182,11 @@
"default": "",
"description": "Specifies the path to a PowerShell Script Analyzer settings file. Use either an absolute path (to override the default settings for all projects) or use a path relative to your workspace."
},
"powershell.developer.powerShellExePath": {
"type": "string",
"default": "",
"description": "Specifies the full path to a PowerShell executable. Used to change the installation of PowerShell used for language and debugging services."
},
"powershell.developer.bundledModulesPath": {
"type": "string",
"default": "../modules/",
Expand Down
169 changes: 145 additions & 24 deletions scripts/Start-EditorServices.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# PowerShell Editor Services Bootstrapper Script
# ----------------------------------------------
# This script contains startup logic for the PowerShell Editor Services
# module when launched by an editor. It handles the following tasks:
#
# - Verifying the existence of dependencies like PowerShellGet
# - Verifying that the expected version of the PowerShellEditorServices module is installed
# - Installing the PowerShellEditorServices module if confirmed by the user
# - Finding unused TCP port numbers for the language and debug services to use
# - Starting the language and debug services from the PowerShellEditorServices module
#
# NOTE: If editor integration authors make modifications to this
# script, please consider contributing changes back to the
# canonical version of this script at the PowerShell Editor
# Services GitHub repository:
#
# https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/Start-EditorServices.ps1

param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
Expand All @@ -19,16 +37,6 @@ param(
[string]
$HostVersion,

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$LanguageServicePipeName,

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$DebugServicePipeName,

[ValidateNotNullOrEmpty()]
[string]
$BundledModulesPath,
Expand All @@ -40,28 +48,141 @@ param(
$LogLevel,

[switch]
$WaitForCompletion,
$WaitForDebugger,

[switch]
$WaitForDebugger
$ConfirmInstall
)

# This variable will be assigned later to contain information about
# what happened while attempting to launch the PowerShell Editor
# Services host
$resultDetails = $null;

function Test-ModuleAvailable($ModuleName, $ModuleVersion) {
$modules = Get-Module -ListAvailable $moduleName
if ($modules -ne $null) {
if ($ModuleVersion -ne $null) {
foreach ($module in $modules) {
if ($module.Version.Equals($moduleVersion)) {
return $true;
}
}
}
else {
return $true;
}
}

return $false;
}

function Test-PortAvailability($PortNumber) {
$portAvailable = $true;

try {
$ipAddress = [System.Net.Dns]::GetHostEntryAsync("localhost").Result.AddressList[0];
$tcpListener = [System.Net.Sockets.TcpListener]::new($ipAddress, $portNumber);
$tcpListener.Start();
$tcpListener.Stop();

}
catch [System.Net.Sockets.SocketException] {
# Check the SocketErrorCode to see if it's the expected exception
if ($error[0].Exception.InnerException.SocketErrorCode -eq [System.Net.Sockets.SocketError]::AddressAlreadyInUse) {
$portAvailable = $false;
}
else {
Write-Output ("Error code: " + $error[0].SocketErrorCode)
}
}

return $portAvailable;
}

$rand = [System.Random]::new()
function Get-AvailablePort {
$triesRemaining = 10;

while ($triesRemaining -gt 0) {
$port = $rand.Next(10000, 30000)
if ((Test-PortAvailability -PortAvailability $port) -eq $true) {
return $port
}

$triesRemaining--;
}

return $null
}

# Add BundledModulesPath to $env:PSModulePath
if ($BundledModulesPath) {
$env:PSModulePath = $BundledModulesPath + ";" + $env:PSModulePath
$env:PSMODULEPATH = $BundledModulesPath + [System.IO.Path]::PathSeparator + $env:PSMODULEPATH
}

# Check if PowerShellGet module is available
if ((Test-ModuleAvailable "PowerShellGet") -eq $false) {
# TODO: WRITE ERROR
}

# Check if the expected version of the PowerShell Editor Services
# module is installed
$parsedVersion = [System.Version]::new($EditorServicesVersion)
if ((Test-ModuleAvailable "PowerShellEditorServices" -RequiredVersion $parsedVersion) -eq $false) {
if ($ConfirmInstall) {
# TODO: Check for error and return failure if necessary
Install-Module "PowerShellEditorServices" -RequiredVersion $parsedVersion -Confirm
}
else {
# Indicate to the client that the PowerShellEditorServices module
# needs to be installed
Write-Output "needs_install"
}
}

Import-Module PowerShellEditorServices -RequiredVersion $parsedVersion -ErrorAction Stop

Start-EditorServicesHost `
-HostName $HostName `
-HostProfileId $HostProfileId `
-HostVersion $HostVersion `
-LogPath $LogPath `
-LogLevel $LogLevel `
-LanguageServicePipeName $LanguageServicePipeName `
-DebugServicePipeName $DebugServicePipeName `
-BundledModulesPath $BundledModulesPath `
-WaitForCompletion:$WaitForCompletion.IsPresent `
-WaitForDebugger:$WaitForDebugger.IsPresent
# Locate available port numbers for services
$languageServicePort = Get-AvailablePort
$debugServicePort = Get-AvailablePort

$editorServicesHost =
Start-EditorServicesHost `
-HostName $HostName `
-HostProfileId $HostProfileId `
-HostVersion $HostVersion `
-LogPath $LogPath `
-LogLevel $LogLevel `
-LanguageServicePort $languageServicePort `
-DebugServicePort $debugServicePort `
-BundledModulesPath $BundledModulesPath `
-WaitForDebugger:$WaitForDebugger.IsPresent

# TODO: Verify that the service is started

$resultDetails = @{
"status" = "started";
"channel" = "tcp";
"languageServicePort" = $languageServicePort;
"debugServicePort" = $debugServicePort;
};

# Notify the client that the services have started
Write-Output (ConvertTo-Json -InputObject $resultDetails -Compress)

try {
# Wait for the host to complete execution before exiting
$editorServicesHost.WaitForCompletion()
}
catch [System.Exception] {
$e = $_.Exception; #.InnerException;
$errorString = ""

while ($e -ne $null) {
$errorString = $errorString + ($e.Message + "`r`n" + $e.StackTrace + "`r`n")
$e = $e.InnerException;
}

Write-Error ("`r`nCaught error while waiting for EditorServicesHost to complete:`r`n" + $errorString)
}
30 changes: 24 additions & 6 deletions src/debugAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs = require('fs');
import path = require('path');
import net = require('net');
import utils = require('./utils');
import logging = require('./logging');

// NOTE: The purpose of this file is to serve as a bridge between
Expand All @@ -10,7 +11,7 @@ import logging = require('./logging');
// relay between the two transports.

var logBasePath = path.resolve(__dirname, "../logs");
logging.ensurePathExists(logBasePath);
utils.ensurePathExists(logBasePath);

var debugAdapterLogWriter =
fs.createWriteStream(
Expand All @@ -22,15 +23,18 @@ var debugAdapterLogWriter =
// debug server
process.stdin.pause();

// Read the details of the current session to learn
// the connection details for the debug service
let sessionDetails = utils.readSessionFile();

// Establish connection before setting up the session
let pipeName = "\\\\.\\pipe\\PSES-VSCode-DebugService-" + process.env.VSCODE_PID;
debugAdapterLogWriter.write("Connecting to named pipe: " + pipeName + "\r\n");
let debugServiceSocket = net.connect(pipeName);
debugAdapterLogWriter.write("Connecting to port: " + sessionDetails.debugServicePort + "\r\n");
let debugServiceSocket = net.connect(sessionDetails.debugServicePort);

// Write any errors to the log file
debugServiceSocket.on(
'error',
(e) => debugAdapterLogWriter.write("Named pipe ERROR: " + e + "\r\n"));
(e) => debugAdapterLogWriter.write("Socket connect ERROR: " + e + "\r\n"));

// Route any output from the socket through stdout
debugServiceSocket.on(
Expand All @@ -41,7 +45,7 @@ debugServiceSocket.on(
debugServiceSocket.on(
'connect',
() => {
debugAdapterLogWriter.write("Connected to named pipe: " + pipeName + "\r\n");
debugAdapterLogWriter.write("Connected to socket!\r\n\r\n");

// When data comes on stdin, route it through the socket
process.stdin.on(
Expand All @@ -51,3 +55,17 @@ debugServiceSocket.on(
// Resume the stdin stream
process.stdin.resume();
});

// When the socket closes, end the session
debugServiceSocket.on(
'close',
() => {
debugAdapterLogWriter.write("Socket closed, shutting down.");

// Close after a short delay to give the client time
// to finish up
setTimeout(() => {
process.exit(0);
}, 1000);
}
)
14 changes: 0 additions & 14 deletions src/logging.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,5 @@
import fs = require('fs');

export function ensurePathExists(targetPath: string) {
// Ensure that the path exists
try {
fs.mkdirSync(targetPath);
}
catch (e) {
// If the exception isn't to indicate that the folder
// exists already, rethrow it.
if (e.code != 'EEXIST') {
throw e;
}
}
}

export function getLogName(baseName: string): string {
return Math.floor(Date.now() / 1000) + '-' + baseName + '.log';
}
Loading