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",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
@ -8426,10 +8425,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.6.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
|
||||
"integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
|
||||
"dev": true,
|
||||
"version": "17.6.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
|
||||
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
@ -8437,7 +8435,7 @@
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.0.0"
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@ -8500,7 +8498,6 @@
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
@ -8571,12 +8568,18 @@
|
||||
"debug": "4.3.4",
|
||||
"extract-zip": "2.0.1",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
"proxy-from-env": "1.1.0",
|
||||
"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": {
|
||||
"@types/node": "^14.15.0"
|
||||
"@types/node": "^14.15.0",
|
||||
"@types/yargs": "17.0.22"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.1.0"
|
||||
@ -8596,6 +8599,15 @@
|
||||
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
|
||||
"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": {
|
||||
"name": "@puppeteer/ng-schematics",
|
||||
"version": "0.1.0",
|
||||
@ -9965,12 +9977,15 @@
|
||||
"version": "file:packages/browsers",
|
||||
"requires": {
|
||||
"@types/node": "^14.15.0",
|
||||
"@types/yargs": "17.0.22",
|
||||
"debug": "4.3.4",
|
||||
"extract-zip": "2.0.1",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
"proxy-from-env": "1.1.0",
|
||||
"tar-fs": "2.1.1",
|
||||
"unbzip2-stream": "1.4.3"
|
||||
"unbzip2-stream": "1.4.3",
|
||||
"yargs": "17.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
@ -9978,6 +9993,15 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.36.tgz",
|
||||
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
|
||||
"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",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
@ -15216,10 +15239,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "17.6.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
|
||||
"integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
|
||||
"dev": true,
|
||||
"version": "17.6.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
|
||||
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
|
||||
"requires": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
@ -15227,14 +15249,13 @@
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.0.0"
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -40,6 +40,7 @@
|
||||
"wireit": {
|
||||
"build": {
|
||||
"dependencies": [
|
||||
"./packages/browsers:build",
|
||||
"./packages/ng-schematics:build",
|
||||
"./packages/puppeteer-core:build",
|
||||
"./packages/puppeteer:build",
|
||||
|
@ -8,6 +8,9 @@
|
||||
"clean": "tsc --build --clean && rimraf lib",
|
||||
"test": "wireit"
|
||||
},
|
||||
"bin": {
|
||||
"@puppeteer/browsers": "lib/cjs/browsers.js"
|
||||
},
|
||||
"wireit": {
|
||||
"build": {
|
||||
"command": "tsc -b",
|
||||
@ -63,12 +66,15 @@
|
||||
"debug": "4.3.4",
|
||||
"extract-zip": "2.0.1",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
"proxy-from-env": "1.1.0",
|
||||
"tar-fs": "2.1.1",
|
||||
"unbzip2-stream": "1.4.3"
|
||||
"unbzip2-stream": "1.4.3",
|
||||
"yargs": "17.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.15.0"
|
||||
"@types/node": "^14.15.0",
|
||||
"@types/yargs": "17.0.22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"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