From 832598ceb7bfc189ffb387bbbd640df689ca78b8 Mon Sep 17 00:00:00 2001 From: Adrian Duke Date: Thu, 5 Feb 2026 14:47:46 +0000 Subject: [PATCH] cli: Warn user about implicit seeding policy To prepare for future changes, warn users if their config file currently does not explicitly specify a default seeding policy. Because there are now potentially multiple warnings generated that all relate to the configuration file, group these together and adjust the wording to be more uniform. --- .../rad-seed-policy-allow-no-scope.md | 7 ++++ .../examples/rad-warn-old-nodes.md | 8 ++-- crates/radicle-cli/src/commands/debug.rs | 2 +- .../radicle-cli/src/commands/node/control.rs | 2 +- crates/radicle-cli/src/warning.rs | 42 +++++++++++++++---- crates/radicle-cli/tests/commands.rs | 21 ++++++++++ 6 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 crates/radicle-cli/examples/rad-seed-policy-allow-no-scope.md diff --git a/crates/radicle-cli/examples/rad-seed-policy-allow-no-scope.md b/crates/radicle-cli/examples/rad-seed-policy-allow-no-scope.md new file mode 100644 index 00000000..f27a3796 --- /dev/null +++ b/crates/radicle-cli/examples/rad-seed-policy-allow-no-scope.md @@ -0,0 +1,7 @@ +We want to ensure that a warning is printed when the `scope` field is missing in the `seedingPolicy`. + +``` alice +$ rad node status +! Warning: Configuration option 'node.seedingPolicy.scope' is not set, and thus takes the value 'all' by default. The default value will change to 'followed' in a future release. Please edit your configuration file, and set it to one of ['all', 'followed'] explicitly. +[..] +``` diff --git a/crates/radicle-cli/examples/rad-warn-old-nodes.md b/crates/radicle-cli/examples/rad-warn-old-nodes.md index bbee052a..21e82d23 100644 --- a/crates/radicle-cli/examples/rad-warn-old-nodes.md +++ b/crates/radicle-cli/examples/rad-warn-old-nodes.md @@ -38,8 +38,8 @@ $ rad debug "RAD_RNG_SEED": "0" }, "warnings": [ - "Value of configuration option `node.connect` at index 0 mentions node with address 'ash.radicle.garden:8776', which has been renamed to 'rosa.radicle.xyz:8776'. Please update your configuration.", - "Value of configuration option `preferredSeeds` at index 0 mentions node with address 'seed.radicle.garden:8776', which has been renamed to 'iris.radicle.xyz:8776'. Please update your configuration." + "Value of configuration option `node.connect` at index 0 mentions node with address 'ash.radicle.garden:8776', which has been renamed to 'rosa.radicle.xyz:8776'. Please edit your configuration file to use the new address.", + "Value of configuration option `preferredSeeds` at index 0 mentions node with address 'seed.radicle.garden:8776', which has been renamed to 'iris.radicle.xyz:8776'. Please edit your configuration file to use the new address." ] } ``` @@ -48,8 +48,8 @@ Also, `rad node status` will warn us: ``` $ rad node status -! Warning: Value of configuration option `node.connect` at index 0 mentions node with address 'ash.radicle.garden:8776', which has been renamed to 'rosa.radicle.xyz:8776'. Please update your configuration. -! Warning: Value of configuration option `preferredSeeds` at index 0 mentions node with address 'seed.radicle.garden:8776', which has been renamed to 'iris.radicle.xyz:8776'. Please update your configuration. +! Warning: Value of configuration option `node.connect` at index 0 mentions node with address 'ash.radicle.garden:8776', which has been renamed to 'rosa.radicle.xyz:8776'. Please edit your configuration file to use the new address. +! Warning: Value of configuration option `preferredSeeds` at index 0 mentions node with address 'seed.radicle.garden:8776', which has been renamed to 'iris.radicle.xyz:8776'. Please edit your configuration file to use the new address. Node is stopped. To start it, run `rad node start`. ``` diff --git a/crates/radicle-cli/src/commands/debug.rs b/crates/radicle-cli/src/commands/debug.rs index da8d1dae..2564ddbc 100644 --- a/crates/radicle-cli/src/commands/debug.rs +++ b/crates/radicle-cli/src/commands/debug.rs @@ -131,7 +131,7 @@ fn stderr_of(bin: &str, args: &[&str]) -> anyhow::Result { fn collect_warnings(profile: Option<&Profile>) -> Vec { match profile { - Some(profile) => crate::warning::nodes_renamed(&profile.config), + Some(profile) => crate::warning::config_warnings(&profile.config), None => vec!["No Radicle profile found.".to_string()], } } diff --git a/crates/radicle-cli/src/commands/node/control.rs b/crates/radicle-cli/src/commands/node/control.rs index f3c10099..63e833f7 100644 --- a/crates/radicle-cli/src/commands/node/control.rs +++ b/crates/radicle-cli/src/commands/node/control.rs @@ -257,7 +257,7 @@ pub fn connect_many( } pub fn status(node: &Node, profile: &Profile) -> anyhow::Result<()> { - for warning in crate::warning::nodes_renamed(&profile.config) { + for warning in crate::warning::config_warnings(&profile.config) { term::warning(warning); } diff --git a/crates/radicle-cli/src/warning.rs b/crates/radicle-cli/src/warning.rs index 431053b6..d1804421 100644 --- a/crates/radicle-cli/src/warning.rs +++ b/crates/radicle-cli/src/warning.rs @@ -22,26 +22,52 @@ fn nodes_renamed_for_option( option: &'static str, iter: impl IntoIterator, ) -> Vec { - let mut warnings: Vec = vec![]; - - for (i, value) in iter.into_iter().enumerate() { + iter.into_iter().enumerate().fold(Vec::new(), |mut warnings, (i, value)| { let old: Address = value.into(); if let Some(new) = NODES_RENAMED.get(&old) { warnings.push(format!( - "Value of configuration option `{option}` at index {i} mentions node with address '{old}', which has been renamed to '{new}'. Please update your configuration." + "Value of configuration option `{option}` at index {i} mentions node with address '{old}', which has been renamed to '{new}'. Please edit your configuration file to use the new address." )); } - } - - warnings + warnings + }) } -pub(crate) fn nodes_renamed(config: &Config) -> Vec { +fn nodes_renamed(config: &Config) -> Vec { let mut warnings = nodes_renamed_for_option("node.connect", config.node.connect.clone()); warnings.extend(nodes_renamed_for_option( "preferredSeeds", config.preferred_seeds.clone(), )); + + warnings +} + +fn implicit_seeding_policy_allow_scope(config: &Config) -> Vec { + use radicle::node::config::DefaultSeedingPolicy; + use radicle::node::policy::Scope::*; + + let DefaultSeedingPolicy::Allow { scope } = config.node.seeding_policy else { + return vec![]; + }; + + if !scope.is_implicit() { + return vec![]; + } + + vec![format!( + "Configuration option 'node.seedingPolicy.scope' is not set, and thus takes the value '{}' by default. The default value will change to '{}' in a future release. Please edit your configuration file, and set it to one of ['{}', '{}'] explicitly.", + scope.into_inner(), + Followed, + All, + Followed, + )] +} + +pub(crate) fn config_warnings(config: &Config) -> Vec { + let mut warnings = nodes_renamed(config); + warnings.extend(implicit_seeding_policy_allow_scope(config)); + warnings } diff --git a/crates/radicle-cli/tests/commands.rs b/crates/radicle-cli/tests/commands.rs index 9af201ca..8455d98f 100644 --- a/crates/radicle-cli/tests/commands.rs +++ b/crates/radicle-cli/tests/commands.rs @@ -2872,3 +2872,24 @@ fn rad_workflow() { ) .unwrap(); } + +#[test] +fn rad_seed_policy_allow_no_scope() { + let mut environment = Environment::new(); + let alice = environment.node_with(Config { + seeding_policy: DefaultSeedingPolicy::Allow { + scope: node::config::Scope::implicit(), + }, + ..Config::test(Alias::new("alice")) + }); + + let alice = alice.spawn(); + + test( + "examples/rad-seed-policy-allow-no-scope.md", + environment.work(&alice), + Some(&alice.home), + [], + ) + .unwrap(); +}