mod.rs

  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;
 22mod webui;
 23
 24use crate::cli::{Cli, Command};
 25use crate::db;
 26use crate::model::{Effort, Priority};
 27use anyhow::Result;
 28
 29fn require_root() -> Result<std::path::PathBuf> {
 30    std::env::current_dir().map_err(Into::into)
 31}
 32
 33pub fn dispatch(cli: &Cli) -> Result<()> {
 34    if let Some(project) = &cli.project {
 35        std::env::set_var(db::PROJECT_ENV, project);
 36    }
 37
 38    match &cli.command {
 39        Command::Project { action } => project::run(action, cli.json),
 40        Command::Create {
 41            title,
 42            priority,
 43            effort,
 44            task_type,
 45            desc,
 46            parent,
 47            labels,
 48        } => {
 49            let root = require_root()?;
 50            create::run(
 51                &root,
 52                create::Opts {
 53                    title: title.as_deref(),
 54                    priority: Priority::parse(priority)?,
 55                    effort: Effort::parse(effort)?,
 56                    task_type,
 57                    desc: desc.as_deref(),
 58                    parent: parent.as_deref(),
 59                    labels: labels.as_deref(),
 60                    json: cli.json,
 61                },
 62            )
 63        }
 64        Command::List {
 65            status,
 66            priority,
 67            effort,
 68            label,
 69            task_type,
 70            all,
 71        } => {
 72            let root = require_root()?;
 73            let pri = priority.as_deref().map(Priority::parse).transpose()?;
 74            let eff = effort.as_deref().map(Effort::parse).transpose()?;
 75            list::run(
 76                &root,
 77                list::Opts {
 78                    status: status.as_deref(),
 79                    priority: pri,
 80                    effort: eff,
 81                    label: label.as_deref(),
 82                    task_type: task_type.as_deref(),
 83                    all: *all,
 84                    json: cli.json,
 85                },
 86            )
 87        }
 88        Command::Show { id } => {
 89            let root = require_root()?;
 90            show::run(&root, id, cli.json)
 91        }
 92        Command::Log { id, message } => {
 93            let root = require_root()?;
 94            log::run(&root, id, message, cli.json)
 95        }
 96        Command::Update {
 97            id,
 98            status,
 99            priority,
100            effort,
101            title,
102            desc,
103            task_type,
104            parent,
105        } => {
106            let root = require_root()?;
107            let pri = priority.as_deref().map(Priority::parse).transpose()?;
108            let eff = effort.as_deref().map(Effort::parse).transpose()?;
109            // --parent "" means clear; --parent <id> means set; absent means don't change.
110            let parent_opt =
111                parent
112                    .as_ref()
113                    .map(|p| if p.is_empty() { None } else { Some(p.as_str()) });
114            update::run(
115                &root,
116                id,
117                update::Opts {
118                    status: status.as_deref(),
119                    priority: pri,
120                    effort: eff,
121                    title: title.as_deref(),
122                    desc: desc.as_deref(),
123                    task_type: task_type.as_deref(),
124                    parent: parent_opt,
125                    json: cli.json,
126                },
127            )
128        }
129        Command::Done { ids } => {
130            let root = require_root()?;
131            done::run(&root, ids, cli.json)
132        }
133        Command::Rm {
134            force,
135            recursive,
136            ids,
137        } => {
138            let root = require_root()?;
139            rm::run(&root, ids, *recursive, *force, cli.json)
140        }
141        Command::Reopen { ids } => {
142            let root = require_root()?;
143            reopen::run(&root, ids, cli.json)
144        }
145        Command::Dep { action } => {
146            let root = require_root()?;
147            dep::run(&root, action, cli.json)
148        }
149        Command::Label { action } => {
150            let root = require_root()?;
151            label::run(&root, action, cli.json)
152        }
153        Command::Search { query } => {
154            let root = require_root()?;
155            search::run(&root, query, cli.json)
156        }
157        Command::Ready => {
158            let root = require_root()?;
159            ready::run(&root, cli.json)
160        }
161        Command::Next {
162            mode,
163            verbose,
164            limit,
165        } => {
166            let root = require_root()?;
167            next::run(&root, mode, *verbose, *limit, cli.json)
168        }
169        Command::Stats => {
170            let root = require_root()?;
171            stats::run(&root)
172        }
173        Command::Doctor { fix } => {
174            let root = require_root()?;
175            doctor::run(&root, *fix, cli.json)
176        }
177        Command::Tidy => {
178            let root = require_root()?;
179            tidy::run(&root)
180        }
181        Command::Export => {
182            let root = require_root()?;
183            export::run(&root)
184        }
185        Command::Import { file } => {
186            let root = require_root()?;
187            import::run(&root, file)
188        }
189        Command::Sync { code } => {
190            let root = require_root()?;
191            sync::run(&root, code.as_deref(), cli.json)
192        }
193        Command::WebUi { host, port } => {
194            let root = require_root()?;
195            webui::run(&root, host, *port, cli.project.as_deref())
196        }
197        Command::Skill { dir } => skill::run(dir.as_deref()),
198    }
199}