Use humantime to parse timeouts
In issue
29c6c6fc8171287faa0079798ba2d6e3e7fd86f3
was noted that it would be nice to use value parsers for the timeouts in
the CLI.
This patch implements this.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Co-Authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
This commit is contained in:
parent
52e5581228
commit
99d9242122
|
|
@ -66,6 +66,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- The `TypeName` strings defined in `radicle-cob` are restricted to reflect the
|
||||
size limits on domain names as specified in
|
||||
[RFC-1035](https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4).
|
||||
- The `--timeout` flag, which is available on a number of CLI subcommands, now
|
||||
takes a human-readable duration as parameter, E.G. "9s" or "1min" instead of
|
||||
"9" or "60".
|
||||
|
||||
## 1.6.1
|
||||
|
||||
|
|
|
|||
|
|
@ -1854,6 +1854,12 @@ dependencies = [
|
|||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
|
|
@ -2939,6 +2945,7 @@ dependencies = [
|
|||
"clap_complete",
|
||||
"dunce",
|
||||
"human-panic",
|
||||
"humantime",
|
||||
"itertools",
|
||||
"log",
|
||||
"nonempty",
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ git2 = { version = "0.20.4", default-features = false, features = ["vendored-lib
|
|||
gix-hash = { version = "0.22.1", default-features = false, features = ["sha1"] }
|
||||
gix-packetline = { version = "0.21.1", default-features = false }
|
||||
human-panic = "2.0.6"
|
||||
humantime = "2.3"
|
||||
itertools = "0.14"
|
||||
lexopt = "0.3.0"
|
||||
libc = "0.2.137"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ clap = { version = "4.5.44", features = ["derive"] }
|
|||
clap_complete = "4.5"
|
||||
dunce = { workspace = true }
|
||||
human-panic.workspace = true
|
||||
humantime.workspace = true
|
||||
itertools.workspace = true
|
||||
log = { workspace = true, features = ["std"] }
|
||||
nonempty = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ When she tries to clone, one of those will fail to fetch. But the clone command
|
|||
still returns successfully.
|
||||
|
||||
```
|
||||
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --timeout 3
|
||||
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --timeout 3s
|
||||
✓ Seeding policy updated for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'followed'
|
||||
Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from the network, found 3 potential seed(s).
|
||||
✓ Target met: 1 seed(s)
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ At this point, when Alice runs `rad sync`, she will fetch Eve's fork
|
|||
since she has become a delegate:
|
||||
|
||||
``` ~alice
|
||||
$ rad sync --timeout 3
|
||||
$ rad sync --timeout 3s
|
||||
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MkvVv…Z1Ct4tD@[..]..
|
||||
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MkuPZ…xEuaPUp@[..]..
|
||||
✓ Fetched repository from 2 seed(s)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ $ rad id update --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --title "Add Bob" --des
|
|||
```
|
||||
|
||||
``` ~bob
|
||||
$ rad watch --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --node z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z -r 'refs/rad/sigrefs' -t c9a828fc2fb01f893d6e6e9e17b9092dea2b3aba -i 500 --timeout 5000
|
||||
$ rad watch --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --node z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z -r 'refs/rad/sigrefs' -t c9a828fc2fb01f893d6e6e9e17b9092dea2b3aba -i 500 --timeout 5000ms
|
||||
$ rad sync --fetch rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from the network, found 1 potential seed(s).
|
||||
✓ Target met: 1 seed(s)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ $ rad inspect --identity
|
|||
|
||||
``` ~bob
|
||||
$ rad ls --all --private
|
||||
$ rad clone rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --seed z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1
|
||||
$ rad clone rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --seed z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1s
|
||||
✓ Seeding policy updated for rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu with scope 'followed'
|
||||
Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from the network, found 1 potential seed(s).
|
||||
✓ Target met: 1 preferred seed(s).
|
||||
|
|
@ -48,7 +48,7 @@ Run `cd ./heartwood` to go to the repository directory.
|
|||
We can also use `rad seed` to seed and fetch without creating a checkout.
|
||||
|
||||
``` ~bob
|
||||
$ rad seed rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --from z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1
|
||||
$ rad seed rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --from z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1s
|
||||
✓ Seeding policy exists for rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu with scope 'followed'
|
||||
Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from the network, found 1 potential seed(s).
|
||||
✓ Target met: 1 seed(s)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Bob tries to fetch it, and even though he's connected to Alice, it fails.
|
|||
$ rad ls
|
||||
```
|
||||
``` ~bob (fail)
|
||||
$ rad clone rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --seed z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1
|
||||
$ rad clone rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --seed z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1s
|
||||
✓ Seeding policy updated for rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu with scope 'followed'
|
||||
Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from the network, found 1 potential seed(s).
|
||||
✗ Target not met: could not fetch from [z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi], and required 1 more seed(s)
|
||||
|
|
@ -20,7 +20,7 @@ the refs.
|
|||
``` ~alice
|
||||
$ rad id update --title "Allow Bob" --description "" --allow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk -q
|
||||
...
|
||||
$ rad sync --announce --timeout 3
|
||||
$ rad sync --announce --timeout 3s
|
||||
✓ Synced with 1 seed(s)
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::time;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
|
|
@ -31,15 +30,17 @@ pub(super) struct SyncArgs {
|
|||
#[arg(short, long = "seed", value_name = "NID", action = clap::ArgAction::Append)]
|
||||
seeds: Vec<NodeId>,
|
||||
|
||||
/// Timeout for fetching repository in seconds
|
||||
#[arg(long, default_value_t = 9, value_name = "SECS")]
|
||||
timeout: usize,
|
||||
/// Timeout for fetching repository
|
||||
///
|
||||
/// Valid arguments are for example "10s", "5min" or "2h 37min"
|
||||
#[arg(long, value_parser = humantime::parse_duration, default_value = "9s")]
|
||||
timeout: std::time::Duration,
|
||||
}
|
||||
|
||||
impl From<SyncArgs> for SyncSettings {
|
||||
fn from(args: SyncArgs) -> Self {
|
||||
SyncSettings {
|
||||
timeout: time::Duration::from_secs(args.timeout as u64),
|
||||
timeout: args.timeout,
|
||||
seeds: args.seeds.into_iter().collect(),
|
||||
..SyncSettings::default()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
|
||||
match command {
|
||||
Command::Connect { addr, timeout } => {
|
||||
let timeout = timeout
|
||||
.map(time::Duration::from_secs)
|
||||
.unwrap_or(time::Duration::MAX);
|
||||
let timeout = timeout.unwrap_or(time::Duration::MAX);
|
||||
match addr {
|
||||
Addr::Peer(addr) => control::connect(&mut node, addr.id, addr.addr, timeout)?,
|
||||
Addr::Node(nid) => {
|
||||
|
|
@ -70,9 +68,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
}
|
||||
Command::Events { timeout, count } => {
|
||||
let count = count.unwrap_or(usize::MAX);
|
||||
let timeout = timeout
|
||||
.map(time::Duration::from_secs)
|
||||
.unwrap_or(time::Duration::MAX);
|
||||
let timeout = timeout.unwrap_or(time::Duration::MAX);
|
||||
|
||||
events::run(node, count, timeout)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,8 +105,10 @@ pub(super) enum Command {
|
|||
addr: Addr,
|
||||
|
||||
/// How long to wait for the connection to be established
|
||||
#[arg(long, value_name = "SECS")]
|
||||
timeout: Option<u64>,
|
||||
///
|
||||
/// Valid arguments are for example "10s", "5min" or "2h 37min"
|
||||
#[arg(long, value_parser = humantime::parse_duration)]
|
||||
timeout: Option<std::time::Duration>,
|
||||
},
|
||||
|
||||
/// Show the config
|
||||
|
|
@ -128,8 +130,10 @@ pub(super) enum Command {
|
|||
/// If no timeout or count is specified, it will run indefinitely.
|
||||
Events {
|
||||
/// How long to wait to receive an event before giving up
|
||||
#[arg(long, value_name = "SECS")]
|
||||
timeout: Option<u64>,
|
||||
///
|
||||
/// Valid arguments are for example "10s", "5min" or "2h 37min"
|
||||
#[arg(long, value_parser = humantime::parse_duration)]
|
||||
timeout: Option<std::time::Duration>,
|
||||
|
||||
/// Exit after <COUNT> events
|
||||
#[arg(long, short = 'n')]
|
||||
|
|
|
|||
|
|
@ -43,8 +43,10 @@ pub struct Args {
|
|||
pub(super) from: Vec<NodeId>,
|
||||
|
||||
/// Fetch timeout in seconds
|
||||
#[arg(long, short, value_name = "SECS", default_value_t = 9)]
|
||||
timeout: u64,
|
||||
///
|
||||
/// Valid arguments are for example "10s", "5min" or "2h 37min"
|
||||
#[arg(long, short, value_parser = humantime::parse_duration, default_value = "9s")]
|
||||
timeout: std::time::Duration,
|
||||
|
||||
/// Peer follow scope for this repository
|
||||
#[arg(long, value_parser = terminal::args::ScopeParser)]
|
||||
|
|
@ -86,7 +88,7 @@ impl From<Args> for Operation {
|
|||
|
||||
impl Args {
|
||||
fn timeout(&self) -> time::Duration {
|
||||
time::Duration::from_secs(self.timeout)
|
||||
self.timeout
|
||||
}
|
||||
|
||||
fn should_fetch(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -89,15 +89,17 @@ pub(super) struct SyncArgs {
|
|||
)]
|
||||
seeds: Vec<NodeId>,
|
||||
|
||||
/// How many seconds to wait while synchronizing
|
||||
/// How long to wait while synchronizing
|
||||
///
|
||||
/// Valid arguments are for example "10s", "5min" or "2h 37min"
|
||||
#[arg(
|
||||
long,
|
||||
short,
|
||||
default_value_t = 9,
|
||||
value_name = "SECS",
|
||||
default_value = "9s",
|
||||
value_parser = humantime::parse_duration,
|
||||
conflicts_with = "inventory"
|
||||
)]
|
||||
timeout: u64,
|
||||
timeout: std::time::Duration,
|
||||
|
||||
/// The repository to perform the synchronizing for [default: cwd]
|
||||
rid: Option<RepoId>,
|
||||
|
|
@ -146,7 +148,7 @@ impl SyncArgs {
|
|||
}
|
||||
|
||||
fn timeout(&self) -> time::Duration {
|
||||
time::Duration::from_secs(self.timeout)
|
||||
self.timeout
|
||||
}
|
||||
|
||||
fn replication(&self) -> sync::ReplicationFactor {
|
||||
|
|
|
|||
|
|
@ -43,8 +43,10 @@ pub struct Args {
|
|||
interval: u64,
|
||||
|
||||
/// Timeout, in milliseconds
|
||||
#[arg(long, value_name = "MILLIS")]
|
||||
timeout: Option<u64>,
|
||||
///
|
||||
/// Valid arguments are for example "10s", "5min" or "2h 37min"
|
||||
#[arg(long, value_parser = humantime::parse_duration)]
|
||||
timeout: Option<std::time::Duration>,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
|
|
@ -55,7 +57,8 @@ impl Args {
|
|||
|
||||
/// Provide the timeout duration in milliseconds.
|
||||
pub(super) fn timeout(&self) -> time::Duration {
|
||||
time::Duration::from_millis(self.timeout.unwrap_or(u64::MAX))
|
||||
self.timeout
|
||||
.unwrap_or_else(|| time::Duration::from_millis(u64::MAX))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue