//! git-remote-iroh: git transport over iroh QUIC. //! //! Remote helper mode (called by git): //! git-remote-iroh iroh:// //! //! Server mode (run manually): //! git-remote-iroh serve //! //! Info mode: //! git-remote-iroh info mod remote_helper; use clap::{Parser, Subcommand}; use std::path::PathBuf; #[derive(Parser)] #[command(name = "git-remote-iroh", about = "Git remote helper over iroh QUIC")] struct Cli { #[command(subcommand)] command: CliCommand, } #[derive(Subcommand)] enum CliCommand { /// Run the iroh server for a git repo (accepts push/fetch from peers) Serve { /// Path to the git repository to serve repo_dir: PathBuf, }, /// Show this node's iroh ID and config Info, } #[tokio::main] async fn main() { tracing_subscriber::fmt() .with_writer(std::io::stderr) .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .init(); let args: Vec = std::env::args().collect(); // detect remote helper mode: git invokes us as `git-remote-iroh ` if args.len() == 3 && args[1] != "serve" && args[1] != "info" { let remote_name = &args[1]; let url = &args[2]; if let Err(e) = remote_helper::run(remote_name, url).await { eprintln!("git-remote-iroh: error: {}", e); std::process::exit(1); } return; } // CLI mode let cli = Cli::parse(); match cli.command { CliCommand::Serve { repo_dir } => { handle_serve(repo_dir).await; } CliCommand::Info => { handle_info(); } } } async fn handle_serve(repo_dir: PathBuf) { let key = git_remote_iroh::config::load_or_create_key().expect("failed to load iroh key"); let (router, ep) = git_remote_iroh::server::start_server(key, repo_dir) .await .expect("failed to start server"); ep.online().await; let addr = ep.addr(); eprintln!("git-remote-iroh: serving"); eprintln!(" node_id: {}", ep.id()); eprintln!(" remote URL: iroh://{}", ep.id()); eprintln!(); eprintln!("add as remote:"); eprintln!(" git remote add iroh iroh://{}", ep.id()); eprintln!(); eprintln!("waiting for connections... (ctrl-c to stop)"); tokio::signal::ctrl_c().await.ok(); router.shutdown().await.ok(); } fn handle_info() { let key = git_remote_iroh::config::load_or_create_key().expect("failed to load iroh key"); let public = key.public(); eprintln!("node_id: {}", public); eprintln!("remote URL: iroh://{}", public); }