From b501bddc6bcfabf9f4d8114b28c21aef4c9119c9 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:21:21 -0700 Subject: [PATCH] feat: report progress during tx-pull-www --- lib/progress-logger.mjs | 42 +++++++++++++++++++++++++++++++++++++++++ scripts/tx-pull-www.mjs | 26 ++++++++++++++++++------- 2 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 lib/progress-logger.mjs diff --git a/lib/progress-logger.mjs b/lib/progress-logger.mjs new file mode 100644 index 00000000..9b8fc020 --- /dev/null +++ b/lib/progress-logger.mjs @@ -0,0 +1,42 @@ +/** + * Helper class to log progress. + */ +export class ProgressLogger { + /** + * @param {number} [total] Optional: expected total number of items to process. + */ + constructor (total) { + this.total = total; + this.completed = 0; + } + + /** + * Set the expected total number of items to process. + * @param {number} total Total number of items to process. + */ + setTotal (total) { + if (this.total !== total) { + this.total = total; + delete this.percent; + } + } + + /** + * Increment the number of items processed and log progress. + * If a total is set, progress is logged as a percentage and only when the percentage changes. + * If no total is set, progress is logged as a count. + * @param {number} [count=1] Number of items processed. + */ + increment (count = 1) { + this.completed += count; + if (this.total) { + const percent = Math.floor(100 * this.completed / this.total); + if (percent !== this.percent) { + this.percent = percent; + console.info(`Progress: ${this.percent}% (${this.completed}/${this.total})`); + } + } else { + console.info(`Progress: ${this.completed} of unknown total`); + } + } +} diff --git a/scripts/tx-pull-www.mjs b/scripts/tx-pull-www.mjs index dbff18d9..ac3838fc 100755 --- a/scripts/tx-pull-www.mjs +++ b/scripts/tx-pull-www.mjs @@ -27,12 +27,13 @@ if (!process.env.TX_TOKEN || args.length < 1) { process.exit(1); } -import fs from 'fs'; +import fs from 'fs/promises'; import path from 'path'; import mkdirp from 'mkdirp'; import {txPull, txResources} from '../lib/transifex.js'; import locales, {localeMap} from '../src/supported-locales.mjs'; import {batchMap} from '../lib/batch.js'; +import {ProgressLogger} from '../lib/progress-logger.mjs'; // Globals const PROJECT = 'scratch-website'; @@ -49,21 +50,24 @@ const getLocaleData = async function (item) { for (let i = 0; i < 5; i++) { try { const translations = await txPull(PROJECT, resource, txLocale); - + const txOutdir = `${OUTPUT_DIR}/${PROJECT}.${resource}`; mkdirp.sync(txOutdir); const fileName = `${txOutdir}/${locale}.json`; - fs.writeFileSync( + + await fs.writeFile( fileName, JSON.stringify(translations, null, 4) ); + this.progress.increment(); return { resource: resource, locale: locale, file: fileName }; } catch (e) { - process.stdout.write(`got ${e.message}, retrying after ${i + 1} attempt(s)\n`); + console.error(e); + console.log(`retrying after ${i + 1} attempt(s)`); } } throw Error('failed to pull translations after 5 retries'); @@ -84,13 +88,21 @@ const expandResourceFiles = (resources) => { }; const pullTranslations = async function () { - const resources = await txResources('scratch-website'); + const resources = await txResources(PROJECT); const allFiles = expandResourceFiles(resources); + const progress = new ProgressLogger(allFiles.length); + try { - await batchMap(allFiles, CONCURRENCY_LIMIT, getLocaleData); + await batchMap(allFiles, CONCURRENCY_LIMIT, item => { + try { + getLocaleData(item); + } finally { + progress.increment(); + } + }); } catch (err) { - console.error(err); // eslint-disable-line no-console + console.error(err); process.exit(1); } };