use anyhow::{anyhow, Result};
use clap::Subcommand;
use console::style;
use crate::registry::Registry;
use crate::state::State;
#[derive(Subcommand)]
pub enum ProjectsCmd {
List,
Forget { name: String },
}
pub fn run(cmd: ProjectsCmd) -> Result<()> {
match cmd {
ProjectsCmd::List => list(),
ProjectsCmd::Forget { name } => forget(name),
}
}
fn list() -> Result<()> {
let reg = Registry::load()?;
let state = State::load()?;
let active = state.active_project.as_deref();
if reg.projects.is_empty() {
println!("{}", style("No projects registered.").yellow());
println!();
println!(
" Create one with: {}",
style("devist init <name> --template=<t>").cyan()
);
return Ok(());
}
println!("{}", style("Registered projects").bold());
println!();
for p in ®.projects {
let active_marker = if Some(p.name.as_str()) == active {
style("● ").green().to_string()
} else {
" ".to_string()
};
println!(
"{}{} {}",
active_marker,
style(format!("{:20}", p.name)).cyan(),
style(format!("[{}]", p.template)).dim()
);
println!(" {}", style(p.path.display()).dim());
println!(" {}", style(format!("created {}", p.created_at)).dim());
}
println!();
if active.is_some() {
println!(" {} = active backend", style("●").green());
}
Ok(())
}
fn forget(name: String) -> Result<()> {
let mut reg = Registry::load()?;
if !reg.remove(&name) {
return Err(anyhow!("Project not found in registry: {}", name));
}
reg.save()?;
let mut state = State::load()?;
if state.active_project.as_deref() == Some(&name) {
state.set_active(None);
state.save()?;
}
println!(" {} {}", style("[FORGOTTEN]").green(), name);
println!(" {}", style("(project files on disk are untouched)").dim());
Ok(())
}