1pub mod cli;
2pub mod collect;
3pub mod queue;
4pub mod queue_path;
5
6use clap::{builder::StyledStr, Args, Command, CommandFactory, Parser, Subcommand};
7use std::path::PathBuf;
8
9#[derive(Parser)]
10#[command(name = "sq", version)]
11pub struct Cli {
12 #[arg(short = 'q', long = "queue", value_name = "PATH", global = true)]
14 pub queue: Option<PathBuf>,
15
16 #[command(subcommand)]
17 pub command: Commands,
18}
19
20pub fn build_cli() -> Command {
21 Cli::command().mut_subcommand("collect", |subcmd| {
22 let styles = subcmd.get_styles();
23 let header = styles.get_header();
24 let literal = styles.get_literal();
25 let help = StyledStr::from(format!(
26 "{header}Examples:{header:#}\n {literal}rg --json PATTERN | sq collect --by-file{literal:#}\n {literal}rg --json -n -C2 PATTERN | sq collect --by-file --title-template \"migrate: {{{{filepath}}}}\"{literal:#}\n\n{header}Templates:{header:#}\n {literal}{{{{filepath}}}}{literal:#} Full file path for the grouped result\n {literal}{{{{filename}}}}{literal:#} Basename of {literal}{{{{filepath}}}}{literal:#}\n {literal}{{{{match_count}}}}{literal:#} Number of rg match events collected for the file\n\n Default title template: {literal}{{{{match_count}}}}:{{{{filepath}}}}{literal:#}"
27 ));
28
29 subcmd.after_help(help)
30 })
31}
32
33#[derive(Subcommand)]
34pub enum Commands {
35 Add(AddArgs),
37 Collect(CollectArgs),
39 List(ListArgs),
41 Show(ShowArgs),
43 Edit(EditArgs),
45 Close(StatusArgs),
47 Rm(RmArgs),
49 Prime(PrimeArgs),
51}
52
53#[derive(Parser)]
54pub struct AddArgs {
55 #[arg(long = "diff", value_name = "PATH")]
57 pub diff: Vec<String>,
58
59 #[arg(long = "file", value_name = "PATH")]
61 pub file: Vec<String>,
62
63 #[arg(long = "text", value_name = "STRING")]
65 pub text: Vec<String>,
66
67 #[arg(long = "directory", value_name = "PATH")]
69 pub directory: Vec<String>,
70
71 #[arg(long = "stdin", value_name = "TYPE")]
73 pub stdin: Option<String>,
74
75 #[arg(long = "title", value_name = "TITLE")]
77 pub title: Option<String>,
78
79 #[arg(long = "description", value_name = "TEXT")]
81 pub description: Option<String>,
82
83 #[arg(long = "metadata", value_name = "JSON")]
85 pub metadata: Option<String>,
86
87 #[arg(long = "blocked-by", value_name = "IDS")]
89 pub blocked_by: Option<String>,
90
91 #[arg(long = "json")]
93 pub json: bool,
94}
95
96#[derive(Args)]
97#[command(about = "Collect items from stdin into queue items")]
98pub struct CollectArgs {
99 #[arg(long = "by-file")]
101 pub by_file: bool,
102
103 #[arg(long = "stdin-format", value_name = "FORMAT")]
105 pub stdin_format: Option<String>,
106
107 #[arg(long = "title", value_name = "TITLE")]
109 pub title: Option<String>,
110
111 #[arg(long = "description", value_name = "TEXT")]
113 pub description: Option<String>,
114
115 #[arg(long = "title-template", value_name = "TEMPLATE")]
117 pub title_template: Option<String>,
118
119 #[arg(long = "metadata", value_name = "JSON")]
121 pub metadata: Option<String>,
122
123 #[arg(long = "blocked-by", value_name = "IDS")]
125 pub blocked_by: Option<String>,
126
127 #[arg(long = "json")]
129 pub json: bool,
130}
131
132#[derive(Parser)]
133pub struct ListArgs {
134 #[arg(long = "status", value_name = "STATUS")]
136 pub status: Option<String>,
137
138 #[arg(long = "all")]
140 pub all: bool,
141
142 #[arg(long = "json")]
144 pub json: bool,
145
146 #[arg(long = "filter", value_name = "EXPR")]
148 pub filter: Option<String>,
149
150 #[arg(long = "sort", value_name = "PATH")]
152 pub sort: Option<String>,
153
154 #[arg(long = "reverse")]
156 pub reverse: bool,
157
158 #[arg(long = "ready")]
160 pub ready: bool,
161}
162
163#[derive(Parser)]
164pub struct ShowArgs {
165 pub id: Option<String>,
167
168 #[arg(long = "json")]
170 pub json: bool,
171}
172
173#[derive(Parser)]
174pub struct EditArgs {
175 pub id: Option<String>,
177
178 #[arg(long = "add-diff", value_name = "PATH")]
180 pub add_diff: Vec<String>,
181
182 #[arg(long = "add-file", value_name = "PATH")]
184 pub add_file: Vec<String>,
185
186 #[arg(long = "add-text", value_name = "STRING")]
188 pub add_text: Vec<String>,
189
190 #[arg(long = "add-directory", value_name = "PATH")]
192 pub add_directory: Vec<String>,
193
194 #[arg(long = "add-transcript", value_name = "PATH")]
196 pub add_transcript: Vec<String>,
197
198 #[arg(long = "rm-source", value_name = "INDEX")]
200 pub rm_source: Vec<usize>,
201
202 #[arg(long = "set-status", value_name = "STATUS")]
204 pub set_status: Option<String>,
205
206 #[arg(long = "set-title", value_name = "TITLE")]
208 pub set_title: Option<String>,
209
210 #[arg(long = "set-description", value_name = "TEXT")]
212 pub set_description: Option<String>,
213
214 #[arg(long = "set-metadata", value_name = "JSON")]
216 pub set_metadata: Option<String>,
217
218 #[arg(long = "merge-metadata", value_name = "JSON")]
220 pub merge_metadata: Option<String>,
221
222 #[arg(long = "set-blocked-by", value_name = "IDS")]
224 pub set_blocked_by: Option<String>,
225
226 #[arg(long = "json")]
228 pub json: bool,
229}
230
231#[derive(Parser)]
232pub struct StatusArgs {
233 pub id: Option<String>,
235
236 #[arg(long = "json")]
238 pub json: bool,
239}
240
241#[derive(Parser)]
242pub struct RmArgs {
243 pub id: Option<String>,
245
246 #[arg(long = "json")]
248 pub json: bool,
249}
250
251#[derive(Parser)]
252pub struct PrimeArgs {
253 #[arg(long = "full")]
255 pub full: bool,
256}