From 2e06647726fae7905da2e2abe43d017860bfd68a Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Sat, 9 Oct 2021 17:43:26 -0400 Subject: [PATCH] sprinkled in some debug logging --- .github/workflows/ci.yml | 4 ++++ index.js | 25 +++++++++++++++++-------- package.json | 1 + yarn.lock | 2 +- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fe031b..6fd87d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/index.js b/index.js index c8b601f..0749d60 100644 --- a/index.js +++ b/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); - }); -} diff --git a/package.json b/package.json index 1cd778f..0d2e74f 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index ce296a6..de45a62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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==