UNPKG

@sitespeed.io/geckodriver

Version:

Install and launch Geckodriver for Mac, Linux or Windows.

154 lines (144 loc) 4.96 kB
'use strict'; 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();