mirror of
https://github.com/jakejarvis/careful-downloader.git
synced 2025-04-26 03:05:23 -04:00
sprinkled in some debug logging
This commit is contained in:
parent
2f0499cd32
commit
2e06647726
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -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
|
||||
|
25
index.js
25
index.js
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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==
|
||||
|
Loading…
x
Reference in New Issue
Block a user