use std::path::Path;
use colored::Colorize;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProjectType {
Docker,
DockerCompose,
Python,
NodeJs,
Rust,
Railway,
Go,
}
impl ProjectType {
pub fn name(&self) -> &str {
match self {
ProjectType::Docker => "Docker",
ProjectType::DockerCompose => "Docker Compose",
ProjectType::Python => "Python",
ProjectType::NodeJs => "Node.js",
ProjectType::Rust => "Rust",
ProjectType::Railway => "Railway",
ProjectType::Go => "Go",
}
}
pub fn icon(&self) -> &str {
match self {
ProjectType::Docker => "🐳",
ProjectType::DockerCompose => "🐋",
ProjectType::Python => "🐍",
ProjectType::NodeJs => "📦",
ProjectType::Rust => "🦀",
ProjectType::Railway => "🚂",
ProjectType::Go => "🔷",
}
}
}
pub fn detect_project_types(path: &Path) -> Vec<ProjectType> {
let mut types = Vec::new();
if path.join("Dockerfile").exists() {
types.push(ProjectType::Docker);
}
if path.join("docker-compose.yml").exists()
|| path.join("docker-compose.yaml").exists()
|| path.join("compose.yml").exists()
|| path.join("compose.yaml").exists() {
types.push(ProjectType::DockerCompose);
}
if path.join("requirements.txt").exists()
|| path.join("pyproject.toml").exists()
|| path.join("setup.py").exists() {
types.push(ProjectType::Python);
}
if path.join("package.json").exists() {
types.push(ProjectType::NodeJs);
}
if path.join("Cargo.toml").exists() {
types.push(ProjectType::Rust);
}
if path.join("railway.json").exists()
|| path.join("railway.toml").exists() {
types.push(ProjectType::Railway);
}
if path.join("go.mod").exists() {
types.push(ProjectType::Go);
}
types
}
pub fn suggest_commands(project_types: &[ProjectType]) -> Vec<String> {
let mut commands = Vec::new();
for project_type in project_types {
match project_type {
ProjectType::Docker => {
commands.push("docker build -t <image-name> .".to_string());
commands.push("docker run -p <port>:<port> <image-name>".to_string());
}
ProjectType::DockerCompose => {
commands.push("docker-compose up -d".to_string());
commands.push("docker-compose down".to_string());
}
ProjectType::Python => {
commands.push("pip install -r requirements.txt".to_string());
commands.push("python main.py".to_string());
}
ProjectType::NodeJs => {
commands.push("npm install".to_string());
commands.push("npm start".to_string());
}
ProjectType::Rust => {
commands.push("cargo build --release".to_string());
commands.push("cargo run".to_string());
}
ProjectType::Railway => {
commands.push("railway up".to_string());
commands.push("railway logs".to_string());
}
ProjectType::Go => {
commands.push("go build".to_string());
commands.push("go run .".to_string());
}
}
}
commands.dedup();
commands
}
pub fn display_project_types(project_types: &[ProjectType]) {
if project_types.is_empty() {
return;
}
let types_str = project_types
.iter()
.map(|t| format!("{} {}", t.icon(), t.name()))
.collect::<Vec<_>>()
.join(", ");
tracing::info!("{} {}", "Detected:".bright_blue(), types_str);
}
pub fn display_suggested_commands(project_types: &[ProjectType]) {
let commands = suggest_commands(project_types);
if commands.is_empty() {
return;
}
tracing::info!("{}", "Suggested commands:".bright_blue());
for cmd in commands.iter().take(3) {
tracing::info!(" {}", cmd.dimmed());
}
}