what-is-my-tech-stack
Version:
Analyze project dependencies and generate a human-readable tech stack description
124 lines • 4.11 kB
JavaScript
import { FileReader } from '../utils/fileReader.js';
export class PythonAnalyzer {
requirementsPath;
constructor(requirementsPath) {
this.requirementsPath = requirementsPath;
}
/**
* Analyzes the requirements.txt file and returns a list of dependencies
*/
async analyze() {
try {
const requirements = await FileReader.readRequirementsTxt(this.requirementsPath);
return requirements.map((line) => this.parseDependency(line));
}
catch (error) {
process.stderr.write(`Error analyzing requirements.txt: ${error.message}\n`);
return [];
}
}
/**
* Parses a single requirement line into a PythonDependency object
*/
parseDependency(line) {
// Match patterns like:
// package==1.0.0
// package>=1.0.0
// package<=1.0.0
// package~=1.0.0
// package!=1.0.0
// package
const pattern = /^([a-zA-Z0-9-_.]+)(?:([<>=!~]=|[<>])(.+))?$/;
const match = line.match(pattern);
if (!match) {
return {
name: line,
version: '',
};
}
const [, name, constraint, version] = match;
return {
name,
version: version || '',
constraint: constraint || undefined,
};
}
/**
* Categorizes dependencies into common tech categories
*/
categorizeDependencies(dependencies) {
const categories = {
web_framework: [],
testing: [],
database: [],
async: [],
data_science: [],
utilities: [],
other: [],
};
dependencies.forEach((dep) => {
const name = dep.name.toLowerCase();
if (this.isWebFramework(name)) {
categories.web_framework.push(dep.name);
}
else if (this.isTestingTool(name)) {
categories.testing.push(dep.name);
}
else if (this.isDatabase(name)) {
categories.database.push(dep.name);
}
else if (this.isAsync(name)) {
categories.async.push(dep.name);
}
else if (this.isDataScience(name)) {
categories.data_science.push(dep.name);
}
else if (this.isUtility(name)) {
categories.utilities.push(dep.name);
}
else {
categories.other.push(dep.name);
}
});
// Remove empty categories
Object.keys(categories).forEach((key) => {
if (categories[key].length === 0) {
delete categories[key];
}
});
return categories;
}
isWebFramework(name) {
const frameworks = ['django', 'flask', 'fastapi', 'pyramid', 'tornado', 'aiohttp', 'sanic'];
return frameworks.some((framework) => name.includes(framework));
}
isTestingTool(name) {
const testingTools = ['pytest', 'unittest', 'nose', 'coverage', 'tox', 'mock'];
return testingTools.some((tool) => name.includes(tool));
}
isDatabase(name) {
const databases = ['sqlalchemy', 'django-orm', 'psycopg2', 'pymongo', 'redis', 'peewee'];
return databases.some((db) => name.includes(db));
}
isAsync(name) {
const async = ['asyncio', 'aiohttp', 'celery', 'dramatiq', 'rq'];
return async.some((pkg) => name.includes(pkg));
}
isDataScience(name) {
const dataScienceTools = [
'numpy',
'pandas',
'scipy',
'scikit-learn',
'tensorflow',
'pytorch',
'matplotlib',
];
return dataScienceTools.some((tool) => name.includes(tool));
}
isUtility(name) {
const utilities = ['requests', 'click', 'pyyaml', 'python-dotenv', 'pillow', 'beautifulsoup4'];
return utilities.some((utility) => name.includes(utility));
}
}
//# sourceMappingURL=pythonAnalyzer.js.map