From 262ab802d3e554b51d00d2d91ac9c4e0cff576a8 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 31 Jul 2020 10:38:31 -0700 Subject: [PATCH] launch: check prerequisites in a pre-launch task Fixes https://github.com/microsoft/vscode/issues/103708 --- .vscode/launch.json | 7 ++-- .vscode/tasks.json | 10 +++++- build/lib/builtInExtensions.js | 24 +++++++------ build/lib/preLaunch.js | 55 ++++++++++++++++++++++++++++ build/lib/preLaunch.ts | 65 ++++++++++++++++++++++++++++++++++ scripts/code-cli.bat | 14 ++------ scripts/code-cli.sh | 15 +++----- scripts/code.bat | 13 ++----- scripts/code.sh | 15 +++----- 9 files changed, 158 insertions(+), 60 deletions(-) create mode 100644 build/lib/preLaunch.js create mode 100644 build/lib/preLaunch.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index 9051afc7e8c76..577b733df800c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -216,10 +216,10 @@ "port": 9222, "timeout": 20000, "env": { - "VSCODE_EXTHOST_WILL_SEND_SOCKET": null + "VSCODE_EXTHOST_WILL_SEND_SOCKET": null, + "VSCODE_SKIP_PRELAUNCH": "1" }, "cleanUp": "wholeBrowser", - "breakOnLoad": false, "urlFilter": "*workbench.html*", "runtimeArgs": [ "--inspect=5875", @@ -232,7 +232,8 @@ "outFiles": [ "${workspaceFolder}/out/**/*.js" ], - "browserLaunchLocation": "workspace" + "browserLaunchLocation": "workspace", + "preLaunchTask": "Ensure Prelaunch Dependencies", }, { "type": "node", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 213183bc072d6..89967210c75c9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -186,6 +186,14 @@ "source": "eslint", "base": "$eslint-stylish" } - } + }, + { + "type": "shell", + "command": "node build/lib/prelaunch.js", + "label": "Ensure Prelaunch Dependencies", + "presentation": { + "reveal": "silent" + } + }, ] } diff --git a/build/lib/builtInExtensions.js b/build/lib/builtInExtensions.js index ebcf8bc8ddb2f..ea6c5289640e5 100644 --- a/build/lib/builtInExtensions.js +++ b/build/lib/builtInExtensions.js @@ -100,7 +100,7 @@ function writeControlFile(control) { fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2)); } -function main() { +exports.getBuiltInExtensions = function getBuiltInExtensions() { log('Syncronizing built-in extensions...'); log(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`); @@ -116,14 +116,16 @@ function main() { writeControlFile(control); - es.merge(streams) - .on('error', err => { - console.error(err); - process.exit(1); - }) - .on('end', () => { - process.exit(0); - }); + return new Promise((resolve, reject) => { + es.merge(streams) + .on('error', reject) + .on('end', resolve); + }); +}; + +if (require.main === module) { + main().then(() => process.exit(0)).catch(err => { + console.error(err); + process.exit(1); + }); } - -main(); diff --git a/build/lib/preLaunch.js b/build/lib/preLaunch.js new file mode 100644 index 0000000000000..1aecbe190487e --- /dev/null +++ b/build/lib/preLaunch.js @@ -0,0 +1,55 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); +// @ts-check +const path = require("path"); +const child_process_1 = require("child_process"); +const fs_1 = require("fs"); +const yarn = process.platform === 'win32' ? 'yarn.cmd' : 'yarn'; +const rootDir = path.resolve(__dirname, '..', '..'); +function runProcess(command, args = []) { + return new Promise((resolve, reject) => { + const child = child_process_1.spawn(command, args, { cwd: rootDir, stdio: 'inherit', env: process.env }); + child.on('exit', err => !err ? resolve() : process.exit(err !== null && err !== void 0 ? err : 1)); + child.on('error', reject); + }); +} +async function exists(subdir) { + try { + await fs_1.promises.stat(path.join(rootDir, subdir)); + return true; + } + catch (_a) { + return false; + } +} +async function ensureNodeModules() { + if (!(await exists('node_modules'))) { + await runProcess(yarn); + } +} +async function getElectron() { + await runProcess(yarn, ['electron']); +} +async function ensureCompiled() { + if (!(await exists('out'))) { + await runProcess(yarn, ['compile']); + } +} +async function main() { + await ensureNodeModules(); + await getElectron(); + await ensureCompiled(); + // Can't require this until after dependencies are installed + const { getBuiltInExtensions } = require('./builtInExtensions'); + await getBuiltInExtensions(); +} +if (require.main === module) { + main().catch(err => { + console.error(err); + process.exit(1); + }); +} diff --git a/build/lib/preLaunch.ts b/build/lib/preLaunch.ts new file mode 100644 index 0000000000000..bd084f5fec59d --- /dev/null +++ b/build/lib/preLaunch.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +// @ts-check + +import * as path from 'path'; +import { spawn } from 'child_process'; +import { promises as fs } from 'fs'; + +const yarn = process.platform === 'win32' ? 'yarn.cmd' : 'yarn'; +const rootDir = path.resolve(__dirname, '..', '..'); + +function runProcess(command: string, args: ReadonlyArray = []) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { cwd: rootDir, stdio: 'inherit', env: process.env }); + child.on('exit', err => !err ? resolve() : process.exit(err ?? 1)); + child.on('error', reject); + }); +} + +async function exists(subdir: string) { + try { + await fs.stat(path.join(rootDir, subdir)); + return true; + } catch { + return false; + } +} + +async function ensureNodeModules() { + if (!(await exists('node_modules'))) { + await runProcess(yarn); + } +} + +async function getElectron() { + await runProcess(yarn, ['electron']); +} + +async function ensureCompiled() { + if (!(await exists('out'))) { + await runProcess(yarn, ['compile']); + } +} + +async function main() { + await ensureNodeModules(); + await getElectron(); + await ensureCompiled(); + + // Can't require this until after dependencies are installed + const { getBuiltInExtensions } = require('./builtInExtensions'); + await getBuiltInExtensions(); +} + +if (require.main === module) { + main().catch(err => { + console.error(err); + process.exit(1); + }); +} diff --git a/scripts/code-cli.bat b/scripts/code-cli.bat index a07ccc96bf6d6..2e4e34ff32e7d 100644 --- a/scripts/code-cli.bat +++ b/scripts/code-cli.bat @@ -5,27 +5,17 @@ title VSCode Dev pushd %~dp0\.. -:: Node modules -if not exist node_modules call yarn +:: Get electron, compile, built-in extensions +if "%VSCODE_SKIP_PRELAUNCH%"=="" node build/lib/preLaunch.js for /f "tokens=2 delims=:," %%a in ('findstr /R /C:"\"nameShort\":.*" product.json') do set NAMESHORT=%%~a set NAMESHORT=%NAMESHORT: "=% set NAMESHORT=%NAMESHORT:"=%.exe set CODE=".build\electron\%NAMESHORT%" -:: Download Electron if needed -node build\lib\electron.js -if %errorlevel% neq 0 node .\node_modules\gulp\bin\gulp.js electron - :: Manage built-in extensions if "%1"=="--builtin" goto builtin -:: Sync built-in extensions -node build\lib\builtInExtensions.js - -:: Build -if not exist out yarn compile - :: Configuration set ELECTRON_RUN_AS_NODE=1 set NODE_ENV=development diff --git a/scripts/code-cli.sh b/scripts/code-cli.sh index e4fa552e64259..a792c08532ee6 100755 --- a/scripts/code-cli.sh +++ b/scripts/code-cli.sh @@ -18,11 +18,10 @@ function code() { CODE=".build/electron/$NAME" fi - # Node modules - test -d node_modules || yarn - - # Get electron - yarn electron + # Get electron, compile, built-in extensions + if [[ -z "${VSCODE_SKIP_PRELAUNCH}" ]]; then + node build/lib/preLaunch.js + fi # Manage built-in extensions if [[ "$1" == "--builtin" ]]; then @@ -30,12 +29,6 @@ function code() { return fi - # Sync built-in extensions - node build/lib/builtInExtensions.js - - # Build - test -d out || yarn compile - ELECTRON_RUN_AS_NODE=1 \ NODE_ENV=development \ VSCODE_DEV=1 \ diff --git a/scripts/code.bat b/scripts/code.bat index c4c1cc7c05799..7ef1fd33fe000 100644 --- a/scripts/code.bat +++ b/scripts/code.bat @@ -5,26 +5,17 @@ title VSCode Dev pushd %~dp0\.. -:: Node modules -if not exist node_modules call yarn +:: Get electron, compile, built-in extensions +if "%VSCODE_SKIP_PRELAUNCH%"=="" node build/lib/preLaunch.js for /f "tokens=2 delims=:," %%a in ('findstr /R /C:"\"nameShort\":.*" product.json') do set NAMESHORT=%%~a set NAMESHORT=%NAMESHORT: "=% set NAMESHORT=%NAMESHORT:"=%.exe set CODE=".build\electron\%NAMESHORT%" -:: Get electron -call yarn electron - :: Manage built-in extensions if "%1"=="--builtin" goto builtin -:: Sync built-in extensions -node build\lib\builtInExtensions.js - -:: Build -if not exist out yarn compile - :: Configuration set NODE_ENV=development set VSCODE_DEV=1 diff --git a/scripts/code.sh b/scripts/code.sh index 390aa4b201d22..b19cc0df9ff43 100755 --- a/scripts/code.sh +++ b/scripts/code.sh @@ -24,11 +24,10 @@ function code() { CODE=".build/electron/$NAME" fi - # Node modules - test -d node_modules || yarn - - # Get electron - yarn electron + # Get electron, compile, built-in extensions + if [[ -z "${VSCODE_SKIP_PRELAUNCH}" ]]; then + node build/lib/preLaunch.js + fi # Manage built-in extensions if [[ "$1" == "--builtin" ]]; then @@ -36,12 +35,6 @@ function code() { return fi - # Sync built-in extensions - node build/lib/builtInExtensions.js - - # Build - test -d out || yarn compile - # Configuration export NODE_ENV=development export VSCODE_DEV=1