From da02c2e2c8f372cb8b7b6e83d1d67f5c21aec8dc Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 25 Nov 2021 01:04:42 +0100 Subject: [PATCH] chore: add --dry-run to install-deps CLI command (#10520) --- packages/playwright-core/src/cli/innerCli.ts | 11 ++++---- .../playwright-core/src/utils/dependencies.ts | 27 ++++++++++++++++--- .../playwright-core/src/utils/registry.ts | 6 ++--- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/playwright-core/src/cli/innerCli.ts b/packages/playwright-core/src/cli/innerCli.ts index 1eb80e3bab..3c25ebdb60 100644 --- a/packages/playwright-core/src/cli/innerCli.ts +++ b/packages/playwright-core/src/cli/innerCli.ts @@ -107,7 +107,7 @@ program if (!args.length) { const executables = registry.defaultExecutables(); if (options.withDeps) - await registry.installDeps(executables); + await registry.installDeps(executables, false); await registry.install(executables); } else { const installDockerImage = args.some(arg => arg === 'docker-image'); @@ -123,7 +123,7 @@ program const executables = checkBrowsersToInstall(args); if (options.withDeps) - await registry.installDeps(executables); + await registry.installDeps(executables, false); await registry.install(executables); } } catch (e) { @@ -143,12 +143,13 @@ Examples: program .command('install-deps [browser...]') .description('install dependencies necessary to run browsers (will ask for sudo permissions)') - .action(async function(args: string[]) { + .option('--dry-run', 'Do not execute installation commands, only print them') + .action(async function(args: string[], options: { dryRun?: boolean }) { try { if (!args.length) - await registry.installDeps(registry.defaultExecutables()); + await registry.installDeps(registry.defaultExecutables(), !!options.dryRun); else - await registry.installDeps(checkBrowsersToInstall(args)); + await registry.installDeps(checkBrowsersToInstall(args), !!options.dryRun); } catch (e) { console.log(`Failed to install browser dependencies\n${e}`); process.exit(1); diff --git a/packages/playwright-core/src/utils/dependencies.ts b/packages/playwright-core/src/utils/dependencies.ts index 00df9c1ff1..0b69b36e31 100644 --- a/packages/playwright-core/src/utils/dependencies.ts +++ b/packages/playwright-core/src/utils/dependencies.ts @@ -38,15 +38,21 @@ function isSupportedWindowsVersion(): boolean { export type DependencyGroup = 'chromium' | 'firefox' | 'webkit' | 'tools'; -export async function installDependenciesWindows(targets: Set) { +export async function installDependenciesWindows(targets: Set, dryRun: boolean): Promise { if (targets.has('chromium')) { - const { code } = await utils.spawnAsync('powershell.exe', ['-ExecutionPolicy', 'Bypass', '-File', path.join(BIN_DIRECTORY, 'install_media_pack.ps1')], { cwd: BIN_DIRECTORY, stdio: 'inherit' }); + const command = 'powershell.exe'; + const args = ['-ExecutionPolicy', 'Bypass', '-File', path.join(BIN_DIRECTORY, 'install_media_pack.ps1')]; + if (dryRun) { + console.log(`${command} ${quoteProcessArgs(args).join(' ')}`); // eslint-disable-line no-console + return; + } + const { code } = await utils.spawnAsync(command, args, { cwd: BIN_DIRECTORY, stdio: 'inherit' }); if (code !== 0) throw new Error('Failed to install windows dependencies!'); } } -export async function installDependenciesLinux(targets: Set) { +export async function installDependenciesLinux(targets: Set, dryRun: boolean) { const libraries: string[] = []; for (const target of targets) { const info = deps[utils.hostPlatform]; @@ -57,13 +63,18 @@ export async function installDependenciesLinux(targets: Set) { libraries.push(...info[target]); } const uniqueLibraries = Array.from(new Set(libraries)); - console.log('Installing Ubuntu dependencies...'); // eslint-disable-line no-console + if (!dryRun) + console.log('Installing Ubuntu dependencies...'); // eslint-disable-line no-console const commands: string[] = []; commands.push('apt-get update'); commands.push(['apt-get', 'install', '-y', '--no-install-recommends', ...uniqueLibraries, ].join(' ')); const [command, args] = await buildAptProcessArgs(commands); + if (dryRun) { + console.log(`${command} ${quoteProcessArgs(args).join(' ')}`); // eslint-disable-line no-console + return; + } const child = childProcess.spawn(command, args, { stdio: 'inherit' }); await new Promise((resolve, reject) => { child.on('exit', resolve); @@ -293,3 +304,11 @@ const MANUAL_LIBRARY_TO_PACKAGE_NAME_UBUNTU: { [s: string]: string} = { // gstreamer1.0-libav -> libavcodec57 -> libx264-152 'libx264.so': 'gstreamer1.0-libav', }; + +function quoteProcessArgs(args: string[]): string[] { + return args.map(arg => { + if (arg.includes(' ')) + return `"${arg}"`; + return arg; + }); +} diff --git a/packages/playwright-core/src/utils/registry.ts b/packages/playwright-core/src/utils/registry.ts index 453e89d83c..2f8f5ff92c 100644 --- a/packages/playwright-core/src/utils/registry.ts +++ b/packages/playwright-core/src/utils/registry.ts @@ -526,7 +526,7 @@ export class Registry { return await validateDependenciesWindows(windowsExeAndDllDirectories.map(d => path.join(browserDirectory, d))); } - async installDeps(executablesToInstallDeps: Executable[]) { + async installDeps(executablesToInstallDeps: Executable[], dryRun: boolean) { const executables = this._addRequirementsAndDedupe(executablesToInstallDeps); const targets = new Set(); for (const executable of executables) { @@ -535,9 +535,9 @@ export class Registry { } targets.add('tools'); if (os.platform() === 'win32') - return await installDependenciesWindows(targets); + return await installDependenciesWindows(targets, dryRun); if (os.platform() === 'linux') - return await installDependenciesLinux(targets); + return await installDependenciesLinux(targets, dryRun); } async install(executablesToInstall: Executable[]) {