use anyhow::Result;
use aven_core::db::Database;
use serde::Serialize;
use crate::cli::{ProjectCommand, ProjectListArgs, ProjectPathSubcommand, ProjectSubcommand};
use crate::operations::{
add_project_path_operation, create_project_operation, delete_project_operation,
list_project_paths_operation, remove_project_path_operation, rename_project_operation,
};
use crate::render::{changed_text, quote};
use crate::workspaces::Workspace;
pub(crate) async fn cmd_project(
database: &Database,
workspace: &Workspace,
args: ProjectCommand,
) -> Result<()> {
match args.command {
ProjectSubcommand::Create { name, path } => {
let outcome =
create_project_operation(database, workspace, &name, path.as_deref()).await?;
let project = outcome.project;
println!(
"created-project {} prefix={} name={}",
project.key,
project.prefix,
quote(&project.name)
);
}
ProjectSubcommand::Delete { project } => {
let outcome = delete_project_operation(database, workspace, &project).await?;
println!(
"deleted-project {} prefix={} name={}",
outcome.project.key,
outcome.project.prefix,
quote(&outcome.project.name)
);
}
ProjectSubcommand::List(args) => cmd_projects(database, workspace, args).await?,
ProjectSubcommand::Rename {
project,
new_name,
prefix,
} => {
let outcome = rename_project_operation(
database,
workspace,
&project,
&new_name,
prefix.as_deref(),
)
.await?;
println!(
"renamed-project {} changed={} old={} old_prefix={} prefix={} name={}",
outcome.project.key,
changed_text(outcome.changed),
outcome.previous.key,
outcome.previous.prefix,
outcome.project.prefix,
quote(&outcome.project.name)
);
if outcome.changed && outcome.config_mapping {
println!("updated-config-project-mapping {}", outcome.project.key);
}
}
ProjectSubcommand::Path { command } => match command {
ProjectPathSubcommand::Add { project, path } => {
let outcome =
add_project_path_operation(database, workspace, &project, &path).await?;
println!(
"added-project-path {} path={} config={}",
outcome.project.key,
quote(&outcome.path),
quote(&outcome.config_path.display().to_string())
);
}
ProjectPathSubcommand::Remove { project, path } => {
let outcome =
remove_project_path_operation(database, workspace, &project, &path).await?;
println!(
"removed-project-path {} path={} config={}",
outcome.project.key,
quote(&outcome.path),
quote(&outcome.config_path.display().to_string())
);
}
ProjectPathSubcommand::List { project } => {
let paths =
list_project_paths_operation(database, workspace, project.as_deref()).await?;
for item in paths {
println!("{} path={}", item.project.key, quote(&item.path));
}
}
},
}
Ok(())
}
#[derive(Serialize)]
struct ProjectListJsonItem {
key: String,
name: String,
prefix: String,
}
async fn cmd_projects(
database: &Database,
workspace: &Workspace,
args: ProjectListArgs,
) -> Result<()> {
let mut projects = database
.list_projects(&workspace.id, args.search.as_deref())
.await?;
if let Some(limit) = args.limit {
projects.truncate(limit);
}
if args.json {
let items: Vec<ProjectListJsonItem> = projects
.into_iter()
.map(|p| ProjectListJsonItem {
key: p.key,
name: p.name,
prefix: p.prefix,
})
.collect();
serde_json::to_writer_pretty(std::io::stdout(), &items)?;
println!();
} else {
for project in projects {
println!(
"{} prefix={} name={}",
project.key,
project.prefix,
quote(&project.name)
);
}
}
Ok(())
}