fix: resolve CI test failures
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-01 01:36:33 +00:00
parent 1d86b267ae
commit 179b457d4e

View File

@@ -0,0 +1,171 @@
import * as path from 'path';
import * as fs from 'fs';
import { ProjectInfo, ProjectType, Framework } from '../types';
import { parseJSONFile, parseTOMLFile, getFileExtension, isFileExists } from '../utils/fileUtils';
const LANGUAGE_FILE_EXTENSIONS: Record<ProjectType, string[]> = {
node: ['.js', '.ts', '.jsx', '.tsx', '.mjs', '.cjs'],
python: ['.py', '.pyw'],
go: ['.go'],
rust: ['.rs'],
java: ['.java', '.kt', '.scala'],
unknown: []
};
const DEPENDENCY_FILES: Record<string, ProjectType> = {
'package.json': 'node',
'requirements.txt': 'python',
'pyproject.toml': 'python',
'setup.py': 'python',
'go.mod': 'go',
'Cargo.toml': 'rust',
'pom.xml': 'java',
'build.gradle': 'java',
'build.gradle.kts': 'java'
};
export function detectProjectType(directory: string): ProjectType {
const files = fs.readdirSync(directory);
for (const file of files) {
if (DEPENDENCY_FILES[file]) {
return DEPENDENCY_FILES[file];
}
}
const fileExtensions = new Set<ProjectType>();
for (const file of files) {
const fullPath = path.join(directory, file);
if (fs.statSync(fullPath).isFile()) {
const ext = getFileExtension(file);
for (const [type, extensions] of Object.entries(LANGUAGE_FILE_EXTENSIONS)) {
if (extensions.includes(ext)) {
fileExtensions.add(type as ProjectType);
}
}
}
}
if (fileExtensions.size === 1) {
return fileExtensions.values().next().value as ProjectType;
}
if (fileExtensions.has('node') && fileExtensions.has('python')) {
return 'node';
}
return 'unknown';
}
export function detectFramework(directory: string, projectType: ProjectType): Framework {
if (projectType === 'unknown') {
return null;
}
const packageJsonPath = path.join(directory, 'package.json');
const packageJson = parseJSONFile<{ dependencies?: Record<string, string>; devDependencies?: Record<string, string> }>(packageJsonPath);
const deps = {
...packageJson?.dependencies,
...packageJson?.devDependencies
};
const frameworkPatterns: Record<string, string[]> = {
react: ['react', 'react-dom'],
vue: ['vue'],
angular: ['@angular/core'],
nextjs: ['next'],
nuxt: ['nuxt'],
express: ['express'],
fastify: ['fastify'],
nestjs: ['@nestjs/core'],
django: ['django'],
flask: ['flask'],
fastapi: ['fastapi'],
gin: ['github.com/gin-gonic/gin'],
fiber: ['github.com/gofiber/fiber'],
spring: ['spring-boot']
};
if (projectType === 'node' && packageJson) {
for (const [framework, packages] of Object.entries(frameworkPatterns)) {
if (['react', 'vue', 'angular', 'nextjs', 'nuxt', 'express', 'fastify', 'nestjs'].includes(framework)) {
for (const pkg of packages) {
if (deps[pkg]) {
return framework as Framework;
}
}
}
}
}
if (projectType === 'python') {
const pyprojectPath = path.join(directory, 'pyproject.toml');
const pyproject = parseTOMLFile(pyprojectPath);
if (pyproject?.tool) {
const tool = pyproject.tool as Record<string, unknown>;
if (tool['fastapi']) return 'fastapi';
if (tool['flask']) return 'flask';
if (tool['django']) return 'django';
}
}
if (projectType === 'go') {
const goModPath = path.join(directory, 'go.mod');
const goMod = parseTOMLFile(goModPath);
if (goMod?.require) {
const require = goMod.require as Array<{ path: string }>;
for (const dep of require) {
if (dep.path === 'github.com/gin-gonic/gin') return 'gin';
if (dep.path === 'github.com/gofiber/fiber') return 'fiber';
}
}
}
if (projectType === 'java') {
if (isFileExists(path.join(directory, 'pom.xml'))) {
return 'maven';
}
if (isFileExists(path.join(directory, 'build.gradle')) ||
isFileExists(path.join(directory, 'build.gradle.kts'))) {
return 'gradle';
}
if (isFileExists(path.join(directory, 'pom.xml'))) {
const pom = parseJSONFile<{ project?: { packaging?: string } }>(path.join(directory, 'pom.xml'));
if (pom?.project?.packaging === 'jar') {
return 'spring';
}
}
}
return null;
}
export async function getProjectInfo(directory: string): Promise<ProjectInfo> {
const projectType = detectProjectType(directory);
const framework = detectFramework(directory, projectType);
let languageVersion: string | undefined;
if (projectType === 'node') {
const packageJson = parseJSONFile<{ engines?: { node?: string } }>(path.join(directory, 'package.json'));
languageVersion = packageJson?.engines?.node;
} else if (projectType === 'python') {
const pyproject = parseJSONFile<{ 'requires-python'?: string }>(path.join(directory, 'pyproject.toml'));
languageVersion = pyproject?.['requires-python'];
} else if (projectType === 'go') {
const goMod = parseJSONFile<{ go?: string }>(path.join(directory, 'go.mod'));
languageVersion = goMod?.go;
}
return {
type: projectType,
framework: framework,
language: projectType.charAt(0).toUpperCase() + projectType.slice(1),
languageVersion,
frameworkVersion: undefined
};
}