Skip to content

Commit ef6d8eb

Browse files
committed
first cut of "server-ready-action" feature
1 parent b05c75c commit ef6d8eb

8 files changed

Lines changed: 230 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
src/**
2+
tsconfig.json
3+
out/**
4+
extension.webpack.config.js
5+
yarn.lock
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
//@ts-check
7+
8+
'use strict';
9+
10+
const withDefaults = require('../shared.webpack.config');
11+
12+
module.exports = withDefaults({
13+
context: __dirname,
14+
entry: {
15+
extension: './src/extension.ts',
16+
},
17+
resolve: {
18+
mainFields: ['module', 'main']
19+
}
20+
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"name": "debug-auto-launch",
3+
"displayName": "%displayName%",
4+
"description": "%description%",
5+
"version": "1.0.0",
6+
"publisher": "vscode",
7+
"engines": {
8+
"vscode": "^1.32.0"
9+
},
10+
"activationEvents": [
11+
"onDebugResolve"
12+
],
13+
"main": "./out/extension",
14+
"scripts": {
15+
"compile": "gulp compile-extension:debug-server-ready",
16+
"watch": "gulp watch-extension:debug-server-ready"
17+
},
18+
"contributes": {
19+
"debuggers": [
20+
{
21+
"type": "node",
22+
"configurationAttributes": {
23+
"launch": {
24+
"properties": {
25+
"serverReadyAction": {
26+
"type": "object",
27+
"markdownDescription": "Server Ready options.",
28+
"default": {
29+
"action": "openExternally"
30+
},
31+
"properties": {
32+
"pattern": {
33+
"type": "string",
34+
"markdownDescription": "Server is ready if this pattern appears on the debug console. The first group must include the port number.",
35+
"default": "listening on port ([0-9]+)"
36+
},
37+
"uriFormat": {
38+
"type": "string",
39+
"markdownDescription": "A format string used when constructing the URI. The first '%s' is substituted with the port number.",
40+
"default": "http://localhost:%s"
41+
},
42+
"action": {
43+
"type": "string",
44+
"enum": [
45+
"openExternally",
46+
"debugWithChrome"
47+
],
48+
"enumDescriptions": [
49+
"Open URI externally.",
50+
"Start debugging with the Debugger for Chrome."
51+
],
52+
"markdownDescription": "Determines what to do with when the server is ready.",
53+
"default": "openExternally"
54+
},
55+
"webRoot": {
56+
"type": "string",
57+
"markdownDescription": "Literally passed to chrome debug configuration.",
58+
"default": "${workspaceFolder}"
59+
}
60+
}
61+
}
62+
}
63+
}
64+
}
65+
}
66+
]
67+
},
68+
"dependencies": {
69+
"vscode-nls": "^4.0.0"
70+
},
71+
"devDependencies": {
72+
"@types/node": "8.0.33"
73+
}
74+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"displayName": "Server Ready Action",
3+
"description": "Open URI in browser if server under debugging is ready."
4+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
//import * as nls from 'vscode-nls';
8+
import * as util from 'util';
9+
10+
const trackers = new Set<string>();
11+
12+
const PATTERN = 'listening on.* (https?://\\S+|[0-9]+)'; // matches "listening on port 3000" or "Now listening on: https://localhost:5001"
13+
const URI_FORMAT = 'http://localhost:%s';
14+
const WEB_ROOT = '${workspaceFolder}';
15+
16+
interface ServerReadyAction {
17+
pattern: string;
18+
action?: 'openExternally' | 'debugWithChrome';
19+
urlFormat?: string;
20+
webRoot?: string;
21+
}
22+
23+
export function activate(context: vscode.ExtensionContext) {
24+
25+
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('*', {
26+
resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration) {
27+
const args: ServerReadyAction = debugConfiguration.serverReadyAction;
28+
if (debugConfiguration.type && args) {
29+
startTrackerForType(context, debugConfiguration.type);
30+
}
31+
return debugConfiguration;
32+
}
33+
}));
34+
}
35+
36+
function startTrackerForType(context: vscode.ExtensionContext, type: string) {
37+
38+
if (!trackers.has(type)) {
39+
trackers.add(type);
40+
41+
// scan debug console output for a PORT message
42+
context.subscriptions.push(vscode.debug.registerDebugAdapterTrackerFactory(type, {
43+
createDebugAdapterTracker(session: vscode.DebugSession) {
44+
const args: ServerReadyAction = session.configuration.serverReadyAction;
45+
if (args) {
46+
const regexp = new RegExp(args.pattern || PATTERN);
47+
let hasFired = false;
48+
return {
49+
onDidSendMessage: m => {
50+
if (!hasFired && m.type === 'event' && m.event === 'output' && m.body.output) {
51+
const result = regexp.exec(m.body.output);
52+
if (result && result.length === 2) {
53+
openExternalWithString(session, result[1]);
54+
hasFired = true;
55+
}
56+
}
57+
}
58+
};
59+
}
60+
return undefined;
61+
}
62+
}));
63+
}
64+
}
65+
66+
function openExternalWithString(session: vscode.DebugSession, portOrUriString: string) {
67+
68+
if (portOrUriString) {
69+
if (/^[0-9]+$/.test(portOrUriString)) {
70+
const args: ServerReadyAction = session.configuration.serverReadyAction;
71+
portOrUriString = util.format(args.urlFormat || URI_FORMAT, portOrUriString);
72+
}
73+
openExternalWithUri(session, portOrUriString);
74+
}
75+
}
76+
77+
function openExternalWithUri(session: vscode.DebugSession, uri: string) {
78+
79+
const args: ServerReadyAction = session.configuration.serverReadyAction;
80+
switch (args.action || 'openExternally') {
81+
case 'openExternally':
82+
vscode.env.openExternal(vscode.Uri.parse(uri));
83+
break;
84+
case 'debugWithChrome':
85+
vscode.debug.startDebugging(session.workspaceFolder, {
86+
type: 'chrome',
87+
name: 'Chrome Debug',
88+
request: 'launch',
89+
url: uri,
90+
webRoot: args.webRoot || WEB_ROOT
91+
});
92+
break;
93+
default:
94+
// not supported
95+
break;
96+
}
97+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
/// <reference path='../../../../src/vs/vscode.d.ts'/>
7+
/// <reference types='@types/node'/>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../shared.tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "./out",
5+
"downlevelIteration": true
6+
},
7+
"include": [
8+
"src/**/*"
9+
]
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
"@types/node@8.0.33":
6+
version "8.0.33"
7+
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd"
8+
integrity sha512-vmCdO8Bm1ExT+FWfC9sd9r4jwqM7o97gGy2WBshkkXbf/2nLAJQUrZfIhw27yVOtLUev6kSZc4cav/46KbDd8A==
9+
10+
vscode-nls@^4.0.0:
11+
version "4.0.0"
12+
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
13+
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==

0 commit comments

Comments
 (0)