refactor: move ChromiumDownloader under lib/ (#1554)
This patch: - renames ChromiumDownloader into just Downloader (this is in preparation for different products download) - moves Downloader from utils/ to lib/. This unifies all of the production-critical code in the lib/. Drive-by: make Downloader a regular class.
This commit is contained in:
parent
11d94525c8
commit
9a5086847c
20
install.js
20
install.js
@ -23,12 +23,14 @@ if (process.env.NPM_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD || process.env.npm_c
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Downloader = require('./utils/ChromiumDownloader');
|
const Downloader = require('./lib/Downloader');
|
||||||
const platform = Downloader.currentPlatform();
|
const downloader = Downloader.createDefault();
|
||||||
const revision = require('./package').puppeteer.chromium_revision;
|
|
||||||
|
const platform = downloader.currentPlatform();
|
||||||
|
const revision = Downloader.defaultRevision();
|
||||||
const ProgressBar = require('progress');
|
const ProgressBar = require('progress');
|
||||||
|
|
||||||
const revisionInfo = Downloader.revisionInfo(platform, revision);
|
const revisionInfo = downloader.revisionInfo(platform, revision);
|
||||||
// Do nothing if the revision is already downloaded.
|
// Do nothing if the revision is already downloaded.
|
||||||
if (revisionInfo.downloaded)
|
if (revisionInfo.downloaded)
|
||||||
return;
|
return;
|
||||||
@ -45,9 +47,11 @@ if (NPM_HTTP_PROXY)
|
|||||||
if (NPM_NO_PROXY)
|
if (NPM_NO_PROXY)
|
||||||
process.env.NO_PROXY = NPM_NO_PROXY;
|
process.env.NO_PROXY = NPM_NO_PROXY;
|
||||||
|
|
||||||
const allRevisions = Downloader.downloadedRevisions();
|
const allRevisions = downloader.downloadedRevisions();
|
||||||
const DOWNLOAD_HOST = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host;
|
const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host;
|
||||||
Downloader.downloadRevision(platform, revision, DOWNLOAD_HOST, onProgress)
|
if (downloadHost)
|
||||||
|
downloader.setDownloadHost(downloadHost);
|
||||||
|
downloader.downloadRevision(platform, revision, onProgress)
|
||||||
.then(onSuccess)
|
.then(onSuccess)
|
||||||
.catch(onError);
|
.catch(onError);
|
||||||
|
|
||||||
@ -57,7 +61,7 @@ Downloader.downloadRevision(platform, revision, DOWNLOAD_HOST, onProgress)
|
|||||||
function onSuccess() {
|
function onSuccess() {
|
||||||
console.log('Chromium downloaded to ' + revisionInfo.folderPath);
|
console.log('Chromium downloaded to ' + revisionInfo.folderPath);
|
||||||
// Remove previous chromium revisions.
|
// Remove previous chromium revisions.
|
||||||
const cleanupOldVersions = allRevisions.map(({platform, revision}) => Downloader.removeRevision(platform, revision));
|
const cleanupOldVersions = allRevisions.map(({platform, revision}) => downloader.removeRevision(platform, revision));
|
||||||
return Promise.all(cleanupOldVersions);
|
return Promise.all(cleanupOldVersions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +26,7 @@ const ProxyAgent = require('https-proxy-agent');
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const getProxyForUrl = require('proxy-from-env').getProxyForUrl;
|
const getProxyForUrl = require('proxy-from-env').getProxyForUrl;
|
||||||
|
|
||||||
const DOWNLOADS_FOLDER = path.join(__dirname, '..', '.local-chromium');
|
|
||||||
const DEFAULT_DOWNLOAD_HOST = 'https://storage.googleapis.com';
|
const DEFAULT_DOWNLOAD_HOST = 'https://storage.googleapis.com';
|
||||||
|
|
||||||
const downloadURLs = {
|
const downloadURLs = {
|
||||||
linux: '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip',
|
linux: '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip',
|
||||||
mac: '%s/chromium-browser-snapshots/Mac/%d/chrome-mac.zip',
|
mac: '%s/chromium-browser-snapshots/Mac/%d/chrome-mac.zip',
|
||||||
@ -36,18 +34,50 @@ const downloadURLs = {
|
|||||||
win64: '%s/chromium-browser-snapshots/Win_x64/%d/chrome-win32.zip',
|
win64: '%s/chromium-browser-snapshots/Win_x64/%d/chrome-win32.zip',
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
const PROJECT_ROOT = path.join(__dirname, '..');
|
||||||
|
|
||||||
|
class Downloader {
|
||||||
/**
|
/**
|
||||||
* @return {!Array<string>}
|
* @param {string} downloadsFolder
|
||||||
*/
|
*/
|
||||||
supportedPlatforms: function() {
|
constructor(downloadsFolder) {
|
||||||
return Object.keys(downloadURLs);
|
this._downloadsFolder = downloadsFolder;
|
||||||
},
|
this._downloadHost = DEFAULT_DOWNLOAD_HOST;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
currentPlatform: function() {
|
static defaultRevision() {
|
||||||
|
return require(path.join(PROJECT_ROOT, 'package.json')).puppeteer.chromium_revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {!Downloader}
|
||||||
|
*/
|
||||||
|
static createDefault() {
|
||||||
|
const downloadsFolder = path.join(PROJECT_ROOT, '.local-chromium');
|
||||||
|
return new Downloader(downloadsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} downloadHost
|
||||||
|
*/
|
||||||
|
setDownloadHost(downloadHost) {
|
||||||
|
this._downloadHost = downloadHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {!Array<string>}
|
||||||
|
*/
|
||||||
|
supportedPlatforms() {
|
||||||
|
return Object.keys(downloadURLs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
currentPlatform() {
|
||||||
const platform = os.platform();
|
const platform = os.platform();
|
||||||
if (platform === 'darwin')
|
if (platform === 'darwin')
|
||||||
return 'mac';
|
return 'mac';
|
||||||
@ -56,17 +86,17 @@ module.exports = {
|
|||||||
if (platform === 'win32')
|
if (platform === 'win32')
|
||||||
return os.arch() === 'x64' ? 'win64' : 'win32';
|
return os.arch() === 'x64' ? 'win64' : 'win32';
|
||||||
return '';
|
return '';
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} platform
|
* @param {string} platform
|
||||||
* @param {string} revision
|
* @param {string} revision
|
||||||
* @return {!Promise<boolean>}
|
* @return {!Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
canDownloadRevision: function(platform, revision) {
|
canDownloadRevision(platform, revision) {
|
||||||
console.assert(downloadURLs[platform], 'Unknown platform: ' + platform);
|
console.assert(downloadURLs[platform], 'Unknown platform: ' + platform);
|
||||||
|
|
||||||
const url = util.format(downloadURLs[platform], DEFAULT_DOWNLOAD_HOST, revision);
|
const url = util.format(downloadURLs[platform], this._downloadHost, revision);
|
||||||
|
|
||||||
let resolve;
|
let resolve;
|
||||||
const promise = new Promise(x => resolve = x);
|
const promise = new Promise(x => resolve = x);
|
||||||
@ -78,25 +108,24 @@ module.exports = {
|
|||||||
resolve(false);
|
resolve(false);
|
||||||
});
|
});
|
||||||
return promise;
|
return promise;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} platform
|
* @param {string} platform
|
||||||
* @param {string} revision
|
* @param {string} revision
|
||||||
* @param {string} [downloadHost=DEFAULT_DOWNLOAD_HOST]
|
|
||||||
* @param {?function(number, number)} progressCallback
|
* @param {?function(number, number)} progressCallback
|
||||||
* @return {!Promise}
|
* @return {!Promise}
|
||||||
*/
|
*/
|
||||||
downloadRevision: function(platform, revision, downloadHost = DEFAULT_DOWNLOAD_HOST, progressCallback) {
|
downloadRevision(platform, revision, progressCallback) {
|
||||||
let url = downloadURLs[platform];
|
let url = downloadURLs[platform];
|
||||||
console.assert(url, `Unsupported platform: ${platform}`);
|
console.assert(url, `Unsupported platform: ${platform}`);
|
||||||
url = util.format(url, downloadHost, revision);
|
url = util.format(url, this._downloadHost, revision);
|
||||||
const zipPath = path.join(DOWNLOADS_FOLDER, `download-${platform}-${revision}.zip`);
|
const zipPath = path.join(this._downloadsFolder, `download-${platform}-${revision}.zip`);
|
||||||
const folderPath = getFolderPath(platform, revision);
|
const folderPath = this._getFolderPath(platform, revision);
|
||||||
if (fs.existsSync(folderPath))
|
if (fs.existsSync(folderPath))
|
||||||
return;
|
return;
|
||||||
if (!fs.existsSync(DOWNLOADS_FOLDER))
|
if (!fs.existsSync(this._downloadsFolder))
|
||||||
fs.mkdirSync(DOWNLOADS_FOLDER);
|
fs.mkdirSync(this._downloadsFolder);
|
||||||
return downloadFile(url, zipPath, progressCallback)
|
return downloadFile(url, zipPath, progressCallback)
|
||||||
.then(() => extractZip(zipPath, folderPath))
|
.then(() => extractZip(zipPath, folderPath))
|
||||||
.catch(err => err)
|
.catch(err => err)
|
||||||
@ -106,38 +135,38 @@ module.exports = {
|
|||||||
if (err)
|
if (err)
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {!Array<!{platform:string, revision: string}>}
|
* @return {!Array<!{platform:string, revision: string}>}
|
||||||
*/
|
*/
|
||||||
downloadedRevisions: function() {
|
downloadedRevisions() {
|
||||||
if (!fs.existsSync(DOWNLOADS_FOLDER))
|
if (!fs.existsSync(this._downloadsFolder))
|
||||||
return [];
|
return [];
|
||||||
const fileNames = fs.readdirSync(DOWNLOADS_FOLDER);
|
const fileNames = fs.readdirSync(this._downloadsFolder);
|
||||||
return fileNames.map(fileName => parseFolderPath(fileName)).filter(revision => !!revision);
|
return fileNames.map(fileName => parseFolderPath(fileName)).filter(revision => !!revision);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} platform
|
* @param {string} platform
|
||||||
* @param {string} revision
|
* @param {string} revision
|
||||||
* @return {!Promise}
|
* @return {!Promise}
|
||||||
*/
|
*/
|
||||||
removeRevision: function(platform, revision) {
|
removeRevision(platform, revision) {
|
||||||
console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`);
|
console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`);
|
||||||
const folderPath = getFolderPath(platform, revision);
|
const folderPath = this._getFolderPath(platform, revision);
|
||||||
console.assert(fs.existsSync(folderPath));
|
console.assert(fs.existsSync(folderPath));
|
||||||
return new Promise(fulfill => removeRecursive(folderPath, fulfill));
|
return new Promise(fulfill => removeRecursive(folderPath, fulfill));
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} platform
|
* @param {string} platform
|
||||||
* @param {string} revision
|
* @param {string} revision
|
||||||
* @return {!{folderPath: string, executablePath: string, downloaded: boolean}}
|
* @return {!{revision: string, folderPath: string, executablePath: string, downloaded: boolean}}
|
||||||
*/
|
*/
|
||||||
revisionInfo: function(platform, revision) {
|
revisionInfo(platform, revision) {
|
||||||
console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`);
|
console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`);
|
||||||
const folderPath = getFolderPath(platform, revision);
|
const folderPath = this._getFolderPath(platform, revision);
|
||||||
let executablePath = '';
|
let executablePath = '';
|
||||||
if (platform === 'mac')
|
if (platform === 'mac')
|
||||||
executablePath = path.join(folderPath, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium');
|
executablePath = path.join(folderPath, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium');
|
||||||
@ -148,22 +177,25 @@ module.exports = {
|
|||||||
else
|
else
|
||||||
throw 'Unsupported platform: ' + platform;
|
throw 'Unsupported platform: ' + platform;
|
||||||
return {
|
return {
|
||||||
|
revision,
|
||||||
executablePath,
|
executablePath,
|
||||||
folderPath,
|
folderPath,
|
||||||
downloaded: fs.existsSync(folderPath)
|
downloaded: fs.existsSync(folderPath)
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} platform
|
* @param {string} platform
|
||||||
* @param {string} revision
|
* @param {string} revision
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
function getFolderPath(platform, revision) {
|
_getFolderPath(platform, revision) {
|
||||||
return path.join(DOWNLOADS_FOLDER, platform + '-' + revision);
|
return path.join(this._downloadsFolder, platform + '-' + revision);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = Downloader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} folderPath
|
* @param {string} folderPath
|
||||||
* @return {?{platform: string, revision: string}}
|
* @return {?{platform: string, revision: string}}
|
@ -17,14 +17,13 @@ const os = require('os');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const removeFolder = require('rimraf');
|
const removeFolder = require('rimraf');
|
||||||
const childProcess = require('child_process');
|
const childProcess = require('child_process');
|
||||||
const Downloader = require('../utils/ChromiumDownloader');
|
const Downloader = require('./Downloader');
|
||||||
const {Connection} = require('./Connection');
|
const {Connection} = require('./Connection');
|
||||||
const {Browser} = require('./Browser');
|
const {Browser} = require('./Browser');
|
||||||
const readline = require('readline');
|
const readline = require('readline');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const {helper} = require('./helper');
|
const {helper} = require('./helper');
|
||||||
// @ts-ignore
|
const ChromiumRevision = Downloader.defaultRevision();
|
||||||
const ChromiumRevision = require('../package.json').puppeteer.chromium_revision;
|
|
||||||
|
|
||||||
const mkdtempAsync = helper.promisify(fs.mkdtemp);
|
const mkdtempAsync = helper.promisify(fs.mkdtemp);
|
||||||
const removeFolderAsync = helper.promisify(removeFolder);
|
const removeFolderAsync = helper.promisify(removeFolder);
|
||||||
@ -88,7 +87,8 @@ class Launcher {
|
|||||||
}
|
}
|
||||||
let chromeExecutable = options.executablePath;
|
let chromeExecutable = options.executablePath;
|
||||||
if (typeof chromeExecutable !== 'string') {
|
if (typeof chromeExecutable !== 'string') {
|
||||||
const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), ChromiumRevision);
|
const downloader = Downloader.createDefault();
|
||||||
|
const revisionInfo = downloader.revisionInfo(downloader.currentPlatform(), ChromiumRevision);
|
||||||
console.assert(revisionInfo.downloaded, `Chromium revision is not downloaded. Run "npm install"`);
|
console.assert(revisionInfo.downloaded, `Chromium revision is not downloaded. Run "npm install"`);
|
||||||
chromeExecutable = revisionInfo.executablePath;
|
chromeExecutable = revisionInfo.executablePath;
|
||||||
}
|
}
|
||||||
@ -176,7 +176,8 @@ class Launcher {
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
static executablePath() {
|
static executablePath() {
|
||||||
const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), ChromiumRevision);
|
const downloader = Downloader.createDefault();
|
||||||
|
const revisionInfo = downloader.revisionInfo(downloader.currentPlatform(), ChromiumRevision);
|
||||||
return revisionInfo.executablePath;
|
return revisionInfo.executablePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +51,7 @@ const defaultBrowserOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Make sure the `npm install` was run after the chromium roll.
|
// Make sure the `npm install` was run after the chromium roll.
|
||||||
{
|
console.assert(fs.existsSync(puppeteer.executablePath()), `Chromium is not Downloaded. Run 'npm install' and try to re-run tests`);
|
||||||
const Downloader = require('../utils/ChromiumDownloader');
|
|
||||||
const chromiumRevision = require('../package.json').puppeteer.chromium_revision;
|
|
||||||
const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), chromiumRevision);
|
|
||||||
console.assert(revisionInfo.downloaded, `Chromium r${chromiumRevision} is not downloaded. Run 'npm install' and try to re-run tests.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const timeout = process.env.DEBUG_TEST || slowMo ? 0 : 10 * 1000;
|
const timeout = process.env.DEBUG_TEST || slowMo ? 0 : 10 * 1000;
|
||||||
|
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Downloader = require('./ChromiumDownloader');
|
const Downloader = require('../lib/Downloader');
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
const OMAHA_PROXY = 'https://omahaproxy.appspot.com/all.json';
|
const OMAHA_PROXY = 'https://omahaproxy.appspot.com/all.json';
|
||||||
|
|
||||||
|
const downloader = Downloader.createDefault();
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
reset: '\x1b[0m',
|
reset: '\x1b[0m',
|
||||||
red: '\x1b[31m',
|
red: '\x1b[31m',
|
||||||
@ -71,7 +73,7 @@ async function checkOmahaProxyAvailability() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const table = new Table([27, 7, 7, 7, 7]);
|
const table = new Table([27, 7, 7, 7, 7]);
|
||||||
table.drawRow([''].concat(Downloader.supportedPlatforms()));
|
table.drawRow([''].concat(downloader.supportedPlatforms()));
|
||||||
for (const platform of platforms) {
|
for (const platform of platforms) {
|
||||||
// Trust only to the main platforms.
|
// Trust only to the main platforms.
|
||||||
if (platform.os !== 'mac' && platform.os !== 'win' && platform.os !== 'win64' && platform.os !== 'linux')
|
if (platform.os !== 'mac' && platform.os !== 'win' && platform.os !== 'win64' && platform.os !== 'linux')
|
||||||
@ -93,7 +95,7 @@ async function checkOmahaProxyAvailability() {
|
|||||||
*/
|
*/
|
||||||
async function checkRangeAvailability(fromRevision, toRevision) {
|
async function checkRangeAvailability(fromRevision, toRevision) {
|
||||||
const table = new Table([10, 7, 7, 7, 7]);
|
const table = new Table([10, 7, 7, 7, 7]);
|
||||||
table.drawRow([''].concat(Downloader.supportedPlatforms()));
|
table.drawRow([''].concat(downloader.supportedPlatforms()));
|
||||||
const inc = fromRevision < toRevision ? 1 : -1;
|
const inc = fromRevision < toRevision ? 1 : -1;
|
||||||
for (let revision = fromRevision; revision !== toRevision; revision += inc)
|
for (let revision = fromRevision; revision !== toRevision; revision += inc)
|
||||||
await checkAndDrawRevisionAvailability(table, '', revision);
|
await checkAndDrawRevisionAvailability(table, '', revision);
|
||||||
@ -106,8 +108,8 @@ async function checkRangeAvailability(fromRevision, toRevision) {
|
|||||||
*/
|
*/
|
||||||
async function checkAndDrawRevisionAvailability(table, name, revision) {
|
async function checkAndDrawRevisionAvailability(table, name, revision) {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (const platform of Downloader.supportedPlatforms())
|
for (const platform of downloader.supportedPlatforms())
|
||||||
promises.push(Downloader.canDownloadRevision(platform, revision));
|
promises.push(downloader.canDownloadRevision(platform, revision));
|
||||||
const availability = await Promise.all(promises);
|
const availability = await Promise.all(promises);
|
||||||
const allAvailable = availability.every(e => !!e);
|
const allAvailable = availability.every(e => !!e);
|
||||||
const values = [name + ' ' + (allAvailable ? colors.green + revision + colors.reset : revision)];
|
const values = [name + ' ' + (allAvailable ? colors.green + revision + colors.reset : revision)];
|
||||||
|
@ -21,6 +21,7 @@ const Message = require('../Message');
|
|||||||
|
|
||||||
const EXCLUDE_CLASSES = new Set([
|
const EXCLUDE_CLASSES = new Set([
|
||||||
'Connection',
|
'Connection',
|
||||||
|
'Downloader',
|
||||||
'EmulationManager',
|
'EmulationManager',
|
||||||
'FrameManager',
|
'FrameManager',
|
||||||
'Helper',
|
'Helper',
|
||||||
|
Loading…
Reference in New Issue
Block a user