1pub mod backend;
9pub mod body;
10pub mod cli;
11pub mod commands;
12pub mod config;
13pub mod doc;
14pub mod error;
15pub mod file_refs;
16pub mod frontmatter;
17pub mod links;
18pub mod mdprism;
19pub mod palette;
20pub mod project;
21pub mod project_config;
22pub mod refs;
23pub mod retired;
24pub mod rules;
25pub mod store;
26pub mod templates;
27
28pub use error::{OpysError, Result};
29pub use frontmatter::Frontmatter;
30pub use project::Project;
31
32use cli::{Cli, Command};
33
34pub struct Ctx {
37 pub root: String,
38 pub no_sync: bool,
39 pub backend: Box<dyn backend::Backend>,
40}
41
42impl Ctx {
43 pub fn open(&self) -> Result<Project> {
44 Project::open(&self.root)
45 }
46
47 pub fn load(&self, prj: &Project) -> Result<(store::Store, Vec<String>)> {
49 self.backend.load(prj)
50 }
51
52 pub fn flush(&self, prj: &Project, store: store::Store) -> Result<()> {
54 self.backend.flush(prj, store)
55 }
56}
57
58pub fn run(cli: Cli, backend: Box<dyn backend::Backend>) -> Result<i32> {
64 let ctx = Ctx {
65 root: cli.root,
66 no_sync: cli.no_sync,
67 backend,
68 };
69 match cli.command {
70 Command::Init => {
71 commands::init::run(&ctx)?;
72 Ok(0)
73 }
74 Command::New {
75 type_name,
76 title,
77 tags,
78 status,
79 features,
80 reason,
81 field,
82 } => {
83 commands::new::run(
84 &ctx,
85 &type_name,
86 &title,
87 &tags,
88 &status,
89 &features,
90 reason.as_deref(),
91 &field,
92 )?;
93 Ok(0)
94 }
95 Command::Import { type_name, file } => {
96 commands::import::run(&ctx, &type_name, &file)?;
97 Ok(0)
98 }
99 Command::Show { id, refs } => {
100 commands::show::run(&ctx, &id, refs)?;
101 Ok(0)
102 }
103 Command::List {
104 type_name,
105 tag,
106 status,
107 field,
108 format,
109 } => {
110 commands::list::run(
111 &ctx,
112 type_name.as_deref(),
113 tag.as_deref(),
114 status.as_deref(),
115 &field,
116 format,
117 )?;
118 Ok(0)
119 }
120 Command::SetStatus {
121 ids,
122 status,
123 reason,
124 } => {
125 commands::set_status::run(&ctx, &ids, &status, reason.as_deref())?;
126 Ok(0)
127 }
128 Command::Tag { ids, add, remove } => {
129 commands::tag::run(&ctx, &ids, add.as_deref(), remove.as_deref())?;
130 Ok(0)
131 }
132 Command::Retire { ids, reason } => {
133 commands::retire::run(&ctx, &ids, &reason)?;
134 Ok(0)
135 }
136 Command::Block { ids, by } => {
137 commands::block::block(&ctx, &ids, &by)?;
138 Ok(0)
139 }
140 Command::Unblock { ids, by } => {
141 commands::block::unblock(&ctx, &ids, &by)?;
142 Ok(0)
143 }
144 Command::Verify => commands::verify::run(&ctx),
145 Command::Sync => {
146 commands::sync::run_command(&ctx)?;
147 Ok(0)
148 }
149 Command::Tags { keys } => {
150 commands::tags::run(&ctx, keys)?;
151 Ok(0)
152 }
153 Command::Stats { plain } => {
154 commands::stats::run(&ctx, plain)?;
155 Ok(0)
156 }
157 Command::Query {
158 sql,
159 plain,
160 write,
161 stdin,
162 } => {
163 commands::query::run(&ctx, &sql, plain, write, stdin)?;
164 Ok(0)
165 }
166 #[cfg(feature = "history")]
167 Command::History { id } => {
168 commands::history::run(&ctx, &id)?;
169 Ok(0)
170 }
171 Command::Close { ids, force } => {
172 commands::close::run(&ctx, &ids, force)?;
173 Ok(0)
174 }
175 Command::Renumber { base } => {
176 commands::renumber::run(&ctx, base.as_deref())?;
177 Ok(0)
178 }
179 Command::Cleanup => {
180 commands::cleanup::run(&ctx)?;
181 Ok(0)
182 }
183 Command::Config(cmd) => match cmd {
184 cli::ConfigCommand::Init => {
185 commands::config::init(&ctx)?;
186 Ok(0)
187 }
188 cli::ConfigCommand::Validate => commands::config::validate(&ctx),
189 },
190 Command::AgentRules { tool, stdout } => {
191 commands::agent_rules::run(&ctx, tool, stdout)?;
192 Ok(0)
193 }
194 #[cfg(feature = "tui")]
197 Command::Tui { .. } => Err(crate::error::usage(
198 "the tui is launched by the opys binary, not opys::run",
199 )),
200 }
201}