1use crate::completion;
2use crate::version;
3use clap::{Args, Parser, Subcommand, ValueEnum};
4
5use super::{
6 AppCommands, EnvCommands, LocalCommands, PresetCommands, SelfCommands, ServeCommands,
7 ShellCommands, StateCommands, SysCommands, TaskCommands, TaskRunCommand, ThemeCommands,
8};
9
10#[derive(Parser, Debug)]
12#[command(name = "shine")]
13#[command(version = version::display(), about, long_about = None)]
14#[command(
15 after_help = "QUICK START:\n shine list --available\n shine info app/starship\n shine install app/starship\n shine update && shine upgrade\n\nTARGETS:\n Use app/<category>, shell/<category>, or sys/<item>. A bare app/shell category is accepted when unique.\n\nNAMESPACES:\n app, shell, and sys expose resource-specific operations; preset, state, self, serve, completions, theme, and local are advanced tools."
16)]
17pub struct Cli {
18 #[arg(long, global = true)]
19 pub config_dir: Option<String>,
20
21 #[command(subcommand)]
22 pub command: Commands,
23}
24
25#[derive(Subcommand, Debug)]
26pub enum Commands {
27 #[command(name = "__shell-render", hide = true)]
28 ShellRender {
29 #[arg(value_name = "TARGET")]
30 target: String,
31 },
32 Init(InitCommand),
34 Shell {
36 #[command(subcommand)]
37 command: ShellCommands,
38 },
39 App {
41 #[command(subcommand)]
42 command: AppCommands,
43 },
44 Install {
46 #[arg(value_name = "TARGET")]
48 target: String,
49 #[arg(long)]
51 replace_managed: bool,
52 },
53 Uninstall {
55 #[arg(value_name = "TARGET")]
57 target: String,
58 #[arg(long)]
60 force: bool,
61 #[arg(long)]
63 purge: bool,
64 #[arg(long)]
66 dry_run: bool,
67 },
68 Completions {
70 #[command(subcommand)]
71 command: CompletionCommands,
72 },
73 List {
75 #[arg(long)]
77 available: bool,
78 #[arg(value_enum, requires = "available", value_name = "KIND")]
80 kind: Option<ResourceKind>,
81 },
82 Info {
84 #[arg(value_name = "TARGET")]
86 target: String,
87 #[arg(long)]
89 diff: bool,
90 #[arg(long)]
92 verbose: bool,
93 },
94 Preset {
96 #[command(subcommand)]
97 command: PresetCommands,
98 },
99 Update(UpdateCommand),
101 Upgrade(UpgradeCommand),
103 State {
105 #[command(subcommand)]
106 command: StateCommands,
107 },
108 #[command(name = "self")]
110 Self_ {
111 #[command(subcommand)]
112 command: SelfCommands,
113 },
114 Serve {
116 #[command(subcommand)]
117 command: ServeCommands,
118 },
119 Env {
121 #[command(subcommand)]
122 command: EnvCommands,
123 },
124 Sys {
126 #[command(subcommand)]
127 command: SysCommands,
128 },
129 Theme {
131 #[command(subcommand)]
132 command: ThemeCommands,
133 },
134 Ssh {
136 #[arg(long, value_enum, default_value_t = RemoteShell::Posix)]
139 remote_shell: RemoteShell,
140 #[arg(long = "with", value_name = "KEY[=ALIAS]")]
143 with: Vec<String>,
144 #[arg(long = "with-secret", value_name = "KEY[=ALIAS]")]
147 with_secret: Vec<String>,
148 #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
151 args: Vec<String>,
152 },
153 Local {
155 #[command(subcommand)]
156 command: LocalCommands,
157 },
158 Task {
160 #[command(subcommand)]
161 command: TaskCommands,
162 },
163 Run(TaskRunCommand),
165}
166
167#[derive(Copy, Clone, Debug, Eq, PartialEq, ValueEnum)]
169pub enum RemoteShell {
170 Posix,
172 Windows,
174}
175
176#[derive(Copy, Clone, Debug, Eq, PartialEq, ValueEnum)]
177pub enum ResourceKind {
178 App,
179 Shell,
180 Sys,
181}
182
183#[derive(Args, Debug)]
184pub struct InitCommand {
185 #[arg(long)]
187 pub yes: bool,
188}
189
190#[derive(Copy, Clone, Debug, Eq, PartialEq, ValueEnum)]
191pub enum CompletionShell {
192 #[value(name = "bash")]
193 Bash,
194 #[value(name = "powershell")]
195 PowerShell,
196 #[value(name = "zsh")]
197 Zsh,
198}
199
200#[derive(Copy, Clone, Debug, Eq, PartialEq, Subcommand)]
201pub enum CompletionCommands {
202 Install,
204 Bash,
206 #[command(name = "powershell")]
208 PowerShell,
209 Zsh,
211}
212
213impl CompletionCommands {
214 pub fn generate(self) {
215 match self {
216 CompletionCommands::Bash => completion::generate_registration(CompletionShell::Bash),
217 CompletionCommands::PowerShell => {
218 completion::generate_registration(CompletionShell::PowerShell)
219 }
220 CompletionCommands::Zsh => completion::generate_registration(CompletionShell::Zsh),
221 CompletionCommands::Install => unreachable!("install is handled by the async runtime"),
222 }
223 }
224}
225
226impl CompletionShell {
227 pub fn from_command(command: &CompletionCommands) -> Option<Self> {
228 match command {
229 CompletionCommands::Bash => Some(CompletionShell::Bash),
230 CompletionCommands::PowerShell => Some(CompletionShell::PowerShell),
231 CompletionCommands::Zsh => Some(CompletionShell::Zsh),
232 CompletionCommands::Install => None,
233 }
234 }
235
236 pub fn as_str(self) -> &'static str {
237 match self {
238 CompletionShell::Bash => "bash",
239 CompletionShell::PowerShell => "powershell",
240 CompletionShell::Zsh => "zsh",
241 }
242 }
243}
244
245#[derive(Parser, Debug)]
246pub struct UpdateCommand {
247 #[arg(value_name = "TARGET")]
249 pub target: Option<String>,
250 #[arg(long)]
252 pub pull: bool,
253 #[arg(long)]
255 pub diff: bool,
256 #[arg(long, conflicts_with = "target")]
258 pub verbose: bool,
259 #[arg(long, conflicts_with = "target")]
261 pub refresh_release: bool,
262}
263
264#[derive(Parser, Debug)]
265pub struct UpgradeCommand {
266 #[arg(value_name = "TARGET")]
268 pub target: Option<String>,
269 #[arg(long)]
271 pub pull: bool,
272 #[arg(long)]
274 pub verbose: bool,
275 #[arg(long)]
277 pub prune_stale: bool,
278}