479 lines
16 KiB
C#
Executable File
479 lines
16 KiB
C#
Executable File
using System;
|
|
using System.Linq;
|
|
|
|
namespace MarketAlly.ProjectDetector.Detectors;
|
|
|
|
// Node.js Project Detectors
|
|
public class ReactProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.PackageJsonDependencies.ContainsKey("react") ||
|
|
analysis.PackageJsonDependencies.ContainsKey("react-dom"))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Has React dependencies");
|
|
}
|
|
|
|
if (analysis.PackageJsonDependencies.ContainsKey("react-scripts") ||
|
|
analysis.PackageJsonDependencies.ContainsKey("@vitejs/plugin-react") ||
|
|
analysis.PackageJsonDependencies.ContainsKey("next"))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Has React build tools");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.EndsWith(".jsx", StringComparison.OrdinalIgnoreCase) ||
|
|
f.EndsWith(".tsx", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains JSX/TSX files");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.ReactApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class VueProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.PackageJsonDependencies.ContainsKey("vue"))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Has Vue dependency");
|
|
}
|
|
|
|
if (analysis.PackageJsonDependencies.ContainsKey("@vue/cli-service") ||
|
|
analysis.PackageJsonDependencies.ContainsKey("vite") ||
|
|
analysis.PackageJsonDependencies.ContainsKey("nuxt"))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Has Vue build tools");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.EndsWith(".vue", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Contains Vue component files");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.VueApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class AngularProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.PackageJsonDependencies.ContainsKey("@angular/core") ||
|
|
analysis.PackageJsonDependencies.ContainsKey("@angular/common"))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Has Angular dependencies");
|
|
}
|
|
|
|
if (analysis.PackageJsonDevDependencies.ContainsKey("@angular/cli") ||
|
|
analysis.PackageJsonDevDependencies.ContainsKey("@angular-devkit/build-angular"))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Has Angular CLI/build tools");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("angular.json", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 40;
|
|
reasons.Add("Contains angular.json");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.AngularApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class NextJsProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.PackageJsonDependencies.ContainsKey("next"))
|
|
{
|
|
confidence += 80;
|
|
reasons.Add("Has Next.js dependency");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("next.config.js", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("next.config.mjs", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("next.config.ts", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 40;
|
|
reasons.Add("Contains Next.js configuration");
|
|
}
|
|
|
|
if (analysis.Folders.Any(f => f.Equals("pages", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("app", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains Next.js routing structure");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.NextJsApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class NodeJsApiProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
var apiPackages = new[] { "express", "fastify", "koa", "hapi", "@nestjs/core", "restify" };
|
|
if (apiPackages.Any(pkg => analysis.PackageJsonDependencies.ContainsKey(pkg)))
|
|
{
|
|
confidence += 60;
|
|
reasons.Add("Has Node.js API framework");
|
|
}
|
|
|
|
// API-related packages
|
|
var apiRelatedPackages = new[] { "cors", "helmet", "body-parser", "express-validator", "jsonwebtoken", "passport" };
|
|
if (apiRelatedPackages.Any(pkg => analysis.PackageJsonDependencies.ContainsKey(pkg)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Has API-related packages");
|
|
}
|
|
|
|
// API structure
|
|
if (analysis.Folders.Any(f => f.Equals("routes", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("controllers", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("api", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 25;
|
|
reasons.Add("Contains API folder structure");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 50,
|
|
ProjectType = ProjectType.NodeJsApi,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class NodeJsProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
// Generic Node.js project (fallback for Node projects)
|
|
if (analysis.Files.Any(f => f.Equals("package.json", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 40;
|
|
reasons.Add("Has package.json");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.EndsWith(".js", StringComparison.OrdinalIgnoreCase) ||
|
|
f.EndsWith(".ts", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains JavaScript/TypeScript files");
|
|
}
|
|
|
|
if (analysis.Folders.Any(f => f.Equals("node_modules", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 10;
|
|
reasons.Add("Has node_modules");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 30,
|
|
ProjectType = ProjectType.NodeJsApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
// Python Project Detectors
|
|
public class DjangoProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.PythonRequirements.Any(req => req.ToLowerInvariant().Contains("django")))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Has Django in requirements");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("manage.py", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 50;
|
|
reasons.Add("Contains manage.py");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("settings.py", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("urls.py", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("wsgi.py", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Contains Django configuration files");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.DjangoApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class FlaskProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.PythonRequirements.Any(req => req.ToLowerInvariant().Contains("flask")))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Has Flask in requirements");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("app.py", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("application.py", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Contains Flask app file");
|
|
}
|
|
|
|
if (analysis.Folders.Any(f => f.Equals("templates", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("static", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains Flask folder structure");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.FlaskApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class PythonProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.Files.Any(f => f.EndsWith(".py", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 40;
|
|
reasons.Add("Contains Python files");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("requirements.txt", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("setup.py", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("pyproject.toml", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Contains Python package files");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("__init__.py", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 10;
|
|
reasons.Add("Contains Python package marker");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 30,
|
|
ProjectType = ProjectType.PythonApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
// Java Project Detectors
|
|
public class JavaMavenProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.Files.Any(f => f.Equals("pom.xml", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 80;
|
|
reasons.Add("Contains pom.xml");
|
|
}
|
|
|
|
if (analysis.Folders.Any(f => f.Equals("src", StringComparison.OrdinalIgnoreCase)) &&
|
|
analysis.Folders.Any(f => f.Equals("target", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Has Maven folder structure");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.JavaMavenProject,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class JavaGradleProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.Files.Any(f => f.Equals("build.gradle", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("build.gradle.kts", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 80;
|
|
reasons.Add("Contains Gradle build file");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("settings.gradle", StringComparison.OrdinalIgnoreCase) ||
|
|
f.Equals("settings.gradle.kts", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains Gradle settings");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 60,
|
|
ProjectType = ProjectType.JavaGradleProject,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
// Other Language Detectors
|
|
public class GoProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.Files.Any(f => f.Equals("go.mod", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Contains go.mod");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.EndsWith(".go", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Contains Go files");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("go.sum", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains go.sum");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 50,
|
|
ProjectType = ProjectType.GoApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
}
|
|
|
|
public class RustProjectDetector : IProjectTypeDetector
|
|
{
|
|
public ProjectTypeDetectionResult Detect(ProjectAnalysis analysis)
|
|
{
|
|
var confidence = 0;
|
|
var reasons = new List<string>();
|
|
|
|
if (analysis.Files.Any(f => f.Equals("Cargo.toml", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 70;
|
|
reasons.Add("Contains Cargo.toml");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.EndsWith(".rs", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 30;
|
|
reasons.Add("Contains Rust files");
|
|
}
|
|
|
|
if (analysis.Files.Any(f => f.Equals("Cargo.lock", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
confidence += 20;
|
|
reasons.Add("Contains Cargo.lock");
|
|
}
|
|
|
|
return new ProjectTypeDetectionResult
|
|
{
|
|
IsMatch = confidence >= 50,
|
|
ProjectType = ProjectType.RustApp,
|
|
Confidence = Math.Min(confidence, 100),
|
|
Reason = string.Join(", ", reasons)
|
|
};
|
|
}
|
|
} |