MarketAlly.AIPlugin.Extensions/MarketAlly.ProjectDetector/ProjectFileLocator.cs

235 lines
9.2 KiB
C#
Executable File

using System;
using System.IO;
using System.Linq;
namespace MarketAlly.ProjectDetector
{
/// <summary>
/// Locates the best project or solution file to index/analyze in a given directory
/// </summary>
public static class ProjectFileLocator
{
/// <summary>
/// Finds the best file to index based on the project type
/// </summary>
public static string FindBestFileToIndex(string projectPath, ProjectType projectType, bool ignoreSolution)
{
if (!ignoreSolution)
{
// Look for solution files first (they're usually the best to index)
var solutionFiles = Directory.GetFiles(projectPath, "*.sln", SearchOption.TopDirectoryOnly);
if (solutionFiles.Any())
{
return Path.GetFullPath(solutionFiles.First());
}
}
// Based on project type, look for appropriate project files
switch (projectType)
{
// .NET project types
case ProjectType.API:
case ProjectType.WebApp:
case ProjectType.Library:
case ProjectType.Service:
case ProjectType.Tests:
case ProjectType.WpfApp:
case ProjectType.WinFormsApp:
case ProjectType.MobileApp:
case ProjectType.Function:
case ProjectType.Standalone:
case ProjectType.Tool:
case ProjectType.Plugin:
case ProjectType.ChatBot:
return FindDotNetProjectFile(projectPath) ?? projectPath;
// Node.js project types
case ProjectType.ReactApp:
case ProjectType.VueApp:
case ProjectType.AngularApp:
case ProjectType.NextJsApp:
case ProjectType.NodeJsApi:
case ProjectType.NodeJsApp:
case ProjectType.ElectronApp:
// For Node projects, the directory itself is usually the best option
// as package.json defines the project
return projectPath;
// Python project types
case ProjectType.DjangoApp:
case ProjectType.FlaskApp:
case ProjectType.PythonApp:
return FindPythonProjectFile(projectPath) ?? projectPath;
// Java project types
case ProjectType.JavaMavenProject:
return FindMavenProjectFile(projectPath) ?? projectPath;
case ProjectType.JavaGradleProject:
return FindGradleProjectFile(projectPath) ?? projectPath;
// Go projects
case ProjectType.GoApp:
var goMod = Path.Combine(projectPath, "go.mod");
return File.Exists(goMod) ? goMod : projectPath;
// Rust projects
case ProjectType.RustApp:
var cargoToml = Path.Combine(projectPath, "Cargo.toml");
return File.Exists(cargoToml) ? cargoToml : projectPath;
// Game development
case ProjectType.UnityProject:
// Unity projects are defined by the directory containing Assets folder
var assetsFolder = Path.Combine(projectPath, "Assets");
return Directory.Exists(assetsFolder) ? projectPath : projectPath;
case ProjectType.UnrealProject:
// Look for .uproject files
var uprojectFiles = Directory.GetFiles(projectPath, "*.uproject", SearchOption.TopDirectoryOnly);
return uprojectFiles.FirstOrDefault() ?? projectPath;
case ProjectType.GodotProject:
// Look for project.godot file
var godotProject = Path.Combine(projectPath, "project.godot");
return File.Exists(godotProject) ? projectPath : projectPath;
default:
// For unknown types, try to find any common project file
return FindAnyIndexableFile(projectPath, ignoreSolution);
}
}
/// <summary>
/// Finds any indexable file when project type is unknown or manually overridden
/// </summary>
public static string FindAnyIndexableFile(string projectPath, bool ignoreSolution)
{
// 1. Look for solution files first (highest priority)
if (!ignoreSolution)
{
var solutionFiles = Directory.GetFiles(projectPath, "*.sln", SearchOption.TopDirectoryOnly);
if (solutionFiles.Any())
{
return Path.GetFullPath(solutionFiles.First());
}
}
// 2. Look for .NET project files
var dotnetProject = FindDotNetProjectFile(projectPath);
if (dotnetProject != null)
{
return dotnetProject;
}
// 3. Check for package.json (Node.js projects)
var packageJson = Path.Combine(projectPath, "package.json");
if (File.Exists(packageJson))
{
return projectPath; // For Node projects, index the directory
}
// 4. Check for Python project files
var pythonProject = FindPythonProjectFile(projectPath);
if (pythonProject != null)
{
return pythonProject;
}
// 5. Check for Java project files
var mavenProject = FindMavenProjectFile(projectPath);
if (mavenProject != null)
{
return mavenProject;
}
var gradleProject = FindGradleProjectFile(projectPath);
if (gradleProject != null)
{
return gradleProject;
}
// 6. Check for Go modules
var goMod = Path.Combine(projectPath, "go.mod");
if (File.Exists(goMod))
{
return goMod;
}
// 7. Check for Rust projects
var cargoToml = Path.Combine(projectPath, "Cargo.toml");
if (File.Exists(cargoToml))
{
return cargoToml;
}
// 8. Check for requirements.txt (generic Python projects)
var requirementsTxt = Path.Combine(projectPath, "requirements.txt");
if (File.Exists(requirementsTxt))
{
return projectPath;
}
// Default: Just return the directory for analysis
return projectPath;
}
private static string? FindDotNetProjectFile(string projectPath)
{
var projectFiles = Directory.GetFiles(projectPath, "*.csproj", SearchOption.AllDirectories)
.Concat(Directory.GetFiles(projectPath, "*.vbproj", SearchOption.AllDirectories))
.Concat(Directory.GetFiles(projectPath, "*.fsproj", SearchOption.AllDirectories))
.OrderBy(f => f.Count(c => c == Path.DirectorySeparatorChar)) // Prefer files closer to root
.FirstOrDefault();
// Normalize the path if found
return projectFiles != null ? Path.GetFullPath(projectFiles) : null;
}
private static string? FindPythonProjectFile(string projectPath)
{
// Check for setup.py
var setupPy = Path.Combine(projectPath, "setup.py");
if (File.Exists(setupPy))
return setupPy;
// Check for pyproject.toml
var pyprojectToml = Path.Combine(projectPath, "pyproject.toml");
if (File.Exists(pyprojectToml))
return pyprojectToml;
// Check for setup.cfg
var setupCfg = Path.Combine(projectPath, "setup.cfg");
if (File.Exists(setupCfg))
return projectPath;
return null;
}
private static string? FindMavenProjectFile(string projectPath)
{
var pomFile = Directory.GetFiles(projectPath, "pom.xml", SearchOption.AllDirectories)
.OrderBy(f => f.Count(c => c == Path.DirectorySeparatorChar))
.FirstOrDefault();
return pomFile != null ? Path.GetFullPath(pomFile) : null;
}
private static string? FindGradleProjectFile(string projectPath)
{
var buildGradle = Directory.GetFiles(projectPath, "build.gradle", SearchOption.AllDirectories)
.OrderBy(f => f.Count(c => c == Path.DirectorySeparatorChar))
.FirstOrDefault();
if (buildGradle != null)
return Path.GetFullPath(buildGradle);
// Also check for build.gradle.kts (Kotlin DSL)
var buildGradleKts = Directory.GetFiles(projectPath, "build.gradle.kts", SearchOption.AllDirectories)
.OrderBy(f => f.Count(c => c == Path.DirectorySeparatorChar))
.FirstOrDefault();
return buildGradleKts != null ? Path.GetFullPath(buildGradleKts) : null;
}
}
}