@sitespeed.io/geckodriver
Version:
Install and launch Geckodriver for Mac, Linux or Windows.
154 lines (144 loc) • 4.96 kB
JavaScript
;
const StreamZip = require('node-stream-zip');
const os = require('os');
const fs = require('fs');
const path = require('path');
const pkg = require('./package');
const { DownloaderHelper } = require('node-downloader-helper');
const { promisify } = require('util');
const tar = require('tar');
const unlink = promisify(fs.unlink);
const mkdir = promisify(fs.mkdir);
const chmod = promisify(fs.chmod);
// The version of the driver that will be installed
const GECKODRIVER_VERSION = process.env.GECKODRIVER_VERSION
? `v${process.env.GECKODRIVER_VERSION}`
: `v${pkg.geckodriver_version}`;
const isWindows = os.platform() === 'win32';
function byteHelper(value) {
// https://gist.github.com/thomseddon/3511330
const units = ['b', 'kB', 'MB', 'GB', 'TB'],
number = Math.floor(Math.log(value) / Math.log(1024));
return (
(value / Math.pow(1024, Math.floor(number))).toFixed(1) +
' ' +
units[number]
);
}
function getDriverUrl() {
let urlBase;
if (process.env.GECKODRIVER_BASE_URL) {
urlBase = process.env.GECKODRIVER_BASE_URL;
} else if (os.platform() === 'linux' && os.arch() === 'arm') {
urlBase = `https://github.com/sitespeedio/geckodriver/releases/download/v0.29.0/`;
} else {
urlBase = `https://github.com/mozilla/geckodriver/releases/download/${GECKODRIVER_VERSION}/`;
}
switch (os.platform()) {
case 'darwin':
// Starting from Geckodriver v0.29.1, there is a separate build for arm64
// architecture. Let's install it if we are on arm64 as well.
// eslint-disable-next-line no-case-declarations
const arch = os.arch() === 'arm64' ? '-aarch64' : '';
return `${urlBase}geckodriver-${GECKODRIVER_VERSION}-macos${arch}.tar.gz`;
case 'linux': {
if (os.arch() === 'arm') {
// Don't want to spend hours to build a new one, so for now serve 0.29.0
// or unreleased 0.30.0
return `${urlBase}geckodriver-0.30.0-linux-arm.tar.gz`;
} else {
const arch = os.arch() === 'x64' ? '64' : '32';
return `${urlBase}geckodriver-${GECKODRIVER_VERSION}-linux${arch}.tar.gz`;
}
}
case 'win32': {
const arch = os.arch() === 'x64' ? 'win64' : 'win32';
return `${urlBase}geckodriver-${GECKODRIVER_VERSION}-${arch}.zip`;
}
default:
return undefined;
}
}
async function download() {
if (
process.env.npm_config_geckodriver_skip_download ||
process.env.GECKODRIVER_SKIP_DOWNLOAD
) {
console.log('Skip downloading Geckodriver');
} else {
const downloadUrl = getDriverUrl();
if (downloadUrl) {
try {
await mkdir('vendor');
} catch (e) {
try {
await unlink('vendor/geckodriver');
} catch (e) {
// nothing to do here
}
}
const dl = new DownloaderHelper(downloadUrl, 'vendor', {
fileName: 'geckodriver' + (isWindows ? '.zip' : '.tar.gz')
});
dl.on('error', err =>
console.error('Could not download Geckodriver: ' + downloadUrl, err)
)
.on('progress', stats => {
const progress = stats.progress.toFixed(1);
const speed = byteHelper(stats.speed);
const downloaded = byteHelper(stats.downloaded);
const total = byteHelper(stats.total);
console.log(`${speed}/s - ${progress}% [${downloaded}/${total}]`);
})
.on('end', () => {
if (isWindows) {
const zip = new StreamZip({
file: 'vendor/geckodriver.zip',
storeEntries: true
});
zip.on('ready', () => {
zip.extract(null, './vendor', async err => {
console.log(
err
? 'Could not extract and install Geckodriver'
: `Geckodriver ${GECKODRIVER_VERSION} installed in ${path.join(
__dirname,
'vendor'
)}`
);
zip.close();
await unlink('vendor/geckodriver.zip');
await chmod('vendor/geckodriver.exe', '755');
});
});
} else {
tar
.x({
file: 'vendor/geckodriver.tar.gz',
cwd: 'vendor'
})
.then(async () => {
await unlink('vendor/geckodriver.tar.gz');
await chmod('vendor/geckodriver', '755');
console.log(
`Geckodriver ${GECKODRIVER_VERSION} installed in ${path.join(
__dirname,
'vendor'
)}`
);
});
}
});
dl.start();
} else {
console.log(
'Skipping installing Geckodriver on ' +
os.platform() +
' for ' +
os.arch() +
" since there's no official build"
);
}
}
}
download();