UNPKG

@ofzza/adventofcode

Version:
273 lines 9.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); // Dependencies require("colors"); const yargs_1 = (0, tslib_1.__importDefault)(require("yargs/yargs")); const services_1 = require("./services"); // Parse arguments (0, yargs_1.default)(process.argv.slice(2)) // Define common CLI options .option('verbose', { alias: 'v', type: 'boolean', describe: 'Verbose output', default: false, }) .option('config', { alias: 'c', type: 'string', describe: 'Path to the configuration file', default: './aoc.json', }) .option('task', { alias: 't', type: 'number', describe: 'Number of task(s) to run', default: [], }) .option('task', { alias: 't', type: 'number', describe: 'Number of task(s) to run', default: [], }) .option('name', { alias: 'n', type: 'string', describe: 'Start of name of task(s) to run', default: '', }) .option('type', { alias: 'p', type: 'string', describe: 'Type of task(s) to run', default: '', }) // Define CLI commands .command('init', 'Creates a default configuration file int he current directory', () => undefined, async (argv) => { // Write default config file configWriteDefault(argv); }) .command('list', 'List all runnable tasks', () => undefined, async (argv) => { // Load and output configuration configInit(argv); printConfigHeader(argv); // List tasks printTaskList(argv); }) .command('run', 'Run all runnable tasks', // Additional command options yargs => yargs .option('output', { alias: 'o', type: 'boolean', describe: 'Pipes everything from the task being run', default: false, }) .option('obfuscate', { alias: 'b', type: 'boolean', describe: 'Obfuscate result', default: false, }), async (argv) => { // Load and output configuration configInit(argv); printConfigHeader(argv); // Run tasks runTasks(argv); }) .help().argv; /** * Initialize configuration writing a default config file * @param argv CLI arguments */ function configWriteDefault(argv) { try { services_1.Configuration.writeDefault(argv.config); } catch (err) { console.error(`ERROR: Failed initializing configuration with error message: ${err.message}`.red); process.exit(1); } } /** * Initialize configuration from a config file * @param argv CLI arguments */ function configInit(argv) { try { services_1.Configuration.initialize(argv.config); } catch (err) { console.error(`ERROR: Failed initializing configuration with error message: ${err.message}`.red); process.exit(1); } } /** * Print configuration header * @param argv CLI arguments */ function printConfigHeader(argv) { if (!!argv.verbose) { console.log(); console.log(`| Advent of Code ${services_1.Configuration.config.year}, ${services_1.Configuration.config.author}`.white); console.log([`|`.white, ` CWD: ${services_1.Configuration.cwd}`.gray].join('')); console.log(`--------------------------------------------------------------`.white); console.log(); } } /** * Print list of runnable tasks * @param verbose If verbose output is requested */ function printTaskList(argv) { var _a; // Get tasks const tasks = services_1.Task.get({ tasks: argv.task instanceof Array ? argv.task.map(task => parseInt(task)) : argv.task ? [parseInt(argv.task)] : [], type: argv.type, name: argv.name, }); // Verbose output if (!!argv.verbose) { console.log(`> Found ${tasks.length} runnable tasks${tasks.length ? ':' : '!'}`.gray); for (const i of Object.keys(tasks).map(i => parseInt(i))) { console.log(taskToString(i + 1, tasks[i])); } } // Non verbose output else { for (const task of tasks) { console.log(`${task.command} ${(_a = task.args) === null || _a === void 0 ? void 0 : _a.join(' ')}`); } } } /** * Executes requested task * @param argv Startup arguments */ async function runTasks(argv) { // Initialize task runner const runner = services_1.Task.run(argv, text => { if (argv.output) { const obfuscatedOutput = text; console.log([...obfuscatedOutput.trim().split('\n')].join('\n').dim.italic); } }); // Run tasks and output result const results = []; while (true) { // Get task being run const stepA = await runner.next(); if (stepA.done) break; const task = stepA.value; // Output task info if (!!argv.verbose) { console.log(taskToString(results.length, task)); } // Run task if (argv.output) { console.log(`~~~ task output: "${task.command} ${task.args} "`.padEnd(64, '~').blue); } const stepB = await runner.next(); if (argv.output) { console.log(''.padEnd(64, '~').blue); } if (stepB.done) break; const result = stepB.value; // Store result results.push(result); // Verbose output of result if (!!argv.verbose) { console.log(resultToString(result, !!argv.output, !!argv.obfuscate)); console.log(); } // Non verbose output of result else { // Task execution output console.log(`${result.isValid === undefined ? '?' : result.isValid ? '✓'.green : '✘'.red} ${result.time.toFixed(3)}ms ${result.value instanceof Error ? result.value.message.replace(/\n/g, ' \\n ') : !argv.obfuscate ? result.value : '*****'}`); } } // Compile execution stats const stats = { error: results.filter(r => r.isError).map(r => r.time), invalid: results.filter(r => !r.isError && r.isValid === false).map(r => r.time), valid: results.filter(r => !r.isError && r.isValid === true).map(r => r.time), unknown: results.filter(r => !r.isError && r.isValid === undefined).map(r => r.time), }; const times = { error: stats.error.reduce((s, t) => s + t, 0), invalid: stats.invalid.reduce((s, t) => s + t, 0), valid: stats.valid.reduce((s, t) => s + t, 0), unknown: stats.unknown.reduce((s, t) => s + t, 0), }; // Output stats if (!!argv.verbose) { console.log(`--------------------------------------------------------------`.white); console.log(); console.log([ `Executed `.gray, `${stats.error.length + stats.invalid.length + stats.valid.length + stats.unknown.length}`, ` tasks in `.gray, `${(times.error + times.invalid + times.valid + times.unknown).toFixed(3)} ms`, `:`.gray, ].join('')); if (stats.error.length) { console.log(['- '.gray, '✘ Error '.red, `| Executed `.gray, `${stats.error.length}`, ` tasks in `.gray, `${times.error.toFixed(3)} ms`].join('')); } if (stats.invalid.length) { console.log(['- '.gray, '✘ Invalid '.red, `| Executed `.gray, `${stats.invalid.length}`, ` tasks in `.gray, `${times.invalid.toFixed(3)} ms`].join('')); } if (stats.valid.length) { console.log(['- '.gray, '✓ Valid '.green, `| Executed `.gray, `${stats.valid.length}`, ` tasks in `.gray, `${times.valid.toFixed(3)} ms`].join('')); } if (stats.unknown.length) { console.log(['- '.gray, '? Unknown ', `| Executed `.gray, `${stats.unknown.length}`, ` tasks in `.gray, `${times.unknown.toFixed(3)} ms`].join('')); } } } /** * Composes a string representation of a task * @param i Index of the task * @param task Task instance * @returns String representation of a task */ function taskToString(i, task) { var _a; return [ `${`${i.toString()}.`.padEnd(4, ' ')}`.blue, ` | `.gray, `${task.name}`.white, ` | `.gray, `${task.type}`.white, ` | $ `.gray, `${task.command} ${(_a = task.args) === null || _a === void 0 ? void 0 : _a.join(' ')}`.gray, ].join(''); } /** * Composes a string representation of a task execution result * @param result Result instance * @param output If full output should be displayed * @param obfuscate If result output should be obfuscated * @returns String representation of a task execution result */ function resultToString(result, output = false, obfuscate = false) { const obfuscatedOutput = !obfuscate ? result.output : result.output.replace(new RegExp(result.value.toString(), 'g'), '*****'); return [ // Task execution result '- executed in: '.gray, `${result.time.toFixed(3)} ms `.white, '\n', '- result: '.gray, result.isError ? `${result.value.message.replace(/\n/g, ' \\n ')}`.red : [ `${!obfuscate ? result.value : '*****'}`[result.isValid === undefined ? 'white' : result.isValid ? 'green' : 'red'], result.isValid === false ? `\n expected: ${!obfuscate ? result.task.value : '*****'}`.gray : '', ].join(''), ].join(''); } //# sourceMappingURL=index.js.map