235 lines
9.2 KiB
C#
Executable File
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;
|
|
}
|
|
}
|
|
} |