use crate::cli::UI;
use anyhow::{bail, Result};
use std::path::Path;
use tracing::warn;
pub fn list(path: &Path, verbose: bool, ui: &UI) -> Result<()> {
let repo = crate::ops::open_repo(path)?;
let remotes = repo.remotes()?;
for name in remotes.iter().flatten() {
if verbose {
if let Ok(remote) = repo.find_remote(name) {
let url = remote.url().unwrap_or("");
ui.list_item(format!("{}\t{} (fetch)", name, url));
let push_url = remote.pushurl().unwrap_or(url);
ui.list_item(format!("{}\t{} (push)", name, push_url));
}
} else {
ui.list_item(name);
}
}
Ok(())
}
pub fn add(path: &Path, name: &str, url: &str, ui: &UI) -> Result<()> {
validate_remote_url(url)?;
let repo = crate::ops::open_repo(path)?;
repo.remote(name, url)?;
ui.success(format!("Added remote '{}' -> {}", name, url));
Ok(())
}
pub fn remove(path: &Path, name: &str, ui: &UI) -> Result<()> {
let repo = crate::ops::open_repo(path)?;
repo.remote_delete(name)?;
ui.success(format!("Removed remote '{}'", name));
Ok(())
}
pub fn set_url(path: &Path, name: &str, url: &str, ui: &UI) -> Result<()> {
validate_remote_url(url)?;
let repo = crate::ops::open_repo(path)?;
repo.remote_set_url(name, url)?;
ui.success(format!("Updated remote '{}' URL to {}", name, url));
Ok(())
}
fn validate_remote_url(url: &str) -> Result<()> {
if url.starts_with("file://") {
bail!("file:// protocol is blocked for security. Use a path or HTTPS URL instead.");
}
if url.starts_with("http://") {
warn!("WARNING: HTTP remote URL detected. Consider using HTTPS for security.");
eprintln!("WARNING: HTTP remote URL detected. Consider using HTTPS for security.");
}
Ok(())
}