Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iroh-cli): improve ergonomics of iroh gossip subscribe CLI cmd #2751

Merged
merged 2 commits into from
Sep 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 40 additions & 10 deletions iroh-cli/src/commands/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,52 @@ use iroh::{
client::{gossip::SubscribeOpts, Iroh},
net::NodeId,
};
use std::str::FromStr as _;
use tokio::io::AsyncBufReadExt;

/// Commands to manage gossiping.
#[derive(Subcommand, Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum GossipCommands {
/// Subscribe to a topic
#[command(group(
ArgGroup::new("input")
.required(true)
.args(&["topic", "raw_topic"])
))]
/// Subscribe to a gossip topic
#[command(
long_about = r#"Subscribe to a gossip topic

Example usage:

$ iroh gossip subscribe --topic test --start

This will print the current node's id. Open another terminal
or another machine and you can join the same topic:

# on another machine/terminal
$ iroh gossip subscribe --topic test <other node_id> --start

Any lines entered in stdin will be sent to the given topic
and received messages will be printed to stdout line-by-line.

The process waits for Ctrl+C to exit."#,
group(
ArgGroup::new("input")
.required(true)
.args(&["topic", "raw_topic"])
)
)]
Subscribe {
/// Topic string to subscribe to.
/// The topic to subscribe to.
///
/// This will be hashed with BLAKE3 to get the actual topic ID.
#[clap(long)]
topic: Option<String>,
/// The raw topic to subscribe to as hex. Needs to be 32 bytes, i.e. 64 hex characters.
#[clap(long)]
raw_topic: Option<String>,
bootstrap: Vec<NodeId>,
/// The set of nodes that are also part of the gossip swarm to bootstrap with.
///
/// If empty, this will bootstrap a new swarm. Running the command will print
/// the node's `NodeId`, which can be used as the bootstrap argument in other nodes.
bootstrap: Vec<String>,
/// If enabled, all gossip events will be printed, including neighbor up/down events.
#[clap(long, short)]
verbose: bool,
},
Expand All @@ -46,7 +70,13 @@ impl GossipCommands {
bootstrap,
verbose,
} => {
let bootstrap = bootstrap.into_iter().collect();
let bootstrap = bootstrap
.into_iter()
.map(|node_id| NodeId::from_str(&node_id).map_err(|e| {
anyhow::anyhow!("Failed to parse bootstrap node id \"{node_id}\": {e}\nMust be a valid base32-encoded iroh node id.")
}))
.collect::<Result<_, _>>()?;

let topic = match (topic, raw_topic) {
(Some(topic), None) => blake3::hash(topic.as_bytes()).into(),
(None, Some(raw_topic)) => {
Expand All @@ -57,7 +87,7 @@ impl GossipCommands {
}
_ => anyhow::bail!("either topic or raw_topic must be provided"),
};
// blake3::hash(topic.as_ref()).into();

let opts = SubscribeOpts {
bootstrap,
subscription_capacity: 1024,
Expand Down
Loading