Skip to content

Commit 08d7c18

Browse files
committed
feat(cli): add soar repo subcommand for repository management
Add CLI integration for repository operations (add, update, remove, list) so users can manage repositories without manually editing config.toml.
1 parent fc76b6f commit 08d7c18

4 files changed

Lines changed: 148 additions & 0 deletions

File tree

crates/soar-cli/src/cli.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,64 @@ pub struct Args {
6363
pub command: Commands,
6464
}
6565

66+
#[derive(Subcommand)]
67+
pub enum RepoAction {
68+
/// Add a new repository
69+
Add {
70+
/// Repository name
71+
name: String,
72+
/// Repository metadata URL
73+
url: String,
74+
/// Base64-encoded public key for signature verification
75+
#[arg(long)]
76+
pubkey: Option<String>,
77+
/// Whether the repository is enabled
78+
#[arg(long)]
79+
enabled: Option<bool>,
80+
/// Enable desktop integration
81+
#[arg(long)]
82+
desktop_integration: Option<bool>,
83+
/// Enable signature verification
84+
#[arg(long)]
85+
signature_verification: Option<bool>,
86+
/// Sync interval (e.g., "1h", "12h", "1d")
87+
#[arg(long)]
88+
sync_interval: Option<String>,
89+
},
90+
/// Update an existing repository
91+
Update {
92+
/// Repository name
93+
name: String,
94+
/// Repository metadata URL
95+
#[arg(long)]
96+
url: Option<String>,
97+
/// Base64-encoded public key for signature verification
98+
#[arg(long)]
99+
pubkey: Option<String>,
100+
/// Whether the repository is enabled
101+
#[arg(long)]
102+
enabled: Option<bool>,
103+
/// Enable desktop integration
104+
#[arg(long)]
105+
desktop_integration: Option<bool>,
106+
/// Enable signature verification
107+
#[arg(long)]
108+
signature_verification: Option<bool>,
109+
/// Sync interval (e.g., "1h", "12h", "1d")
110+
#[arg(long)]
111+
sync_interval: Option<String>,
112+
},
113+
/// Remove a repository
114+
#[clap(visible_alias = "del")]
115+
Remove {
116+
/// Repository name
117+
name: String,
118+
},
119+
/// List configured repositories
120+
#[clap(visible_alias = "ls")]
121+
List,
122+
}
123+
66124
#[derive(Subcommand)]
67125
pub enum SelfAction {
68126
/// Update soar
@@ -404,6 +462,14 @@ pub enum Commands {
404462
repositories: Vec<String>,
405463
},
406464

465+
/// Manage repositories
466+
#[command(arg_required_else_help = true)]
467+
#[clap(name = "repo", visible_alias = "repository")]
468+
Repo {
469+
#[clap(subcommand)]
470+
action: RepoAction,
471+
},
472+
407473
/// View env
408474
#[clap(name = "env")]
409475
Env,

crates/soar-cli/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ mod list;
4949
mod logging;
5050
mod progress;
5151
mod remove;
52+
mod repo;
5253
mod run;
5354
mod update;
5455
#[path = "use.rs"]
@@ -372,6 +373,11 @@ async fn handle_cli() -> SoarResult<()> {
372373
download(context, links, github, gitlab, ghcr).await?;
373374
}
374375
cli::Commands::Health => display_health(&ctx).await?,
376+
cli::Commands::Repo {
377+
action,
378+
} => {
379+
repo::handle_repo_action(&ctx, action)?;
380+
}
375381
cli::Commands::Env => {
376382
let config = get_config();
377383

crates/soar-cli/src/repo.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use soar_config::repository::Repository;
2+
use soar_core::SoarResult;
3+
use soar_operations::{repo::RepoUpdate, SoarContext};
4+
use tracing::info;
5+
6+
use crate::cli::RepoAction;
7+
8+
pub fn handle_repo_action(ctx: &SoarContext, action: RepoAction) -> SoarResult<()> {
9+
match action {
10+
RepoAction::Add {
11+
name,
12+
url,
13+
pubkey,
14+
enabled,
15+
desktop_integration,
16+
signature_verification,
17+
sync_interval,
18+
} => {
19+
ctx.add_repository(Repository {
20+
name: name.clone(),
21+
url,
22+
pubkey,
23+
enabled,
24+
desktop_integration,
25+
signature_verification,
26+
sync_interval,
27+
})?;
28+
info!("Repository '{}' added successfully.", name);
29+
}
30+
RepoAction::Update {
31+
name,
32+
url,
33+
pubkey,
34+
enabled,
35+
desktop_integration,
36+
signature_verification,
37+
sync_interval,
38+
} => {
39+
ctx.update_repository(
40+
&name,
41+
RepoUpdate {
42+
url,
43+
pubkey,
44+
enabled,
45+
desktop_integration,
46+
signature_verification,
47+
sync_interval,
48+
},
49+
)?;
50+
info!("Repository '{}' updated successfully.", name);
51+
}
52+
RepoAction::Remove {
53+
name,
54+
} => {
55+
ctx.remove_repository(&name)?;
56+
info!("Repository '{}' removed successfully.", name);
57+
}
58+
RepoAction::List => {
59+
let config = soar_config::config::get_config();
60+
if config.repositories.is_empty() {
61+
info!("No repositories configured.");
62+
} else {
63+
for repo in &config.repositories {
64+
let status = if repo.is_enabled() {
65+
"enabled"
66+
} else {
67+
"disabled"
68+
};
69+
info!("{} ({}) - {}", repo.name, status, repo.url);
70+
}
71+
}
72+
}
73+
}
74+
Ok(())
75+
}

crates/soar-operations/src/utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub fn get_package_hooks(pkg_name: &str) -> (Option<PackageHooks>, Option<Sandbo
4242
}
4343

4444
/// Creates symlinks from installed package binaries to the bin directory.
45+
#[allow(clippy::too_many_arguments)]
4546
pub async fn mangle_package_symlinks(
4647
install_dir: &Path,
4748
bin_dir: &Path,

0 commit comments

Comments
 (0)