1
mirror of https://github.com/jakejarvis/careful-downloader.git synced 2025-04-26 08:55:23 -04:00

sprinkled in some debug logging

This commit is contained in:
Jake Jarvis 2021-10-09 17:43:26 -04:00
parent 2f0499cd32
commit 2e06647726
Signed by: jake
GPG Key ID: 2B0C9CF251E69A39
4 changed files with 23 additions and 9 deletions

View File

@ -30,3 +30,7 @@ jobs:
- run: yarn install --frozen-lockfile
- run: yarn audit
- run: yarn test
env:
DEBUG: careful-downloader
DEBUG_HIDE_DATE: 1
DEBUG_COLORS: 0

View File

@ -1,6 +1,7 @@
import path from "path";
import stream from "stream";
import { promisify } from "util";
import createDebug from "debug";
import fs from "fs-extra";
import tempy from "tempy";
import got from "got";
@ -9,8 +10,12 @@ import decompress from "decompress";
import urlParse from "url-parse";
import isPathInCwd from "is-path-in-cwd";
// set DEBUG=careful-downloader in environment to enable detailed logging
const debug = new createDebug("careful-downloader");
export default async function downloader(downloadUrl, checksumUrl, options = {}) {
// normalize options and set defaults
debug(`User-provided config: ${JSON.stringify(options)}`);
options = {
filename: options.filename || urlParse(downloadUrl).pathname.split("/").pop(),
extract: !!options.extract,
@ -19,6 +24,7 @@ export default async function downloader(downloadUrl, checksumUrl, options = {})
algorithm: options.algorithm || "sha256",
encoding: options.encoding || "binary",
};
debug(`Normalized config with defaults: ${JSON.stringify(options)}`);
// throw an error if destDir is outside of the module to prevent path traversal for security reasons
if (!isPathInCwd(options.destDir)) {
@ -27,6 +33,7 @@ export default async function downloader(downloadUrl, checksumUrl, options = {})
// initialize temporary directory
const tempDir = tempy.directory();
debug(`Temp dir generated: '${tempDir}'`);
try {
// simultaneously download the desired file and its checksums
@ -39,32 +46,39 @@ export default async function downloader(downloadUrl, checksumUrl, options = {})
if (await checkChecksum(tempDir, options.filename, "checksums.txt", options.algorithm, options.encoding)) {
// optionally clear the target directory of existing files
if (options.cleanDestDir && fs.existsSync(options.destDir)) {
debug(`Deleting contents of '${options.destDir}'`);
await fs.remove(options.destDir);
}
// ensure the target directory exists
debug(`Ensuring target '${options.destDir}' exists`);
await fs.mkdirp(options.destDir);
if (options.extract) {
// decompress download and move resulting files to final destination
debug(`Extracting '${options.filename}' to '${options.destDir}'`);
await decompress(path.join(tempDir, options.filename), options.destDir);
return options.destDir;
} else {
// move verified download to final destination as-is
debug(`Not told to extract; copying '${options.filename}' as-is to '${path.join(options.destDir, options.filename)}'`);
await fs.copy(path.join(tempDir, options.filename), path.join(options.destDir, options.filename));
return path.join(options.destDir, options.filename);
}
} else {
throw new Error(`Invalid checksum for ${options.filename}.`);
throw new Error(`Invalid checksum for '${options.filename}'.`);
}
} finally {
// delete temporary directory
debug(`Deleting temp dir: '${tempDir}'`);
await fs.remove(tempDir);
}
}
// Download any file to any destination. Returns a promise.
async function downloadFile(url, dest) {
debug(`Downloading '${url}' to '${dest}'`);
// get remote file and write locally
const pipeline = promisify(stream.pipeline);
const download = await pipeline(
@ -77,6 +91,8 @@ async function downloadFile(url, dest) {
// Check da checksum.
async function checkChecksum(baseDir, downloadFile, checksumFile, algorithm, encoding) {
debug(`Validating checksum of '${downloadFile}' (hash: '${algorithm}', encoding: '${encoding}')`);
// instantiate checksum validator
const checker = new sumchecker.ChecksumValidator(algorithm, path.join(baseDir, checksumFile), {
defaultTextEncoding: encoding,
@ -87,10 +103,3 @@ async function checkChecksum(baseDir, downloadFile, checksumFile, algorithm, enc
return valid;
}
// eslint-disable-next-line no-unused-vars
async function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

View File

@ -24,6 +24,7 @@
"test": "eslint . && mocha"
},
"dependencies": {
"debug": "^4.3.2",
"decompress": "^4.2.1",
"fs-extra": "^10.0.0",
"got": "^11.8.2",

View File

@ -553,7 +553,7 @@ crypto-random-string@^4.0.0:
dependencies:
type-fest "^1.0.1"
debug@4.3.2, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
debug@4.3.2, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==