diff --git a/README.md b/README.md index ad3c156..c182737 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This is an npm module for using [ripgrep](https://github.com/BurntSushi/ripgrep) - Ripgrep is built in [microsoft/ripgrep-prebuilt](https://github.com/microsoft/ripgrep-prebuilt) and published to releases for each tag in that repo. - In this module's postinstall task, it determines which platform it is being installed on and downloads the correct binary from ripgrep-prebuilt for the platform. - The path to the ripgrep binary is exported as `rgPath`. +- Download Mirror url from environment variable RIPGREP_MIRROR_URL or npm config ripgrep_mirror_url ### Usage example diff --git a/lib/download.js b/lib/download.js index 9036134..ffaa5da 100644 --- a/lib/download.js +++ b/lib/download.js @@ -134,25 +134,31 @@ function getApiUrl(repo, tag) { } /** - * @param {{ force: boolean; token: string; version: string; }} opts - * @param {string} assetName - * @param {string} downloadFolder + * @returns {string | null} */ -async function getAssetFromGithubApi(opts, assetName, downloadFolder) { - const assetDownloadPath = path.join(downloadFolder, assetName); +function getMirrorUrl() { + const mirrorUrlFromEnv = process.env.RIPGREP_MIRROR_URL; + if (mirrorUrlFromEnv) { + console.log('Using ripgrep mirror URL from environment variable RIPGREP_MIRROR_URL: ' + mirrorUrlFromEnv); + return mirrorUrlFromEnv; + } - // We can just use the cached binary - if (!opts.force && await fsExists(assetDownloadPath)) { - console.log('Using cached download: ' + assetDownloadPath); - return assetDownloadPath; + const mirrorUrlFromNpmConfig = process.env.npm_config_ripgrep_mirror_url; + if (mirrorUrlFromNpmConfig) { + console.log('Using ripgrep mirror URL from npm config: ' + mirrorUrlFromNpmConfig); + return mirrorUrlFromNpmConfig; } - const downloadOpts = { - headers: { - 'user-agent': 'vscode-ripgrep' - } - }; + return null; +} +/** + * @param {{ force: boolean; token: string; version: string; }} opts + * @param {string} assetName + * @param {string} assetDownloadPath + * @param {object} downloadOpts + */ +async function downloadFromGithub(opts, assetName, assetDownloadPath, downloadOpts) { if (opts.token) { downloadOpts.headers.authorization = `token ${opts.token}`; } @@ -182,6 +188,41 @@ async function getAssetFromGithubApi(opts, assetName, downloadFolder) { await download(asset.url, assetDownloadPath, downloadOpts); } +/** + * Downloads the ripgrep asset from a mirror or from the GitHub API. + * @param {{ force: boolean; token: string; version: string; }} opts + * @param {string} assetName + * @param {string} downloadFolder + * @param {string | null} mirrorUrl + */ +async function downloadAsset(opts, assetName, downloadFolder, mirrorUrl) { + const assetDownloadPath = path.join(downloadFolder, assetName); + + // We can just use the cached binary + if (!opts.force && await fsExists(assetDownloadPath)) { + console.log('Using cached download: ' + assetDownloadPath); + return; + } + + const downloadOpts = { + headers: { + 'user-agent': 'vscode-ripgrep' + } + }; + + if (mirrorUrl) { + const baseUrl = mirrorUrl.endsWith('/') ? mirrorUrl : `${mirrorUrl}/`; + const downloadUrl = baseUrl + assetName; + + console.log(`Downloading from mirror: ${downloadUrl}`); + console.log(`Downloading to: ${assetDownloadPath}`); + await download(downloadUrl, assetDownloadPath, downloadOpts); + return; + } + + await downloadFromGithub(opts, assetName, assetDownloadPath, downloadOpts); +} + /** * @param {string} zipPath * @param {string} destinationDir @@ -261,15 +302,6 @@ function unzipWindows(zipPath, destinationDir) { }); } -/** - * Handle whitespace in filepath as powershell splits path with whitespaces - * @param {string} path - */ -function sanitizePathForPowershell(path) { - path = path.replace(/ /g, '` '); // replace whitespace with "` " as solution provided here https://stackoverflow.com/a/18537344/7374562 - return path; -} - function untar(zipPath, destinationDir) { return new Promise((resolve, reject) => { const unzipProc = child_process.spawn('tar', ['xvf', zipPath, '-C', destinationDir], { stdio: 'inherit' }); @@ -328,8 +360,10 @@ module.exports = async opts => { } const assetDownloadPath = path.join(tmpDir, assetName); + const mirrorUrl = getMirrorUrl(); + try { - await getAssetFromGithubApi(opts, assetName, tmpDir) + await downloadAsset(opts, assetName, tmpDir, mirrorUrl) } catch (e) { console.log('Deleting invalid download cache'); try {