MarketAlly.AIPlugin.Extensions/MarketAlly.ProjectDetector/Detectors/LanguageDetectors.cs

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)
};
}
}