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