This commit is contained in:
2026-05-08 16:24:23 +00:00
parent 3d73f20c1f
commit 018f1f12d5
5 changed files with 188 additions and 236 deletions
+30 -42
View File
@@ -89,50 +89,24 @@ enum WebhookCommand {
#[derive(Args, Debug)]
struct WebhookInstallCommand {
#[arg(value_name = "REPO", conflicts_with = "repo_pattern")]
repo: Option<String>,
#[arg(long, value_name = "URL")]
url: Option<String>,
#[arg(long, conflicts_with = "secret_env")]
secret: Option<String>,
#[arg(long, value_name = "ENV", conflicts_with = "secret")]
secret_env: Option<String>,
#[arg(long, value_name = "NAME")]
group: Option<String>,
#[arg(long, value_name = "REGEX")]
repo_pattern: Option<String>,
#[arg(long)]
dry_run: bool,
#[arg(long, value_name = "PATH")]
work_dir: Option<PathBuf>,
#[arg(long, default_value_t = DEFAULT_JOBS, value_name = "N")]
jobs: usize,
}
#[derive(Args, Debug)]
struct WebhookUninstallCommand {
#[arg(value_name = "REPO")]
repo: Option<String>,
#[arg(long, value_name = "URL")]
url: Option<String>,
#[arg(long, value_name = "NAME")]
group: Option<String>,
#[arg(long)]
dry_run: bool,
#[arg(long, value_name = "PATH")]
work_dir: Option<PathBuf>,
#[arg(long, default_value_t = DEFAULT_JOBS, value_name = "N")]
jobs: usize,
}
#[derive(Args, Debug)]
struct WebhookUpdateCommand {
#[arg(long, value_name = "URL")]
#[arg(value_name = "URL")]
url: String,
#[arg(long, conflicts_with = "secret_env")]
secret: Option<String>,
#[arg(long, value_name = "ENV", conflicts_with = "secret")]
secret_env: Option<String>,
#[arg(long)]
dry_run: bool,
#[arg(long, value_name = "PATH")]
@@ -199,33 +173,28 @@ fn main() -> Result<()> {
}
Command::Webhook(WebhookCommand::Install(command)) => {
let config = load_config(&config_path)?;
let secret = resolve_webhook_secret(&config, command.secret, command.secret_env)?;
let url = resolve_webhook_url(&config, command.url)?;
let secret = resolve_config_webhook_secret(&config)?;
let url = resolve_config_webhook_url(&config)?;
install_webhooks(
&config,
WebhookInstallOptions {
url,
secret,
group: command.group,
repo: command.repo,
repo_pattern: command.repo_pattern,
dry_run: command.dry_run,
work_dir: command.work_dir,
work_dir: None,
jobs: command.jobs,
},
)
}
Command::Webhook(WebhookCommand::Uninstall(command)) => {
let config = load_config(&config_path)?;
let url = resolve_webhook_url(&config, command.url)?;
let url = resolve_config_webhook_url(&config)?;
uninstall_webhooks(
&config,
WebhookUninstallOptions {
url,
group: command.group,
repo: command.repo,
dry_run: command.dry_run,
work_dir: command.work_dir,
work_dir: None,
jobs: command.jobs,
},
)
@@ -239,7 +208,7 @@ fn main() -> Result<()> {
.ok_or_else(|| {
anyhow::anyhow!("configure [webhook] before running webhook update")
})?;
let secret = resolve_webhook_secret(&config, command.secret, command.secret_env)?;
let secret = resolve_config_webhook_secret(&config)?;
update_webhooks(
&config,
WebhookUpdateOptions {
@@ -261,9 +230,26 @@ fn main() -> Result<()> {
}
fn load_config(path: &Path) -> Result<Config> {
if !path.exists() {
anyhow::bail!(
"config not found at {}. Run `refray config` first to create one.",
path.display()
);
}
Config::load(path).with_context(|| format!("failed to load config at {}", path.display()))
}
fn resolve_config_webhook_secret(config: &Config) -> Result<String> {
config
.webhook
.as_ref()
.map(|webhook| webhook.secret())
.transpose()?
.ok_or_else(|| {
anyhow::anyhow!("configure [webhook].secret before running webhook commands")
})
}
fn resolve_webhook_secret(
config: &Config,
value: Option<String>,
@@ -283,10 +269,12 @@ fn resolve_webhook_secret(
}
}
fn resolve_webhook_url(config: &Config, value: Option<String>) -> Result<String> {
value
.or_else(|| config.webhook.as_ref().map(|webhook| webhook.url.clone()))
.ok_or_else(|| anyhow::anyhow!("pass --url or configure [webhook].url"))
fn resolve_config_webhook_url(config: &Config) -> Result<String> {
config
.webhook
.as_ref()
.map(|webhook| webhook.url.clone())
.ok_or_else(|| anyhow::anyhow!("configure [webhook].url before running webhook commands"))
}
fn set_config_webhook_url(config: &mut Config, url: String) {
-42
View File
@@ -39,9 +39,6 @@ pub struct ServeOptions {
pub struct WebhookInstallOptions {
pub url: String,
pub secret: String,
pub group: Option<String>,
pub repo: Option<String>,
pub repo_pattern: Option<String>,
pub dry_run: bool,
pub work_dir: Option<PathBuf>,
pub jobs: usize,
@@ -50,8 +47,6 @@ pub struct WebhookInstallOptions {
#[derive(Clone, Debug)]
pub struct WebhookUninstallOptions {
pub url: String,
pub group: Option<String>,
pub repo: Option<String>,
pub dry_run: bool,
pub work_dir: Option<PathBuf>,
pub jobs: usize,
@@ -183,21 +178,8 @@ pub fn install_webhooks(config: &Config, options: WebhookInstallOptions) -> Resu
}
let work_dir = options.work_dir.clone().unwrap_or_else(default_work_dir);
let state = Arc::new(Mutex::new(load_webhook_state(&work_dir)?));
let repo_pattern = options
.repo_pattern
.as_deref()
.map(regex::Regex::new)
.transpose()
.with_context(|| "invalid --repo-pattern regex")?;
for mirror in &config.mirrors {
if options
.group
.as_ref()
.is_some_and(|group| group != &mirror.name)
{
continue;
}
crate::logln!();
crate::logln!(
"{} {}",
@@ -222,15 +204,6 @@ pub fn install_webhooks(config: &Config, options: WebhookInstallOptions) -> Resu
.filter(|repo| mirror.sync_visibility.matches_private(repo.private))
.filter(|repo| repo_filter.matches(&repo.name))
{
if options.repo.as_ref().is_some_and(|name| name != &repo.name) {
continue;
}
if repo_pattern
.as_ref()
.is_some_and(|pattern| !pattern.is_match(&repo.name))
{
continue;
}
tasks.push(WebhookInstallTask {
site: site.clone(),
group: mirror.name.clone(),
@@ -262,13 +235,6 @@ pub fn uninstall_webhooks(config: &Config, options: WebhookUninstallOptions) ->
let mut state = load_webhook_state(&work_dir)?;
let mut tasks = Vec::new();
for mirror in &config.mirrors {
if options
.group
.as_ref()
.is_some_and(|group| group != &mirror.name)
{
continue;
}
crate::logln!();
crate::logln!(
"{} {}",
@@ -287,9 +253,6 @@ pub fn uninstall_webhooks(config: &Config, options: WebhookUninstallOptions) ->
.list_repos(endpoint)
.with_context(|| format!("failed to list repos for {}", endpoint.label()))?;
for repo in repos {
if options.repo.as_ref().is_some_and(|name| name != &repo.name) {
continue;
}
tasks.push(WebhookUninstallTask {
group: mirror.name.clone(),
site: site.clone(),
@@ -329,8 +292,6 @@ pub fn update_webhooks(config: &Config, options: WebhookUpdateOptions) -> Result
config,
WebhookUninstallOptions {
url: options.old_url.clone(),
group: None,
repo: None,
dry_run: options.dry_run,
work_dir: options.work_dir.clone(),
jobs: options.jobs,
@@ -343,9 +304,6 @@ pub fn update_webhooks(config: &Config, options: WebhookUpdateOptions) -> Result
WebhookInstallOptions {
url: options.new_url,
secret: options.secret,
group: None,
repo: None,
repo_pattern: None,
dry_run: options.dry_run,
work_dir: options.work_dir,
jobs: options.jobs,