Skip to main content

apm/cmd/
set.rs

1use anyhow::{bail, Result};
2use apm_core::{git, ticket, ticket_fmt};
3use chrono::Utc;
4use std::path::Path;
5use crate::ctx::CmdContext;
6
7pub fn run(root: &Path, id_arg: &str, field: String, value: String, no_aggressive: bool) -> Result<()> {
8    let ctx = CmdContext::load(root, no_aggressive)?;
9    let id = ticket::resolve_id_in_slice(&ctx.tickets, id_arg)?;
10    let mut tickets = ctx.tickets;
11
12    let Some(t) = tickets.iter_mut().find(|t| t.frontmatter.id == id) else {
13        bail!("ticket {id:?} not found");
14    };
15    if field == "owner" {
16        ticket::check_owner(root, t)?;
17        let local = apm_core::config::LocalConfig::load(root);
18        apm_core::validate::validate_owner(&ctx.config, &local, &value)?;
19    }
20    ticket::set_field(&mut t.frontmatter, &field, &value)?;
21    t.frontmatter.updated_at = Some(Utc::now());
22
23    let content = t.serialize()?;
24    let rel_path = format!(
25        "{}/{}",
26        ctx.config.tickets.dir.to_string_lossy(),
27        t.path.file_name().unwrap().to_string_lossy()
28    );
29    let branch = t
30        .frontmatter
31        .branch
32        .clone()
33        .or_else(|| ticket_fmt::branch_name_from_path(&t.path))
34        .unwrap_or_else(|| format!("ticket/{id}"));
35
36    git::commit_to_branch(
37        root,
38        &branch,
39        &rel_path,
40        &content,
41        &format!("ticket({id}): set {field} = {value}"),
42    )?;
43
44    if ctx.aggressive {
45        if let Err(e) = git::push_branch(root, &branch) {
46            eprintln!("warning: push failed: {e:#}");
47        }
48    }
49
50    println!("{id}: {field} = {value}");
51    Ok(())
52}