tix/cli/cli_templates.rs
1#[allow(clippy::wildcard_imports)]
2use super::*;
3
4/// The `tix template` management tree (`contracts/cli-surface.md`).
5///
6/// `list`/`show` are read-only; the four mutations call one service that
7/// validates the complete candidate registry before a single atomic
8/// `tix.toml` save, so a refused operation leaves the file byte-identical.
9/// Identity is the immutable stable ID: `update` changes a display name
10/// without touching scope, defaults, prompts, references, or preserved
11/// unknown metadata.
12#[derive(Subcommand)]
13pub enum TemplateAction {
14 /// List templates: one `id<TAB>name<TAB>scope` row each, in declaration order
15 List,
16 /// Show one template by stable ID (or a unique display name)
17 Show {
18 /// Stable ID, or a display name that names exactly one template
19 reference: String,
20 },
21 /// Create a template under a new stable ID
22 Create {
23 /// The new stable ID: ASCII letters, digits, `-` or `_`
24 #[arg(long, value_name = "ID")]
25 id: String,
26 /// Display name; omitted means the ID is shown in its place
27 #[arg(long, value_name = "NAME")]
28 name: Option<String>,
29 /// Scope: `repository` (default) | `board:<name>` | `team:<label>`
30 #[arg(long, value_name = "SCOPE")]
31 scope: Option<String>,
32 /// A normal create default, `FIELD=VALUE` (repeatable). Supplying any
33 /// `--default` replaces the whole defaults block.
34 #[arg(long = "default", value_name = "FIELD=VALUE")]
35 defaults: Vec<String>,
36 /// A structured prompt,
37 /// `key=<field>[,kind=text|select|multi-select|date][,required=true|false][,default=<v>][,label=<l>][,options_ref=<source>]`
38 /// (repeatable). Supplying any `--prompt` replaces the whole prompt list.
39 #[arg(long = "prompt", value_name = "KEY,ATTR=VALUE...")]
40 prompts: Vec<String>,
41 /// A typed reference,
42 /// `kind=label|assignee|file|cycle|milestone|relationship,value=<v>[,required=true|false]`
43 /// (repeatable). Supplying any `--reference` replaces the whole list.
44 #[arg(long = "reference", value_name = "KIND=VALUE,ATTR=VALUE...")]
45 references: Vec<String>,
46 },
47 /// Update the flags supplied, leaving every other stored field as it was
48 Update {
49 /// Stable ID, or a display name that names exactly one template
50 reference: String,
51 /// New display name (the stable ID never changes)
52 #[arg(long, value_name = "NAME")]
53 name: Option<String>,
54 /// New scope: `repository` | `board:<name>` | `team:<label>`
55 #[arg(long, value_name = "SCOPE")]
56 scope: Option<String>,
57 /// Replacement defaults, `FIELD=VALUE` (repeatable)
58 #[arg(long = "default", value_name = "FIELD=VALUE")]
59 defaults: Vec<String>,
60 /// Replacement prompts (repeatable; same grammar as `create`)
61 #[arg(long = "prompt", value_name = "KEY,ATTR=VALUE...")]
62 prompts: Vec<String>,
63 /// Replacement references (repeatable; same grammar as `create`)
64 #[arg(long = "reference", value_name = "KIND=VALUE,ATTR=VALUE...")]
65 references: Vec<String>,
66 },
67 /// Copy a template to a new stable ID, leaving the source untouched
68 Duplicate {
69 /// Stable ID, or a display name that names exactly one template
70 reference: String,
71 /// The new stable ID; omitted allocates `<source>-copy`, `-copy-2`, …
72 #[arg(long, value_name = "ID")]
73 id: Option<String>,
74 /// Display name for the copy; omitted keeps the source's label
75 #[arg(long, value_name = "NAME")]
76 name: Option<String>,
77 },
78 /// Delete a template definition (never the issues created from it)
79 Delete {
80 /// Stable ID, or a display name that names exactly one template
81 reference: String,
82 /// Confirm without prompting
83 #[arg(long)]
84 yes: bool,
85 },
86}