mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: add a basic CLI for fetching the browsers (#9671)
This commit is contained in:
parent
c6054ac1a5
commit
6e428edb9d
57
package-lock.json
generated
57
package-lock.json
generated
@ -2708,7 +2708,6 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"string-width": "^4.2.0",
|
"string-width": "^4.2.0",
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
@ -8426,10 +8425,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yargs": {
|
"node_modules/yargs": {
|
||||||
"version": "17.6.0",
|
"version": "17.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
|
||||||
"integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
|
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cliui": "^8.0.1",
|
"cliui": "^8.0.1",
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.1",
|
||||||
@ -8437,7 +8435,7 @@
|
|||||||
"require-directory": "^2.1.1",
|
"require-directory": "^2.1.1",
|
||||||
"string-width": "^4.2.3",
|
"string-width": "^4.2.3",
|
||||||
"y18n": "^5.0.5",
|
"y18n": "^5.0.5",
|
||||||
"yargs-parser": "^21.0.0"
|
"yargs-parser": "^21.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
@ -8500,7 +8498,6 @@
|
|||||||
"version": "21.1.1",
|
"version": "21.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
@ -8571,12 +8568,18 @@
|
|||||||
"debug": "4.3.4",
|
"debug": "4.3.4",
|
||||||
"extract-zip": "2.0.1",
|
"extract-zip": "2.0.1",
|
||||||
"https-proxy-agent": "5.0.1",
|
"https-proxy-agent": "5.0.1",
|
||||||
|
"progress": "2.0.3",
|
||||||
"proxy-from-env": "1.1.0",
|
"proxy-from-env": "1.1.0",
|
||||||
"tar-fs": "2.1.1",
|
"tar-fs": "2.1.1",
|
||||||
"unbzip2-stream": "1.4.3"
|
"unbzip2-stream": "1.4.3",
|
||||||
|
"yargs": "17.6.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"browsers": "lib/cjs/browsers.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^14.15.0"
|
"@types/node": "^14.15.0",
|
||||||
|
"@types/yargs": "17.0.22"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.1.0"
|
"node": ">=14.1.0"
|
||||||
@ -8596,6 +8599,15 @@
|
|||||||
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
|
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"packages/browsers/node_modules/@types/yargs": {
|
||||||
|
"version": "17.0.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz",
|
||||||
|
"integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/yargs-parser": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"packages/ng-schematics": {
|
"packages/ng-schematics": {
|
||||||
"name": "@puppeteer/ng-schematics",
|
"name": "@puppeteer/ng-schematics",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
@ -9965,12 +9977,15 @@
|
|||||||
"version": "file:packages/browsers",
|
"version": "file:packages/browsers",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "^14.15.0",
|
"@types/node": "^14.15.0",
|
||||||
|
"@types/yargs": "17.0.22",
|
||||||
"debug": "4.3.4",
|
"debug": "4.3.4",
|
||||||
"extract-zip": "2.0.1",
|
"extract-zip": "2.0.1",
|
||||||
"https-proxy-agent": "5.0.1",
|
"https-proxy-agent": "5.0.1",
|
||||||
|
"progress": "2.0.3",
|
||||||
"proxy-from-env": "1.1.0",
|
"proxy-from-env": "1.1.0",
|
||||||
"tar-fs": "2.1.1",
|
"tar-fs": "2.1.1",
|
||||||
"unbzip2-stream": "1.4.3"
|
"unbzip2-stream": "1.4.3",
|
||||||
|
"yargs": "17.6.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
@ -9978,6 +9993,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.36.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.36.tgz",
|
||||||
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
|
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/yargs": {
|
||||||
|
"version": "17.0.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz",
|
||||||
|
"integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/yargs-parser": "*"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11023,7 +11047,6 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"string-width": "^4.2.0",
|
"string-width": "^4.2.0",
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
@ -15216,10 +15239,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"yargs": {
|
"yargs": {
|
||||||
"version": "17.6.0",
|
"version": "17.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
|
||||||
"integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
|
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"cliui": "^8.0.1",
|
"cliui": "^8.0.1",
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.1",
|
||||||
@ -15227,14 +15249,13 @@
|
|||||||
"require-directory": "^2.1.1",
|
"require-directory": "^2.1.1",
|
||||||
"string-width": "^4.2.3",
|
"string-width": "^4.2.3",
|
||||||
"y18n": "^5.0.5",
|
"y18n": "^5.0.5",
|
||||||
"yargs-parser": "^21.0.0"
|
"yargs-parser": "^21.1.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yargs-parser": {
|
"yargs-parser": {
|
||||||
"version": "21.1.1",
|
"version": "21.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"wireit": {
|
"wireit": {
|
||||||
"build": {
|
"build": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
"./packages/browsers:build",
|
||||||
"./packages/ng-schematics:build",
|
"./packages/ng-schematics:build",
|
||||||
"./packages/puppeteer-core:build",
|
"./packages/puppeteer-core:build",
|
||||||
"./packages/puppeteer:build",
|
"./packages/puppeteer:build",
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
"clean": "tsc --build --clean && rimraf lib",
|
"clean": "tsc --build --clean && rimraf lib",
|
||||||
"test": "wireit"
|
"test": "wireit"
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"@puppeteer/browsers": "lib/cjs/browsers.js"
|
||||||
|
},
|
||||||
"wireit": {
|
"wireit": {
|
||||||
"build": {
|
"build": {
|
||||||
"command": "tsc -b",
|
"command": "tsc -b",
|
||||||
@ -63,12 +66,15 @@
|
|||||||
"debug": "4.3.4",
|
"debug": "4.3.4",
|
||||||
"extract-zip": "2.0.1",
|
"extract-zip": "2.0.1",
|
||||||
"https-proxy-agent": "5.0.1",
|
"https-proxy-agent": "5.0.1",
|
||||||
|
"progress": "2.0.3",
|
||||||
"proxy-from-env": "1.1.0",
|
"proxy-from-env": "1.1.0",
|
||||||
"tar-fs": "2.1.1",
|
"tar-fs": "2.1.1",
|
||||||
"unbzip2-stream": "1.4.3"
|
"unbzip2-stream": "1.4.3",
|
||||||
|
"yargs": "17.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^14.15.0"
|
"@types/node": "^14.15.0",
|
||||||
|
"@types/yargs": "17.0.22"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": ">= 4.7.4"
|
"typescript": ">= 4.7.4"
|
||||||
|
107
packages/browsers/src/CLI.ts
Normal file
107
packages/browsers/src/CLI.ts
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import yargs from 'yargs';
|
||||||
|
import ProgressBar from 'progress';
|
||||||
|
import {hideBin} from 'yargs/helpers';
|
||||||
|
import {Browser, BrowserPlatform} from './browsers/types.js';
|
||||||
|
import {fetch} from './fetch.js';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
type Arguments = {
|
||||||
|
browser: {
|
||||||
|
name: Browser;
|
||||||
|
revision: string;
|
||||||
|
};
|
||||||
|
path?: string;
|
||||||
|
platform?: BrowserPlatform;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class CLI {
|
||||||
|
#cachePath;
|
||||||
|
|
||||||
|
constructor(cachePath = process.cwd()) {
|
||||||
|
this.#cachePath = cachePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(argv: string[]): Promise<void> {
|
||||||
|
await yargs(hideBin(argv))
|
||||||
|
.command(
|
||||||
|
'$0 install <browser>',
|
||||||
|
'run files',
|
||||||
|
yargs => {
|
||||||
|
yargs.positional('browser', {
|
||||||
|
description: 'The browser version',
|
||||||
|
type: 'string',
|
||||||
|
coerce: (opt): Arguments['browser'] => {
|
||||||
|
return {
|
||||||
|
name: this.#parseBrowser(opt),
|
||||||
|
revision: this.#parseRevision(opt),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async argv => {
|
||||||
|
const args = argv as unknown as Arguments;
|
||||||
|
await fetch({
|
||||||
|
browser: args.browser.name,
|
||||||
|
revision: args.browser.revision,
|
||||||
|
platform: args.platform,
|
||||||
|
outputDir: path.join(
|
||||||
|
args.path ?? this.#cachePath,
|
||||||
|
args.browser.name
|
||||||
|
),
|
||||||
|
progressCallback: this.#makeProgressBar(
|
||||||
|
args.browser.name,
|
||||||
|
args.browser.revision
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.option('path', {
|
||||||
|
type: 'string',
|
||||||
|
desc: 'Path where the browsers will be downloaded to and installed from',
|
||||||
|
default: process.cwd(),
|
||||||
|
})
|
||||||
|
.option('platform', {
|
||||||
|
type: 'string',
|
||||||
|
desc: 'Platform that the binary needs to be compatible with.',
|
||||||
|
choices: Object.values(BrowserPlatform),
|
||||||
|
defaultDescription: 'Auto-detected by default.',
|
||||||
|
})
|
||||||
|
.parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
#parseBrowser(version: string): Browser {
|
||||||
|
return version.split('@').shift() as Browser;
|
||||||
|
}
|
||||||
|
|
||||||
|
#parseRevision(version: string): string {
|
||||||
|
return version.split('@').pop() ?? 'latest';
|
||||||
|
}
|
||||||
|
|
||||||
|
#toMegabytes(bytes: number) {
|
||||||
|
const mb = bytes / 1024 / 1024;
|
||||||
|
return `${Math.round(mb * 10) / 10} Mb`;
|
||||||
|
}
|
||||||
|
|
||||||
|
#makeProgressBar(browser: Browser, revision: string) {
|
||||||
|
let progressBar: ProgressBar | null = null;
|
||||||
|
let lastDownloadedBytes = 0;
|
||||||
|
return (downloadedBytes: number, totalBytes: number) => {
|
||||||
|
if (!progressBar) {
|
||||||
|
progressBar = new ProgressBar(
|
||||||
|
`Downloading ${browser} r${revision} - ${this.#toMegabytes(
|
||||||
|
totalBytes
|
||||||
|
)} [:bar] :percent :etas `,
|
||||||
|
{
|
||||||
|
complete: '=',
|
||||||
|
incomplete: ' ',
|
||||||
|
width: 20,
|
||||||
|
total: totalBytes,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const delta = downloadedBytes - lastDownloadedBytes;
|
||||||
|
lastDownloadedBytes = downloadedBytes;
|
||||||
|
progressBar.tick(delta);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
5
packages/browsers/src/browsers.ts
Normal file
5
packages/browsers/src/browsers.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import {CLI} from './CLI.js';
|
||||||
|
|
||||||
|
new CLI().run(process.argv);
|
67
packages/browsers/test/src/cli.spec.ts
Normal file
67
packages/browsers/test/src/cli.spec.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {CLI} from '../../lib/cjs/CLI.js';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import os from 'os';
|
||||||
|
import assert from 'assert';
|
||||||
|
|
||||||
|
describe('CLI', function () {
|
||||||
|
this.timeout(60000);
|
||||||
|
|
||||||
|
let tmpDir = '/tmp/puppeteer-browsers-test';
|
||||||
|
const testChromeRevision = '1083080';
|
||||||
|
const testFirefoxRevision = '111.0a1';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'puppeteer-browsers-test'));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fs.rmSync(tmpDir, {recursive: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should download Chromium binaries', async () => {
|
||||||
|
await new CLI(tmpDir).run([
|
||||||
|
'npx',
|
||||||
|
'@puppeteer/browsers',
|
||||||
|
'install',
|
||||||
|
`chrome@${testChromeRevision}`,
|
||||||
|
`--path=${tmpDir}`,
|
||||||
|
'--platform=linux',
|
||||||
|
]);
|
||||||
|
assert.ok(
|
||||||
|
fs.existsSync(path.join(tmpDir, 'chrome', `linux-${testChromeRevision}`))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should download Firefox binaries', async () => {
|
||||||
|
await new CLI(tmpDir).run([
|
||||||
|
'npx',
|
||||||
|
'@puppeteer/browsers',
|
||||||
|
'install',
|
||||||
|
`firefox@${testFirefoxRevision}`,
|
||||||
|
`--path=${tmpDir}`,
|
||||||
|
'--platform=linux',
|
||||||
|
]);
|
||||||
|
assert.ok(
|
||||||
|
fs.existsSync(
|
||||||
|
path.join(tmpDir, 'firefox', `linux-${testFirefoxRevision}`)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user