1mod create;
2mod dep;
3mod doctor;
4mod done;
5mod export;
6mod import;
7mod label;
8mod list;
9mod log;
10mod next;
11mod project;
12mod ready;
13mod reopen;
14mod rm;
15mod search;
16mod show;
17mod skill;
18mod stats;
19pub mod sync;
20mod tidy;
21mod update;
22
23use crate::cli::{Cli, Command};
24use crate::db;
25use anyhow::Result;
26
27fn require_root() -> Result<std::path::PathBuf> {
28 std::env::current_dir().map_err(Into::into)
29}
30
31pub fn dispatch(cli: &Cli) -> Result<()> {
32 if let Some(project) = &cli.project {
33 std::env::set_var(db::PROJECT_ENV, project);
34 }
35
36 match &cli.command {
37 Command::Project { action } => project::run(action, cli.json),
38 Command::Create {
39 title,
40 priority,
41 effort,
42 task_type,
43 desc,
44 parent,
45 labels,
46 } => {
47 let root = require_root()?;
48 create::run(
49 &root,
50 create::Opts {
51 title: title.as_deref(),
52 priority: db::parse_priority(priority)?,
53 effort: db::parse_effort(effort)?,
54 task_type,
55 desc: desc.as_deref(),
56 parent: parent.as_deref(),
57 labels: labels.as_deref(),
58 json: cli.json,
59 },
60 )
61 }
62 Command::List {
63 status,
64 priority,
65 effort,
66 label,
67 } => {
68 let root = require_root()?;
69 let pri = priority.as_deref().map(db::parse_priority).transpose()?;
70 let eff = effort.as_deref().map(db::parse_effort).transpose()?;
71 list::run(
72 &root,
73 status.as_deref(),
74 pri,
75 eff,
76 label.as_deref(),
77 cli.json,
78 )
79 }
80 Command::Show { id } => {
81 let root = require_root()?;
82 show::run(&root, id, cli.json)
83 }
84 Command::Log { id, message } => {
85 let root = require_root()?;
86 log::run(&root, id, message, cli.json)
87 }
88 Command::Update {
89 id,
90 status,
91 priority,
92 effort,
93 title,
94 desc,
95 } => {
96 let root = require_root()?;
97 let pri = priority.as_deref().map(db::parse_priority).transpose()?;
98 let eff = effort.as_deref().map(db::parse_effort).transpose()?;
99 update::run(
100 &root,
101 id,
102 update::Opts {
103 status: status.as_deref(),
104 priority: pri,
105 effort: eff,
106 title: title.as_deref(),
107 desc: desc.as_deref(),
108 json: cli.json,
109 },
110 )
111 }
112 Command::Done { ids } => {
113 let root = require_root()?;
114 done::run(&root, ids, cli.json)
115 }
116 Command::Rm {
117 force,
118 recursive,
119 ids,
120 } => {
121 let root = require_root()?;
122 rm::run(&root, ids, *recursive, *force, cli.json)
123 }
124 Command::Reopen { ids } => {
125 let root = require_root()?;
126 reopen::run(&root, ids, cli.json)
127 }
128 Command::Dep { action } => {
129 let root = require_root()?;
130 dep::run(&root, action, cli.json)
131 }
132 Command::Label { action } => {
133 let root = require_root()?;
134 label::run(&root, action, cli.json)
135 }
136 Command::Search { query } => {
137 let root = require_root()?;
138 search::run(&root, query, cli.json)
139 }
140 Command::Ready => {
141 let root = require_root()?;
142 ready::run(&root, cli.json)
143 }
144 Command::Next {
145 mode,
146 verbose,
147 limit,
148 } => {
149 let root = require_root()?;
150 next::run(&root, mode, *verbose, *limit, cli.json)
151 }
152 Command::Stats => {
153 let root = require_root()?;
154 stats::run(&root)
155 }
156 Command::Doctor { fix } => {
157 let root = require_root()?;
158 doctor::run(&root, *fix, cli.json)
159 }
160 Command::Tidy => {
161 let root = require_root()?;
162 tidy::run(&root)
163 }
164 Command::Export => {
165 let root = require_root()?;
166 export::run(&root)
167 }
168 Command::Import { file } => {
169 let root = require_root()?;
170 import::run(&root, file)
171 }
172 Command::Sync { code } => {
173 let root = require_root()?;
174 sync::run(&root, code.as_deref(), cli.json)
175 }
176 Command::Skill { dir } => skill::run(dir.as_deref()),
177 }
178}