git-spark
Version:
Git repository analytics and reporting tool for analyzing commit patterns and contributor activity
476 lines • 17.7 kB
JavaScript
;
/**
* git-spark: Enterprise-grade Git repository analytics and reporting tool
* Main entry point for the library
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitSpark = void 0;
exports.analyze = analyze;
exports.exportReport = exportReport;
__exportStar(require("./types"), exports);
__exportStar(require("./core/analyzer"), exports);
__exportStar(require("./core/collector"), exports);
__exportStar(require("./utils/git"), exports);
__exportStar(require("./utils/logger"), exports);
__exportStar(require("./utils/validation"), exports);
const analyzer_1 = require("./core/analyzer");
const validation_1 = require("./utils/validation");
const logger_1 = require("./utils/logger");
const logger = (0, logger_1.createLogger)('git-spark');
/**
* Main GitSpark class for enterprise-grade Git repository analysis
*
* Provides a high-level interface for analyzing Git repositories and generating
* comprehensive reports. Handles the complete analysis pipeline from data
* collection through export in multiple formats.
*
* Key features:
* - Comprehensive commit and author analysis
* - Risk assessment and governance scoring
* - Multiple export formats (HTML, JSON, Markdown, CSV, Console)
* - Progress tracking for long-running operations
* - Extensive configuration options and validation
* - Enterprise-grade error handling and logging
*
* @example
* ```typescript
* // Basic analysis
* const gitSpark = new GitSpark({
* repoPath: '/path/to/repo',
* since: '2024-01-01'
* });
*
* const report = await gitSpark.analyze();
* await gitSpark.export('html', './reports');
*
* // With progress tracking
* const gitSpark = new GitSpark({
* repoPath: '/path/to/repo'
* }, (progress) => {
* console.log(`${progress.stage}: ${progress.percentage}%`);
* });
* ```
*/
class GitSpark {
constructor(options, progressCallback) {
// Validate options
const validation = (0, validation_1.validateOptions)(options);
if (!validation.isValid) {
throw new Error(`Invalid options: ${validation.errors.join(', ')}`);
}
this.options = { ...options };
this.analyzer = new analyzer_1.GitAnalyzer(options.repoPath || process.cwd(), progressCallback);
logger.info('GitSpark initialized', { options: this.options });
}
/**
* Perform complete repository analysis
*/
async analyze() {
logger.info('Starting repository analysis');
try {
const report = await this.analyzer.analyze(this.options);
logger.info('Analysis completed successfully', {
commits: report.repository.totalCommits,
authors: report.repository.totalAuthors,
files: report.repository.totalFiles,
});
return report;
}
catch (error) {
logger.error('Analysis failed', {
error: error instanceof Error
? {
message: error.message,
name: error.name,
stack: error.stack,
}
: error,
});
throw error;
}
}
/**
* Export analysis report in specified format
*/
async export(format, outputPath) {
const report = await this.analyze();
switch (format) {
case 'html':
await this.exportHTML(report, outputPath);
break;
case 'json':
await this.exportJSON(report, outputPath);
break;
case 'markdown':
await this.exportMarkdown(report, outputPath);
break;
case 'csv':
await this.exportCSV(report, outputPath);
break;
case 'console':
this.exportConsole(report);
break;
default:
throw new Error(`Unsupported format: ${format}`);
}
}
/**
* Export as HTML report
*/
async exportHTML(report, outputPath) {
const { HTMLExporter } = await Promise.resolve().then(() => __importStar(require('./output/html')));
const exporter = new HTMLExporter();
const defaultConfig = GitSpark.getDefaultConfig();
await exporter.export(report, outputPath, defaultConfig.output.fileFiltering);
logger.info('HTML report exported', { outputPath });
}
/**
* Export as JSON
*/
async exportJSON(report, outputPath) {
const { JSONExporter } = await Promise.resolve().then(() => __importStar(require('./output/json')));
const exporter = new JSONExporter();
await exporter.export(report, outputPath);
logger.info('JSON report exported', { outputPath });
}
/**
* Export as Markdown
*/
async exportMarkdown(report, outputPath) {
const { MarkdownExporter } = await Promise.resolve().then(() => __importStar(require('./output/markdown')));
const exporter = new MarkdownExporter();
await exporter.export(report, outputPath);
logger.info('Markdown report exported', { outputPath });
}
/**
* Export as CSV
*/
async exportCSV(report, outputPath) {
const { CSVExporter } = await Promise.resolve().then(() => __importStar(require('./output/csv')));
const exporter = new CSVExporter();
await exporter.export(report, outputPath);
logger.info('CSV report exported', { outputPath });
}
/**
* Export to console
*/
exportConsole(report) {
const { ConsoleExporter } = require('./output/console');
const exporter = new ConsoleExporter();
exporter.export(report);
logger.info('Console report displayed');
}
/**
* Get default configuration
*/
static getDefaultConfig() {
return {
version: '1.0',
analysis: {
excludePaths: ['node_modules/**', 'dist/**', 'build/**', '.git/**'],
includeAuthors: [],
excludeAuthors: [],
thresholds: {
largeCommitLines: 500,
smallCommitLines: 50,
staleBranchDays: 30,
largeFileKB: 300,
hotspotAuthorThreshold: 3,
},
weights: {
risk: {
churn: 0.35,
recency: 0.25,
ownership: 0.2,
entropy: 0.1,
coupling: 0.1,
},
governance: {
conventional: 0.4,
traceability: 0.25,
length: 0.15,
wipPenalty: 0.1,
revertPenalty: 0.05,
shortPenalty: 0.05,
},
},
},
output: {
defaultFormat: 'html',
outputDir: './reports',
includeCharts: true,
redactEmails: false,
theme: 'default',
fileFiltering: {
sourceCodeExtensions: [
// Web languages
'.js',
'.jsx',
'.ts',
'.tsx',
'.vue',
'.svelte',
'.css',
'.scss',
'.sass',
'.less',
// Backend/System languages
'.cs',
'.vb',
'.fs', // .NET
'.java',
'.kt',
'.scala', // JVM
'.py',
'.pyx', // Python
'.rb',
'.rake', // Ruby
'.php',
'.php3',
'.php4',
'.php5',
'.php7',
'.php8', // PHP
'.go', // Go
'.rs', // Rust
'.cpp',
'.cxx',
'.cc',
'.c', // C/C++
'.h',
'.hpp',
'.hxx', // C/C++ headers
'.swift', // Swift
'.m',
'.mm', // Objective-C
'.dart', // Dart
'.ex',
'.exs', // Elixir
'.erl',
'.hrl', // Erlang
'.clj',
'.cljs',
'.cljc', // Clojure
'.hs',
'.lhs', // Haskell
'.ml',
'.mli', // OCaml/F#
'.elm', // Elm
'.lua', // Lua
'.r',
'.rmd', // R
'.jl', // Julia
'.zig', // Zig
'.nim', // Nim
'.cr', // Crystal
// Database and query languages
'.sql',
'.plsql',
'.psql',
// Scripting
'.sh',
'.bash',
'.zsh',
'.fish',
'.ps1',
'.bat',
'.cmd',
'.pl',
'.pm', // Perl
'.tcl', // Tcl
// Graphics and markup languages (source code context)
'.xml',
'.xaml',
'.graphql',
'.gql',
// Template languages
'.mustache',
'.hbs',
'.handlebars',
'.pug',
'.jade',
'.ejs',
'.erb',
'.twig',
'.liquid',
'.jinja',
'.jinja2',
],
configExtensions: [
// Configuration and data files
'.html',
'.htm', // Often templates/config in backends
'.json', // Config files, package files
'.yaml',
'.yml', // Config files
'.toml', // Config files
'.ini',
'.conf',
'.config', // Config files
'.env', // Environment files
'.properties', // Java properties
'.plist', // macOS property lists
// Documentation and markdown
'.md',
'.markdown',
'.mdx',
'.txt',
'.rst',
'.adoc',
'.asciidoc',
// Build and project files
'.gradle',
'.maven',
'.gemfile',
'.podfile',
'.dockerfile',
'.containerfile',
],
excludePatterns: [
// Lock files and package files that change frequently but aren't source
'package-lock.json',
'yarn.lock',
'pnpm-lock.yaml',
'composer.lock',
'pipfile.lock',
'poetry.lock',
'requirements.txt',
// Build outputs and artifacts
'/dist/',
'/build/',
'/out/',
'/target/',
'/bin/',
'/obj/',
'.min.js',
'.min.css',
'.bundle.js',
'.bundle.css',
'.map',
// Node modules and dependencies
'node_modules/',
'vendor/',
// Configuration files that change frequently
'.gitignore',
'.gitattributes',
'.editorconfig',
'.eslintrc',
'.prettierrc',
'tsconfig.json',
'jsconfig.json',
'webpack.config',
'vite.config',
'rollup.config',
'babel.config',
'.babelrc',
'jest.config',
'vitest.config',
'karma.conf',
'cypress.config',
'playwright.config',
// Documentation directories
'/docs/',
'changelog',
'license',
'readme',
// IDE and editor files
'.vscode/',
'.idea/',
'.vs/',
'*.sln',
'*.csproj',
'*.vcxproj',
'*.proj',
// Generated files
'.generated.',
'.g.cs',
'.g.ts',
'.designer.cs',
'assemblyinfo.cs',
// Test files (focus on production code)
'.test.',
'.spec.',
'__tests__/',
'/tests/',
'/test/',
],
maxHotspots: 10,
},
},
performance: {
maxBuffer: 200,
enableCaching: true,
cacheDir: '.git-spark-cache',
chunkSize: 1000,
},
};
}
}
exports.GitSpark = GitSpark;
/**
* Quick analysis function for simple use cases
*/
async function analyze(repoPath, options) {
const gitSpark = new GitSpark({
repoPath: repoPath || process.cwd(),
...options,
});
return gitSpark.analyze();
}
/**
* Quick export function
*/
async function exportReport(report, format, outputPath) {
// const gitSpark = new GitSpark({ repoPath: process.cwd() });
// This is a simplified export that doesn't re-analyze
switch (format) {
case 'html':
const { HTMLExporter } = await Promise.resolve().then(() => __importStar(require('./output/html')));
const defaultConfig = GitSpark.getDefaultConfig();
await new HTMLExporter().export(report, outputPath, defaultConfig.output.fileFiltering);
break;
case 'json':
const { JSONExporter } = await Promise.resolve().then(() => __importStar(require('./output/json')));
await new JSONExporter().export(report, outputPath);
break;
default:
throw new Error(`Format ${format} not supported in quick export`);
}
}
//# sourceMappingURL=index.js.map