UNPKG

@keymanapp/kmc

Version:

Keyman Developer compiler command line tools

123 lines 5.49 kB
import * as fs from 'fs'; import * as path from 'path'; import { Option } from 'commander'; import { NodeCompilerCallbacks } from '../util/NodeCompilerCallbacks.js'; import { InfrastructureMessages } from '../messages/infrastructureMessages.js'; import { AnalyzeOskCharacterUse, AnalyzeOskRewritePua } from '@keymanapp/kmc-analyze'; import { BaseOptions } from '../util/baseOptions.js'; import { runOnFiles } from '../util/projectRunner.js'; import { exitProcess } from '../util/sysexits.js'; import { commanderOptionsToBaseOptions } from '../util/extendedCompilerOptions.js'; ; export function declareAnalyze(program) { let command = program.command('analyze'); declareOskCharUse(command); declareOskRewrite(command); } function declareOskCharUse(command) { let subCommand = command.command('osk-char-use [infile...]'); BaseOptions.addAll(subCommand); subCommand .description('Analyze On Screen Keyboards for character usage') .option('-b, --base', 'First PUA codepoint to use, in hexadecimal (default F100)', 'F100') .option('--include-counts', 'Include number of times each character is referenced', false) .option('--strip-dotted-circle', 'Strip U+25CC (dotted circle base) from results', false) .option('-i, --input-mapping-file <filename>', 'Merge result file with existing mapping file') .addOption(new Option('-m, --mapping-file <filename>', 'Result file to write to (.json, .md, or .txt)').makeOptionMandatory()) .action(async (filenames, _options, commander) => { const options = commander.optsWithGlobals(); if (!filenames.length) { // If there are no filenames provided, then we are building the current // folder ('.') as a project-style build filenames.push('.'); } if (!await analyze(analyzeOskCharUse, filenames, options)) { // Once a file fails to build, we bail on subsequent builds return await exitProcess(1); } }); } function declareOskRewrite(command) { let subCommand = command.command('osk-rewrite-from-char-use [infile...]'); subCommand .description('Rewrite On Screen Keyboard files from source mapping; given file.ext, output is written to file-pua.ext') .addOption(new Option('-m, --mapping-file <filename>', 'JSON mapping file to read from').makeOptionMandatory()) .action(async (filenames, options) => { if (!filenames.length) { // If there are no filenames provided, then we are building the current // folder ('.') as a project-style build filenames.push('.'); } if (!await analyze(analyzeOskRewritePua, filenames, options)) { // Once a file fails to build, we bail on subsequent builds return await exitProcess(1); } return null; }); } function commanderOptionsToAnalyzeOptions(options) { // TODO: split options per sub-command const result = { ...commanderOptionsToBaseOptions(options), // AnalysisActivityOptions base: options.base, includeCounts: options.includeCounts ?? false, inputMappingFile: options.inputMappingFile, mappingFile: options.mappingFile, stripDottedCircle: options.stripDottedCircle ?? false, }; return result; } async function analyze(action, filenames, commanderOptions) { const options = commanderOptionsToAnalyzeOptions(commanderOptions); let callbacks = new NodeCompilerCallbacks(options); try { return await action(callbacks, filenames, options); } catch (e) { callbacks.reportMessage(InfrastructureMessages.Fatal_UnexpectedException({ e })); return false; } } async function analyzeOskCharUse(callbacks, filenames, options) { const format = path.extname(options.mappingFile); if (format != '.txt' && format != '.json' && format != '.md') { callbacks.reportMessage(InfrastructureMessages.Error_UnknownFileFormat({ format })); return false; } const analyzer = new AnalyzeOskCharacterUse(callbacks, { puaBase: parseInt(options.base, 16), stripDottedCircle: options.stripDottedCircle, includeCounts: options.includeCounts, mergeMapFile: options.inputMappingFile }); if (!await runOnFiles(callbacks, filenames, analyzer.analyze.bind(analyzer))) { return false; } const output = analyzer.getStrings(format).join('\n'); fs.writeFileSync(options.mappingFile, output, 'utf8'); return true; } async function analyzeOskRewritePua(callbacks, filenames, options) { const analyzer = new AnalyzeOskRewritePua(callbacks); const mapping = JSON.parse(fs.readFileSync(options.mappingFile, 'utf-8')); return await runOnFiles(callbacks, filenames, async (filename) => { if (!await analyzer.analyze(filename, mapping)) { return false; } const mappedFilenames = Object.keys(analyzer.data); for (let filename of mappedFilenames) { const ext = path.extname(filename); const outputFilename = filename.substring(0, filename.length - ext.length) + '-pua' + ext; fs.writeFileSync(outputFilename, analyzer.data[filename]); } return true; }); } /** * these are exported only for unit tests, do not use */ export const analyzeUnitTestEndpoints = { analyzeOskCharUse }; //# sourceMappingURL=analyze.js.map