127 lines
No EOL
4.6 KiB
TypeScript
127 lines
No EOL
4.6 KiB
TypeScript
#!/usr/bin/env bun
|
|
import { Command } from 'commander';
|
|
import { existsSync } from 'fs';
|
|
import { resolve } from 'path';
|
|
import chalk from 'chalk';
|
|
import { loadConfig } from './config';
|
|
import { CoverageRunner } from './runner';
|
|
import { CoverageProcessor } from './processor';
|
|
import { ReporterManager } from './reporters';
|
|
import type { CLIOptions } from './types';
|
|
|
|
const program = new Command();
|
|
|
|
program
|
|
.name('stock-bot-coverage')
|
|
.description('Advanced coverage tool for Stock Bot with exclusion support and beautiful reporting')
|
|
.version('1.0.0')
|
|
.option('-p, --packages <packages...>', 'Run coverage for specific packages')
|
|
.option('-e, --exclude <patterns...>', 'Glob patterns to exclude from coverage')
|
|
.option('-i, --include <patterns...>', 'Glob patterns to include in coverage')
|
|
.option('-r, --reporters <reporters...>', 'Coverage reporters (terminal, html, json, markdown, text)')
|
|
.option('-t, --threshold <number>', 'Set coverage threshold for all metrics', parseFloat)
|
|
.option('--threshold-lines <number>', 'Set line coverage threshold', parseFloat)
|
|
.option('--threshold-functions <number>', 'Set function coverage threshold', parseFloat)
|
|
.option('--threshold-branches <number>', 'Set branch coverage threshold', parseFloat)
|
|
.option('--threshold-statements <number>', 'Set statement coverage threshold', parseFloat)
|
|
.option('-o, --output-dir <path>', 'Output directory for reports')
|
|
.option('-c, --config <path>', 'Path to coverage config file')
|
|
.option('--fail-under', 'Exit with non-zero code if coverage is below threshold')
|
|
.action(async (options: CLIOptions) => {
|
|
try {
|
|
console.log(chalk.bold.blue('\n🚀 Stock Bot Coverage Tool\n'));
|
|
|
|
// Load configuration
|
|
const config = loadConfig(options);
|
|
console.log(chalk.gray('Configuration loaded'));
|
|
console.log(chalk.gray(`Workspace root: ${config.workspaceRoot}`));
|
|
console.log(chalk.gray(`Excluded patterns: ${config.exclude.length}`));
|
|
console.log(chalk.gray(`Reporters: ${config.reporters.join(', ')}\n`));
|
|
|
|
// Run coverage
|
|
const runner = new CoverageRunner(config);
|
|
console.log(chalk.yellow('Running tests with coverage...\n'));
|
|
|
|
const result = await runner.run();
|
|
|
|
if (!result.success) {
|
|
console.error(chalk.red('\n❌ Some tests failed'));
|
|
if (options.failUnder) {
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Process coverage data
|
|
const processor = new CoverageProcessor(config);
|
|
const report = processor.process(result.coverage, result.testResults);
|
|
|
|
// Generate reports
|
|
console.log(chalk.yellow('\nGenerating reports...\n'));
|
|
const reporterManager = new ReporterManager();
|
|
await reporterManager.report(report, config.reporters, config.outputDir);
|
|
|
|
// Check thresholds
|
|
if (options.failUnder) {
|
|
const thresholdResult = processor.checkThresholds(report);
|
|
if (!thresholdResult.passed) {
|
|
console.error(chalk.red('\n❌ Coverage thresholds not met'));
|
|
for (const failure of thresholdResult.failures) {
|
|
console.error(
|
|
chalk.red(
|
|
` ${failure.metric}: ${failure.actual.toFixed(1)}% < ${failure.expected}%`
|
|
)
|
|
);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
console.log(chalk.green('\n✅ Coverage analysis complete!\n'));
|
|
} catch (error) {
|
|
console.error(chalk.red('\n❌ Error running coverage:'), error);
|
|
process.exit(1);
|
|
}
|
|
});
|
|
|
|
// Add init command to create default config
|
|
program
|
|
.command('init')
|
|
.description('Create a default .coveragerc.json configuration file')
|
|
.action(() => {
|
|
const configPath = resolve(process.cwd(), '.coveragerc.json');
|
|
|
|
if (existsSync(configPath)) {
|
|
console.error(chalk.red('Configuration file already exists'));
|
|
process.exit(1);
|
|
}
|
|
|
|
const defaultConfig = {
|
|
exclude: [
|
|
'**/node_modules/**',
|
|
'**/dist/**',
|
|
'**/build/**',
|
|
'**/coverage/**',
|
|
'**/*.test.ts',
|
|
'**/*.test.js',
|
|
'**/*.spec.ts',
|
|
'**/*.spec.js',
|
|
'**/test/**',
|
|
'**/tests/**',
|
|
'**/__tests__/**',
|
|
'**/__mocks__/**',
|
|
],
|
|
reporters: ['terminal', 'html'],
|
|
thresholds: {
|
|
lines: 80,
|
|
functions: 80,
|
|
branches: 80,
|
|
statements: 80,
|
|
},
|
|
outputDir: 'coverage',
|
|
};
|
|
|
|
require('fs').writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
|
|
console.log(chalk.green(`✅ Created ${configPath}`));
|
|
});
|
|
|
|
program.parse(); |