From 5dc8e31eb3e066029c8bd22b33a3bcb8f1084780 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 7 Jun 2025 20:58:25 +0000 Subject: [PATCH] feat: New `config relays` command to set the default fallbacks relays Signed-off-by: Awiteb --- CHANGELOG.md | 2 ++ src/cli/commands/config/mod.rs | 7 ++++ src/cli/commands/config/relays.rs | 53 +++++++++++++++++++++++++++++++ src/cli/config.rs | 9 ++++-- src/cli/mod.rs | 12 +++++-- 5 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/cli/commands/config/relays.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index fe3a935..cfa5b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New `patch send` command to send patches - by Awiteb - Add `alt` tag to the git issue - by Awiteb - Add `description` tag to the patch - by Awiteb +- New `config pow` command to set the default PoW difficulty - by Awiteb +- New `config relays` command to set the default fallbacks relays - by Awiteb ### Refactor diff --git a/src/cli/commands/config/mod.rs b/src/cli/commands/config/mod.rs index 37c15a7..0174e72 100644 --- a/src/cli/commands/config/mod.rs +++ b/src/cli/commands/config/mod.rs @@ -16,10 +16,13 @@ /// `config pow` subcommand mod pow; +/// `config relays` subcommand +mod relays; use clap::Subcommand; use self::pow::PowArgs; +use self::relays::RelaysArgs; use super::CliOptions; use crate::{cli::traits::CommandRunner, error::N34Result}; @@ -28,12 +31,16 @@ use crate::{cli::traits::CommandRunner, error::N34Result}; pub enum ConfigSubcommands { /// Sets the default PoW difficulty (0 if not specified) Pow(PowArgs), + /// Sets the default fallback relays if none provided. Use this relays for + /// read and write. + Relays(RelaysArgs), } impl CommandRunner for ConfigSubcommands { async fn run(self, options: CliOptions) -> N34Result<()> { match self { Self::Pow(args) => args.run(options).await, + Self::Relays(args) => args.run(options).await, } } } diff --git a/src/cli/commands/config/relays.rs b/src/cli/commands/config/relays.rs new file mode 100644 index 0000000..3656f43 --- /dev/null +++ b/src/cli/commands/config/relays.rs @@ -0,0 +1,53 @@ +// n34 - A CLI to interact with NIP-34 and other stuff related to codes in nostr +// Copyright (C) 2025 Awiteb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use clap::Args; +use nostr::types::RelayUrl; + +use crate::{ + cli::{CliOptions, traits::CommandRunner}, + error::N34Result, +}; + +#[derive(Args, Debug)] +pub struct RelaysArgs { + /// List of relay URLs to append to fallback relays. If empty, removes all + /// fallback relays. + relays: Vec, + /// Replace existing fallback relays instead of appending new ones. + #[arg(long = "override")] + override_relays: bool, +} + +impl CommandRunner for RelaysArgs { + async fn run(self, mut options: CliOptions) -> N34Result<()> { + // FIXME: The signer is not required here + + if self.relays.is_empty() { + options.config.fallback_relays = None; + } else if self.override_relays { + options.config.fallback_relays = Some(self.relays); + } else { + let mut relays = options.config.fallback_relays.clone().unwrap_or_default(); + relays.extend(self.relays); + relays.sort_unstable(); + relays.dedup(); + options.config.fallback_relays = Some(relays); + } + + options.config.dump() + } +} diff --git a/src/cli/config.rs b/src/cli/config.rs index 667396a..ba3b20c 100644 --- a/src/cli/config.rs +++ b/src/cli/config.rs @@ -53,13 +53,16 @@ pub enum ConfigError { pub struct CliConfig { /// Path to the configuration file (not serialized) #[serde(skip)] - path: PathBuf, + path: PathBuf, /// Groups of repositories and relays. #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub sets: Vec, + pub sets: Vec, /// The default PoW difficulty #[serde(skip_serializing_if = "Option::is_none")] - pub pow: Option, + pub pow: Option, + /// List of fallback relays used if no fallback relays was provided. + #[serde(skip_serializing_if = "Option::is_none")] + pub fallback_relays: Option>, } /// A named group of repositories and relays. diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 6bd0802..156d2cd 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -29,6 +29,7 @@ pub mod types; use clap::Parser; use clap_verbosity_flag::Verbosity; +use types::RelayOrSet; pub use self::commands::*; pub use self::config::*; @@ -72,10 +73,15 @@ impl Cli { } } -/// Processes the CLI configuration and returns it if successful. +/// Processes the CLI configuration by applying fallback values from config if +/// needed. Returns the processed Cli configuration if successful. pub fn post_cli(mut cli: Cli) -> N34Result { - if cli.options.pow.is_none() && cli.options.config.pow.is_some() { - cli.options.pow = cli.options.config.pow; + cli.options.pow = cli.options.pow.or(cli.options.config.pow); + + if cli.options.relays.is_empty() { + if let Some(relays) = &cli.options.config.fallback_relays { + cli.options.relays = relays.iter().cloned().map(RelayOrSet::Relay).collect(); + } } Ok(cli)