UNPKG

atlas-app-services-cli

Version:

The Atlas App Services Command Line Interface

160 lines (132 loc) 4.39 kB
"use strict"; import axios from 'axios'; import decompress from '@xhmikosr/decompress'; import fs from 'fs'; import path from 'path'; const KILOBYTE = 1024; const MAX_BYTES_READ = 800000; const manifestURL = 'https://downloads.mongodb.com/app-services-cli/versions/cloud-prod/MANIFEST'; function fetchManifest() { return axios(manifestURL) .then(function (res) { return res.data; }); } function getDownloadURL(manifest) { const pastReleases = manifest.past_releases || []; let tag = ''; switch(process.platform) { case 'linux': if (process.arch !== 'x64' && process.arch !== 'arm64') { throw new Error('Only Linux 64 bits supported.'); } if (process.arch === 'x64') { tag = 'linux-amd64'; } else if (process.arch === 'arm64') { tag = 'linux-arm64'; } break; case 'darwin': case 'freebsd': if (process.arch !== 'x64' && process.arch !== 'arm64') { throw new Error('Only Mac 64 bits supported.'); } if (process.arch === 'x64') { tag = 'darwin-amd64'; } else if (process.arch === 'arm64') { tag = 'darwin-arm64'; } break; case 'win32': if (process.arch !== 'x64') { throw new Error('Only Windows 64 bits supported.'); } tag = 'windows-amd64'; break; default: throw new Error(`Unexpected platform or architecture: ${process.platform} ${process.arch}`); } const packageMetadata = JSON.parse(fs.readFileSync('./package.json')) if (manifest.version !== packageMetadata.version) { const matchingPastRelease = pastReleases.find((pastRelease) => pastRelease.version === packageMetadata.version); if (matchingPastRelease) return matchingPastRelease.info[tag].url; } return manifest.info[tag].url; } function requestArchive(downloadURL) { console.log(`downloading appservices cli archive from "${downloadURL}"`); const archiveName = downloadURL.split("/").pop() return new Promise(function (resolve, reject) { let count = 0; let notifiedCount = 0; const filePath = path.join(process.cwd(), archiveName); const outFile = fs.openSync(filePath, 'w'); axios.get(downloadURL, { responseType: 'stream' }) .then(function (res) { return res.data; }) .then(function (stream) { stream.on('error', function (err) { reject(new Error(`Error with http(s) request: ${err}`)); }); stream.on('data', function (data) { fs.writeSync(outFile, data, 0, data.length, null); count += data.length; if (count - notifiedCount > MAX_BYTES_READ) { process.stdout.write(`Received ${Math.floor(count / KILOBYTE)} K...\r`); notifiedCount = count; } }); stream.on('end', function () { console.log(`Received ${Math.floor(count / KILOBYTE)} K total.`); fs.closeSync(outFile); fixFilePermissions(filePath); resolve(archiveName); }); }) .catch(reject); }); } const unzip = (path) => { return decompress(path, ".", { map: file => { // remove wrapping directory to write contents of zip in cwd file.path = file.path.split('/').slice(1).join('/') return file } }) } const untar = (path) => { return decompress(path, ".", { map: file => { // remove wrapping directory to write contents of tar in cwd file.path = file.path.split('/').slice(1).join('/') return file } }) } function decompressArchive(filepath) { if (filepath.slice(-3) === "zip") { return unzip(filepath) } if (filepath.slice(-6) === "tar.gz") { return untar(filepath) } throw new Error(`could not decompress archive: unexpected archive type for file: ${filepath}`) } function fixFilePermissions(filePath) { // Check that the binary is user-executable and fix it if it isn't if (process.platform !== 'win32') { const stat = fs.statSync(filePath); // 64 == 0100 (no octal literal in strict mode) // eslint-disable-next-line no-bitwise if (!(stat.mode & 64)) { fs.chmodSync(filePath, '755'); } } } fetchManifest() .then(getDownloadURL) .then(requestArchive) .then(decompressArchive) .catch(function (err) { console.error('failed to download Atlas App Services CLI:', err); process.exit(1); });