const fs = require('fs'); const path = require('path'); const shell = require('shelljs'); const download = require('download'); const decompress = require('decompress'); const unzip = require('decompress-unzip'); const untargz = require('decompress-targz'); const untarbz2 = require('decompress-tarbz2'); process.on('unhandledRejection', (reason, _) => { shell.echo(String(reason)); shell.exit(1); throw reason; }); process.on('uncaughtException', (error) => { shell.echo(String(error)); shell.exit(1); throw error; }); /** * @param url {string} Download URL * @param targetFile {string} Path to the file to copy from the decompressed archive * @param filePrefix {string} Prefix of the file name found in the archive * @param force {boolean} Whether to download even if the target file exists. `false` by default. */ exports.downloadUnzipFile = async ( url, targetFile, filePrefix, force = false ) => { if (fs.existsSync(targetFile) && !force) { shell.echo(`Skipping download because file already exists: ${targetFile}`); return; } if (!fs.existsSync(path.dirname(targetFile))) { if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) { shell.echo('Could not create new directory.'); shell.exit(1); } } const downloads = path.join(__dirname, '..', 'downloads'); if (shell.rm('-rf', targetFile, downloads).code !== 0) { shell.exit(1); } shell.echo(`>>> Downloading from '${url}'...`); const data = await download(url); shell.echo(`<<< Download succeeded.`); shell.echo('>>> Decompressing...'); const files = await decompress(data, downloads, { plugins: [unzip(), untargz(), untarbz2()], }); if (files.length === 0) { shell.echo('Error ocurred while decompressing the archive.'); shell.exit(1); } const fileIndex = files.findIndex((f) => f.path.startsWith(filePrefix)); if (fileIndex === -1) { shell.echo( `The downloaded artifact does not contain any file with prefix ${filePrefix}.` ); shell.exit(1); } shell.echo('<<< Decompressing succeeded.'); if ( shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile) .code !== 0 ) { shell.echo(`Could not move file to target path: ${targetFile}`); shell.exit(1); } if (!fs.existsSync(targetFile)) { shell.echo(`Could not find file: ${targetFile}`); shell.exit(1); } shell.echo(`Done: ${targetFile}`); }; /** * @param url {string} Download URL * @param targetDir {string} Directory into which to decompress the archive * @param targetFile {string} Path to the main file expected after decompressing * @param force {boolean} Whether to download even if the target file exists * @param decompressOptions {import('decompress').DecompressOptions} */ exports.downloadUnzipAll = async ( url, targetDir, targetFile, force, decompressOptions = undefined ) => { if (fs.existsSync(targetFile) && !force) { shell.echo(`Skipping download because file already exists: ${targetFile}`); return; } if (!fs.existsSync(targetDir)) { if (shell.mkdir('-p', targetDir).code !== 0) { shell.echo('Could not create new directory.'); shell.exit(1); } } shell.echo(`>>> Downloading from '${url}'...`); const data = await download(url); shell.echo(`<<< Download succeeded.`); shell.echo('>>> Decompressing...'); let options = { plugins: [unzip(), untargz(), untarbz2()], }; if (decompressOptions) { options = Object.assign(options, decompressOptions); } const files = await decompress(data, targetDir, options); if (files.length === 0) { shell.echo('Error ocurred while decompressing the archive.'); shell.exit(1); } shell.echo('<<< Decompressing succeeded.'); if (!fs.existsSync(targetFile)) { shell.echo(`Could not find file: ${targetFile}`); shell.exit(1); } shell.echo(`Done: ${targetFile}`); };