From bf92574b9034f9616a1980fb15d8ee8d6423894b Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Wed, 4 Mar 2020 03:48:17 +0100 Subject: [PATCH 1/2] Pass through output directory --- src/batch.ts | 2 +- src/interface.d.ts | 2 ++ src/output/processor/FileOutput.ts | 6 +++--- src/utils/execution_options.ts | 8 +++++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/batch.ts b/src/batch.ts index 4752e429..ce29a8f3 100644 --- a/src/batch.ts +++ b/src/batch.ts @@ -95,7 +95,7 @@ readDir(FIXTURES_ROOT) if (options.dry) { await processable } else { - await FileOutput(processable, { ...options, inputDir, output: './analysis.json' }) + await FileOutput(processable, { ...options, inputDir, outputDir: inputDir, output: './analysis.json' }) } return { result: analysis, runtime, fixture } diff --git a/src/interface.d.ts b/src/interface.d.ts index 39d0638a..a1bbb45a 100644 --- a/src/interface.d.ts +++ b/src/interface.d.ts @@ -9,6 +9,8 @@ interface ExecutionOptions { output: string; /** The input directory path */ inputDir: string; + /** The output directory path */ + outputDir: string; /** The exercise slug */ exercise: string; /** Unless true, expects website-copy to provide the contents of the templates */ diff --git a/src/output/processor/FileOutput.ts b/src/output/processor/FileOutput.ts index cd1e8f71..5eb2a649 100644 --- a/src/output/processor/FileOutput.ts +++ b/src/output/processor/FileOutput.ts @@ -3,7 +3,7 @@ import path from 'path' import { getProcessLogger } from '~src/utils/logger' -type FileOutputOptions = Pick +type FileOutputOptions = Pick export const FileOutput: OutputProcessor = async (previous: Promise, options: FileOutputOptions): Promise => { const output = await previous @@ -13,8 +13,8 @@ export const FileOutput: OutputProcessor = async (previous: Promise, opt return writeFile(outputPath, output) } -function getOutputPath({ output, inputDir }: FileOutputOptions): string { +function getOutputPath({ output, outputDir }: FileOutputOptions): string { return path.isAbsolute(output) ? output - : path.join(inputDir, output) + : path.join(outputDir, output) } diff --git a/src/utils/execution_options.ts b/src/utils/execution_options.ts index 2aa2db86..96c0f070 100644 --- a/src/utils/execution_options.ts +++ b/src/utils/execution_options.ts @@ -5,6 +5,7 @@ export class ExecutionOptionsImpl implements ExecutionOptions { public console!: boolean public output!: string public inputDir!: string + public outputDir!: string public exercise!: string public dry!: boolean public noTemplates!: boolean @@ -16,7 +17,7 @@ export class ExecutionOptionsImpl implements ExecutionOptions { public static create(): ExecutionOptions { const args = yargs - .usage('Usage: $0 [options]') + .usage('Usage: $0 [] [options]') .example('$0 two-fer ~/javascript/two-fer/128/', 'Analyze the input directory "128" against the two-fer analyzer') .alias('d', 'debug') .alias('c', 'console') @@ -24,7 +25,7 @@ export class ExecutionOptionsImpl implements ExecutionOptions { .alias('p', 'pretty') .describe('d', 'Unless given, only outputs warnings and errors') .describe('c', 'If given, outputs to the console') - .describe('o', 'Path relative to the input dir where the analyzis results are stored') + .describe('o', 'Path relative to the output dir where the analyzis results are stored') .describe('noTemplates', 'Unless given, exports templates instead of messages (feature flag)') .describe('p', 'If given, formats the JSON output using 2 space indentation') .describe('dry', 'If given, does not output anything to disk') @@ -49,7 +50,8 @@ export class ExecutionOptionsImpl implements ExecutionOptions { dry, noTemplates, exercise: _[0], - inputDir: _[1] + inputDir: _[1], + outputDir: _[2] || _[1] }) } } From a51a9f37bae2e26fda76e9f6d3f6f2f376d83d22 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Sun, 28 Jun 2020 05:34:05 +0200 Subject: [PATCH 2/2] Update stats.ts --- src/stats.ts | 145 +++++++++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 62 deletions(-) diff --git a/src/stats.ts b/src/stats.ts index 96a29c15..137f5718 100644 --- a/src/stats.ts +++ b/src/stats.ts @@ -1,12 +1,11 @@ +import { Node } from "@typescript-eslint/typescript-estree/dist/ts-estree/ts-estree"; -import { Node } from '@typescript-eslint/typescript-estree/dist/ts-estree/ts-estree'; +import path from "path"; -import path from 'path'; - -import { DirectoryInput } from '~src/input/DirectoryInput'; -import { AstParser } from '~src/parsers/AstParser'; -import { Bootstrap } from '~src/utils/bootstrap'; -import { readDir } from '~src/utils/fs'; +import { DirectoryInput } from "~src/input/DirectoryInput"; +import { AstParser } from "~src/parsers/AstParser"; +import { Bootstrap } from "~src/utils/bootstrap"; +import { readDir } from "~src/utils/fs"; // The bootstrap call uses the arguments passed to the process to figure out // which exercise to target, where the input lives (directory input) and what @@ -18,65 +17,85 @@ import { readDir } from '~src/utils/fs'; // exercise analyzer (dry: without output) for all the folders inside the // two-fer fixture folder, with console log output turned on // -const { exercise, options, logger } = Bootstrap.call() +const { exercise, options, logger } = Bootstrap.call(); -const FIXTURES_ROOT = path.join(options.inputDir || path.join(__dirname, '..', 'test', 'fixtures'), exercise.slug) +const FIXTURES_ROOT = path.join( + options.inputDir || path.join(__dirname, "..", "test", "fixtures"), + exercise.slug +); -function pad(value: string | number, pad = ' '): string { - return (pad + value).slice(-pad.length) +function pad(value: string | number, pad = " "): string { + return (pad + value).slice(-pad.length); } -logger.log(`=> start statistics collection for ${exercise.slug}`) +logger.log(`=> start statistics collection for ${exercise.slug}`); -const parser = new AstParser({ comment: false, tokens: false, loc: false, range: false }) +const parser = new AstParser({ + comment: false, + tokens: false, + loc: false, + range: false, +}); readDir(FIXTURES_ROOT) // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - .then(async (fixtureDirs) => Promise.all(fixtureDirs.map(async (fixtureDir) => { - const inputDirectory = path.join(FIXTURES_ROOT, fixtureDir) - try { - const input = new DirectoryInput(inputDirectory, exercise.slug) - const results = await parser.parse(input) - - if (results.length === 0) { - throw new Error(`No input source files for ${exercise.slug}`) - } - - const [{ program: root }] = results - - // There can be a bug where loc and range data is not removed - if (root.loc || root.range) { - delete root.comments - delete root.tokens - delete root.loc - delete root.range - - require('eslint/lib/util/traverser').traverse( - root, { - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - enter(node: Node) { - delete node.loc - delete node.range - }, - - // Use typescript visitor keys (otherwise type annotations are not removed) - visitorKeys: require("@typescript-eslint/parser/dist/visitor-keys").visitorKeys + .then(async (fixtureDirs) => + Promise.all( + fixtureDirs.map(async (fixtureDir) => { + const inputDirectory = path.join(FIXTURES_ROOT, fixtureDir); + try { + const input = new DirectoryInput(inputDirectory, exercise.slug); + const results = await parser.parse(input); + + if (results.length === 0) { + throw new Error(`No input source files for ${exercise.slug}`); + } + + const [{ program: root }] = results; + + // There can be a bug where loc and range data is not removed + if (root.loc || root.range) { + delete root.comments; + delete root.tokens; + delete root.loc; + delete root.range; + + require("eslint/lib/shared/traverser").traverse(root, { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + enter(node: Node) { + delete node.loc; + delete node.range; + }, + + // Use typescript visitor keys (otherwise type annotations are not removed) + visitorKeys: require("@typescript-eslint/typescript-estree/dist/visitor-keys") + .visitorKeys, + }); } - ) - } - - return JSON.stringify(root) - } catch ({ message, ...other}) { - logger.error(`=> skipping ~${path.relative(path.dirname(FIXTURES_ROOT), inputDirectory)}`) - logger.error(` ${message}${Object.keys(other).length > 0 ? ` (${JSON.stringify(other)})` : ''}\n`) - return undefined - } - }))) + + return JSON.stringify(root); + } catch ({ message, ...other }) { + logger.error( + `=> skipping ~${path.relative( + path.dirname(FIXTURES_ROOT), + inputDirectory + )}` + ); + logger.error( + ` ${message}${ + Object.keys(other).length > 0 ? ` (${JSON.stringify(other)})` : "" + }\n` + ); + return undefined; + } + }) + ) + ) // eslint-disable-next-line @typescript-eslint/explicit-function-return-type .then((trees) => trees.filter(Boolean) as readonly string[]) // eslint-disable-next-line @typescript-eslint/explicit-function-return-type .then((trees) => { - const realTrees = trees.filter(Boolean) + const realTrees = trees.filter(Boolean); const counts = { invalid: trees.length - realTrees.length, valid: realTrees.length, @@ -84,15 +103,16 @@ readDir(FIXTURES_ROOT) unique: Object.keys( // eslint-disable-next-line @typescript-eslint/explicit-function-return-type realTrees.reduce((counts, tree) => { - counts[tree] = (counts[tree] || 0) + 1 - return counts - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + counts[tree] = (counts[tree] || 0) + 1; + return counts; + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions }, {} as { [tree: string]: number }) - ).length - } + ).length, + }; - const { total, unique, valid, invalid } = counts - process.stdout.write(` + const { total, unique, valid, invalid } = counts; + process.stdout.write( + ` ## Raw output \`\`\`json @@ -107,5 +127,6 @@ location data (whitespace) and other tokens. | total | unique | valid | invalid | |--------:|--------:|--------:|--------:| | ${pad(total)} | ${pad(unique)} | ${pad(valid)} | ${pad(invalid)} | - `.trim()) - }) + `.trim() + ); + });