Skip to content

Commit

Permalink
feat: allow patterns in config
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 committed Apr 19, 2024
1 parent d86f992 commit aa76508
Show file tree
Hide file tree
Showing 15 changed files with 1,200 additions and 399 deletions.
678 changes: 678 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"prettier": "prettier --write ./src ./test ./scripts jest.config.ts jest.*.config.ts",
"run-dev": "cross-env NODE_OPTIONS=\"--import=./scripts/registerTsNode.js\" node ./src/index.ts",
"schema": "openapi-typescript http://localhost:22222/v3/api-docs/All%20Internal%20-%20for%20Tolgee%20Web%20application --output src/client/internal/schema.generated.ts",
"release": "semantic-release"
"release": "semantic-release",
"config:type": "node scripts/configType.mjs"
},
"author": "Jan Cizmar",
"license": "MIT",
Expand Down Expand Up @@ -58,6 +59,7 @@
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.6.1",
"js-yaml": "^4.1.0",
"json-schema-to-typescript": "^13.1.2",
"openapi-typescript": "^6.3.9",
"prettier": "^3.0.0",
"rimraf": "^5.0.1",
Expand Down
17 changes: 14 additions & 3 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,28 @@
"type": "object",
"properties": {
"apiUrl": {
"description": "The url of Tolgee API.",
"type": "string"
},
"apiKey": {
"description": "Tolgee API Key. Can be a Project API Key or a Personal Access Token.",
"type": "string"
},
"projectId": {
"description": "Project ID. Only required when using a Personal Access Token.",
"type": ["number", "string"]
},
"extractor": {
"description": "A path to a custom extractor to use instead of the default one.",
"type": "string"
},
"patterns": {
"description": "File glob patterns to include",
"type": "array",
"items": {
"type": "string"
}
},
"path": {
"type": "string"
},
Expand Down Expand Up @@ -37,9 +51,6 @@
"type": "string"
}
},
"extractor": {
"type": "string"
},
"sdk": {
"enum": ["react", "vue", "svelte"]
}
Expand Down
7 changes: 7 additions & 0 deletions scripts/configType.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { writeFileSync } from 'fs';
import { compileFromFile } from 'json-schema-to-typescript';

// compile from file
compileFromFile('schema.json', {}).then((ts) =>
writeFileSync('./src/schema.d.ts', ts)
);
2 changes: 1 addition & 1 deletion src/arguments.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Argument } from 'commander';

export const FILE_PATTERNS = new Argument(
'<patterns...>',
'[patterns...]',
'File glob patterns to include (hint: make sure to escape it in quotes, or your shell might attempt to unroll some tokens like *)'
);
12 changes: 7 additions & 5 deletions src/commands/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { Command } from 'commander';
import extractPrint from './extract/print.js';
import extractCheck from './extract/check.js';
import { EXTRACTOR } from '../options.js';
import { Schema } from '../schema.js';

export type BaseExtractOptions = {
extractor: string;
};

export default new Command('extract')
.description('Extracts strings from your projects')
.addOption(EXTRACTOR)
.addCommand(extractPrint)
.addCommand(extractCheck);
export default (config: Schema) =>
new Command('extract')
.description('Extracts strings from your projects')
.addOption(EXTRACTOR)
.addCommand(extractPrint(config))
.addCommand(extractCheck(config));
96 changes: 53 additions & 43 deletions src/commands/extract/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,68 @@ import {
WarningMessages,
emitGitHubWarning,
} from '../../extractor/warnings.js';
import { loading } from '../../utils/logger.js';
import { error, loading } from '../../utils/logger.js';
import { FILE_PATTERNS } from '../../arguments.js';
import { Schema } from '../../schema.js';

type ExtractLintOptions = BaseExtractOptions;

