(feature) add support for expanding paths on Windows + added more usage examples to cli
This commit is contained in:
parent
7b94c9b9a5
commit
b813ec0063
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,6 +8,8 @@ npm-debug.log*
|
||||
|
||||
# Compiled files
|
||||
dist
|
||||
src/**/*.js
|
||||
tests/**/*.js
|
||||
|
||||
# Extracted strings
|
||||
strings.json
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -107,6 +107,12 @@
|
||||
"any-observable": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"@types/braces": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz",
|
||||
"integrity": "sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.10.tgz",
|
||||
|
@ -61,6 +61,7 @@
|
||||
},
|
||||
"config": {},
|
||||
"devDependencies": {
|
||||
"@types/braces": "^3.0.0",
|
||||
"@types/chai": "^4.2.10",
|
||||
"@types/flat": "^5.0.0",
|
||||
"@types/glob": "^7.1.1",
|
||||
@ -68,6 +69,7 @@
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.12.29",
|
||||
"@types/yargs": "^15.0.4",
|
||||
"braces": "^3.0.2",
|
||||
"chai": "^4.2.0",
|
||||
"husky": "^4.2.3",
|
||||
"lint-staged": "^10.0.8",
|
||||
|
@ -1,4 +1,3 @@
|
||||
import * as fs from 'fs';
|
||||
import * as yargs from 'yargs';
|
||||
|
||||
import { ExtractTask } from './tasks/extract.task';
|
||||
@ -14,9 +13,22 @@ import { NullAsDefaultValuePostProcessor } from '../post-processors/null-as-defa
|
||||
import { PurgeObsoleteKeysPostProcessor } from '../post-processors/purge-obsolete-keys.post-processor';
|
||||
import { CompilerInterface } from '../compilers/compiler.interface';
|
||||
import { CompilerFactory } from '../compilers/compiler.factory';
|
||||
import { normalizePaths } from '../utils/fs-helpers';
|
||||
import { donateMessage } from '../utils/donate';
|
||||
|
||||
export const cli = yargs
|
||||
// First parsing pass to be able to access pattern argument for use input/output arguments
|
||||
const y = yargs
|
||||
.option('patterns', {
|
||||
alias: 'p',
|
||||
describe: 'Default patterns',
|
||||
type: 'array',
|
||||
default: ['/**/*.html', '/**/*.ts'],
|
||||
hidden: true
|
||||
});
|
||||
|
||||
const parsed = y.parse();
|
||||
|
||||
export const cli = y
|
||||
.usage('Extract strings from files for translation.\nUsage: $0 [options]')
|
||||
.version(require(__dirname + '/../../package.json').version)
|
||||
.alias('version', 'v')
|
||||
@ -30,19 +42,9 @@ export const cli = yargs
|
||||
normalize: true,
|
||||
required: true
|
||||
})
|
||||
.check(options => {
|
||||
options.input.forEach((dir: string) => {
|
||||
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
|
||||
throw new Error(`The path you supplied was not found: '${dir}'`);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
})
|
||||
.option('patterns', {
|
||||
alias: 'p',
|
||||
describe: 'Extract strings from the following file patterns',
|
||||
type: 'array',
|
||||
default: ['/**/*.html', '/**/*.ts']
|
||||
.coerce('input', (input: string[]) => {
|
||||
const paths = normalizePaths(input, parsed.patterns);
|
||||
return paths;
|
||||
})
|
||||
.option('output', {
|
||||
alias: 'o',
|
||||
@ -51,16 +53,20 @@ export const cli = yargs
|
||||
normalize: true,
|
||||
required: true
|
||||
})
|
||||
.coerce('output', (output: string[]) => {
|
||||
const paths = normalizePaths(output, parsed.patterns);
|
||||
return paths;
|
||||
})
|
||||
.option('format', {
|
||||
alias: 'f',
|
||||
describe: 'Output format',
|
||||
describe: 'Format',
|
||||
default: 'json',
|
||||
type: 'string',
|
||||
choices: ['json', 'namespaced-json', 'pot']
|
||||
})
|
||||
.option('format-indentation', {
|
||||
alias: 'fi',
|
||||
describe: 'Output format indentation',
|
||||
describe: 'Format indentation (JSON/Namedspaced JSON)',
|
||||
default: '\t',
|
||||
type: 'string'
|
||||
})
|
||||
@ -71,31 +77,39 @@ export const cli = yargs
|
||||
})
|
||||
.option('sort', {
|
||||
alias: 's',
|
||||
describe: 'Sort strings in alphabetical order when saving',
|
||||
describe: 'Sort strings in alphabetical order',
|
||||
type: 'boolean'
|
||||
})
|
||||
.option('clean', {
|
||||
alias: 'c',
|
||||
describe: 'Remove obsolete strings when merging',
|
||||
describe: 'Remove obsolete strings after merge',
|
||||
type: 'boolean'
|
||||
})
|
||||
.option('key-as-default-value', {
|
||||
alias: 'k',
|
||||
describe: 'Use key as default value for translations',
|
||||
describe: 'Use key as default value',
|
||||
type: 'boolean'
|
||||
})
|
||||
.option('null-as-default-value', {
|
||||
alias: 'n',
|
||||
describe: 'Use null as default value for translations',
|
||||
describe: 'Use null as default value',
|
||||
type: 'boolean'
|
||||
})
|
||||
.group(['format', 'format-indentation', 'sort', 'clean'], 'Output')
|
||||
.group(['key-as-default-value', 'null-as-default-value'], 'Default value (defaults to empty string)')
|
||||
.conflicts('key-as-default-value', 'null-as-default-value')
|
||||
.example(`$0 -i ./src-a/ -i ./src-b/ -o strings.json`, 'Extract (ts, html) from multiple paths')
|
||||
.example(`$0 -i './{src-a,src-b}/' -o strings.json`, 'Extract (ts, html) from multiple paths using brace expansion')
|
||||
.example(`$0 -i ./src/ -o ./i18n/da.json -o ./i18n/en.json`, 'Extract (ts, html) and save to da.json+en.json')
|
||||
.example(`$0 -i ./src/ -o './i18n/{en,da}.json'`, 'Extract (ts, html) and save to da.json+en.json using brace expansion')
|
||||
.example(`$0 -i './src/**/*.{ts,tsx,html}' -o strings.json`, 'Extract from ts, tsx and html')
|
||||
.example(`$0 -i './src/**/!(*.spec).{ts,html}' -o strings.json`, 'Extract from ts, html, excluding files with ".spec" in filename')
|
||||
.wrap(110)
|
||||
.exitProcess(true)
|
||||
.parse(process.argv);
|
||||
|
||||
const extractTask = new ExtractTask(cli.input, cli.output, {
|
||||
replace: cli.replace,
|
||||
patterns: cli.patterns
|
||||
replace: cli.replace
|
||||
});
|
||||
|
||||
// Parsers
|
||||
|
@ -12,13 +12,11 @@ import * as mkdirp from 'mkdirp';
|
||||
|
||||
export interface ExtractTaskOptionsInterface {
|
||||
replace?: boolean;
|
||||
patterns?: string[];
|
||||
}
|
||||
|
||||
export class ExtractTask implements TaskInterface {
|
||||
protected options: ExtractTaskOptionsInterface = {
|
||||
replace: false,
|
||||
patterns: []
|
||||
replace: false
|
||||
};
|
||||
|
||||
protected parsers: ParserInterface[] = [];
|
||||
@ -100,8 +98,8 @@ export class ExtractTask implements TaskInterface {
|
||||
*/
|
||||
protected extract(): TranslationCollection {
|
||||
let collection: TranslationCollection = new TranslationCollection();
|
||||
this.inputs.forEach(dir => {
|
||||
this.readDir(dir, this.options.patterns).forEach(filePath => {
|
||||
this.inputs.forEach(pattern => {
|
||||
this.getFiles(pattern).forEach(filePath => {
|
||||
this.out(dim('- %s'), filePath);
|
||||
const contents: string = fs.readFileSync(filePath, 'utf-8');
|
||||
this.parsers.forEach(parser => {
|
||||
@ -138,15 +136,12 @@ export class ExtractTask implements TaskInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all files in dir matching patterns
|
||||
* Get all files matching pattern
|
||||
*/
|
||||
protected readDir(dir: string, patterns: string[]): string[] {
|
||||
return patterns.reduce((results, pattern) => {
|
||||
return glob
|
||||
.sync(dir + pattern)
|
||||
.filter(filePath => fs.statSync(filePath).isFile())
|
||||
.concat(results);
|
||||
}, []);
|
||||
protected getFiles(pattern: string): string[] {
|
||||
return glob
|
||||
.sync(pattern)
|
||||
.filter(filePath => fs.statSync(filePath).isFile());
|
||||
}
|
||||
|
||||
protected out(...args: any[]): void {
|
||||
|
26
src/utils/fs-helpers.ts
Normal file
26
src/utils/fs-helpers.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as os from 'os';
|
||||
import * as fs from 'fs';
|
||||
import * as braces from 'braces';
|
||||
|
||||
export function normalizeHomeDir(path: string): string {
|
||||
if (path.substring(0, 1) === '~') {
|
||||
return `${os.homedir()}/${path.substring(1)}`;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
export function expandPattern(pattern: string): string[] {
|
||||
return braces(pattern, { expand: true });
|
||||
}
|
||||
|
||||
export function normalizePaths(patterns: string[], defaultPatterns: string[] = []): string[] {
|
||||
return patterns.map(pattern =>
|
||||
expandPattern(pattern).map(path => {
|
||||
path = normalizeHomeDir(path);
|
||||
if (fs.existsSync(path) && fs.statSync(path).isDirectory()) {
|
||||
return defaultPatterns.map(defaultPattern => path + defaultPattern);
|
||||
}
|
||||
return path;
|
||||
}).flat()
|
||||
).flat();
|
||||
}
|
Loading…
Reference in New Issue
Block a user