async function lintHandler(this: Command, filesPatterns: string[]) {
const opts: ExtractLintOptions = this.optsWithGlobals();
const extracted = await loading(
'Analyzing code...',
extractKeysOfFiles(filesPatterns, opts.extractor)
);
const lintHandler = (config: Schema) =>
async function (this: Command, filesPatterns: string[]) {
const patterns = filesPatterns.length ? filesPatterns : config.patterns;

let warningCount = 0;
let filesCount = 0;
for (const [file, { warnings }] of extracted) {
if (warnings.length) {
warningCount += warnings.length;
filesCount++;
if (!patterns?.length) {
error('Missing argument <patterns>');
process.exit(1);
}

const relFile = relative(process.cwd(), file);
console.log('%s:', relFile);
for (const warning of warnings) {
if (warning.warning in WarningMessages) {
const { name } = WarningMessages[warning.warning];
console.log('\tline %d: %s', warning.line, name);
} else {
console.log('\tline %d: %s', warning.line, warning.warning);
}
const opts: ExtractLintOptions = this.optsWithGlobals();
const extracted = await loading(
'Analyzing code...',
extractKeysOfFiles(patterns, opts.extractor)
);

let warningCount = 0;
let filesCount = 0;
for (const [file, { warnings }] of extracted) {
if (warnings.length) {
warningCount += warnings.length;
filesCount++;

emitGitHubWarning(warning.warning, file, warning.line);
const relFile = relative(process.cwd(), file);
console.log('%s:', relFile);
for (const warning of warnings) {
if (warning.warning in WarningMessages) {
const { name } = WarningMessages[warning.warning];
console.log('\tline %d: %s', warning.line, name);
} else {
console.log('\tline %d: %s', warning.line, warning.warning);
}

emitGitHubWarning(warning.warning, file, warning.line);
}
}
}
}

if (warningCount !== 0) {
console.log();
console.log(
'Total: %d warning%s in %d file%s',
warningCount,
warningCount !== 1 ? 's' : '',
filesCount,
filesCount !== 1 ? 's' : ''
);
process.exit(1);
}
if (warningCount !== 0) {
console.log();
console.log(
'Total: %d warning%s in %d file%s',
warningCount,
warningCount !== 1 ? 's' : '',
filesCount,
filesCount !== 1 ? 's' : ''
);
process.exit(1);
}

console.log('No issues found.');
}
console.log('No issues found.');
};

export default new Command('check')
.description(
'Checks if the keys can be extracted automatically, and reports problems if any'
)
.addArgument(FILE_PATTERNS)
.action(lintHandler);
export default (config: Schema) =>
new Command('check')
.description(
'Checks if the keys can be extracted automatically, and reports problems if any'
)
.addArgument(FILE_PATTERNS)
.action(lintHandler(config));
114 changes: 62 additions & 52 deletions src/commands/extract/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,79 @@ import { Command } from 'commander';

import { extractKeysOfFiles } from '../../extractor/runner.js';
import { WarningMessages } from '../../extractor/warnings.js';
import { loading } from '../../utils/logger.js';
import { error, loading } from '../../utils/logger.js';
import { FILE_PATTERNS } from '../../arguments.js';
import { Schema } from '../../schema.js';

type ExtractPrintOptions = BaseExtractOptions;

async function printHandler(this: Command, filesPatterns: string[]) {
const opts: ExtractPrintOptions = this.optsWithGlobals();
const extracted = await loading(
'Analyzing code...',
extractKeysOfFiles(filesPatterns, opts.extractor)
);
const printHandler = (config: Schema) =>
async function (this: Command, filesPatterns: string[]) {
const patterns = filesPatterns.length ? filesPatterns : config.patterns;

let warningCount = 0;
const keySet = new Set();
for (const [file, { keys, warnings }] of extracted) {
if (keys.length) {
const relFile = relative(process.cwd(), file);
console.log(
'%d key%s found in %s:',
keys.length,
keys.length !== 1 ? 's' : '',
relFile
);
for (const key of keys) {
keySet.add(key);
console.log('\tline %d: %s', key.line, key.keyName);
if (key.namespace) {
console.log('\t\tnamespace: %s', key.namespace);
}
if (key.defaultValue) {
console.log('\t\tdefault: %s', key.defaultValue);
if (!patterns?.length) {
error('Missing argument <patterns>');
process.exit(1);
}

const opts: ExtractPrintOptions = this.optsWithGlobals();
const extracted = await loading(
'Analyzing code...',
extractKeysOfFiles(patterns, opts.extractor)
);

let warningCount = 0;
const keySet = new Set();
for (const [file, { keys, warnings }] of extracted) {
if (keys.length) {
const relFile = relative(process.cwd(), file);
console.log(
'%d key%s found in %s:',
keys.length,
keys.length !== 1 ? 's' : '',
relFile
);
for (const key of keys) {
keySet.add(key);
console.log('\tline %d: %s', key.line, key.keyName);
if (key.namespace) {
console.log('\t\tnamespace: %s', key.namespace);
}
if (key.defaultValue) {
console.log('\t\tdefault: %s', key.defaultValue);
}
}
}
}

if (warnings.length) {
warningCount += warnings.length;
console.log(
'%d warning%s %s emitted during extraction:',
warnings.length,
warnings.length !== 1 ? 's' : '',
warnings.length !== 1 ? 'were' : 'was'
);
for (const warning of warnings) {
if (warning.warning in WarningMessages) {
const { name } = WarningMessages[warning.warning];
console.log('\tline %d: %s', warning.line, name);
} else {
console.log('\tline %d: %s', warning.line, warning.warning);
if (warnings.length) {
warningCount += warnings.length;
console.log(
'%d warning%s %s emitted during extraction:',
warnings.length,
warnings.length !== 1 ? 's' : '',
warnings.length !== 1 ? 'were' : 'was'
);
for (const warning of warnings) {
if (warning.warning in WarningMessages) {
const { name } = WarningMessages[warning.warning];
console.log('\tline %d: %s', warning.line, name);
} else {
console.log('\tline %d: %s', warning.line, warning.warning);
}
}
}
}

if (keys.length || warnings.length) {
console.log();
if (keys.length || warnings.length) {
console.log();
}
}
}

console.log('Total unique keys found: %d', keySet.size);
console.log('Total warnings: %d', warningCount);
}
console.log('Total unique keys found: %d', keySet.size);
console.log('Total warnings: %d', warningCount);
};

export default new Command('print')
.description('Prints extracted data to the console')
.addArgument(FILE_PATTERNS)
.action(printHandler);
export default (config: Schema) =>
new Command('print')
.description('Prints extracted data to the console')
.addArgument(FILE_PATTERNS)
.action(printHandler(config));
Loading

0 comments on commit aa76508

Please sign in to comment.