Skip to main content

radicle_cli/commands/watch/
args.rs

1use std::time;
2
3#[allow(rustdoc::broken_intra_doc_links)]
4use clap::Parser;
5
6use radicle::git;
7use radicle::git::fmt::RefString;
8use radicle::prelude::{NodeId, RepoId};
9
10const ABOUT: &str = "Wait for some state to be updated";
11
12const LONG_ABOUT: &str = r#"
13Watches a Git reference, and optionally exits when it reaches a target value.
14If no target value is passed, exits when the target changes."#;
15
16fn parse_refstr(refstr: &str) -> Result<RefString, git::fmt::Error> {
17    RefString::try_from(refstr)
18}
19
20#[derive(Parser, Debug)]
21#[command(about = ABOUT, long_about = LONG_ABOUT,disable_version_flag = true)]
22pub struct Args {
23    /// The repository to watch, defaults to `rad .`
24    #[arg(long)]
25    pub(super) repo: Option<RepoId>,
26
27    /// The fully-qualified Git reference (branch, tag, etc.) to watch
28    ///
29    /// [example value: 'refs/heads/master']
30    #[arg(long, short, alias = "ref", value_name = "REF", value_parser = parse_refstr)]
31    pub(super) refstr: git::fmt::RefString,
32
33    /// The target OID (commit hash) that when reached, will cause the command to exit
34    #[arg(long, short, value_name = "OID")]
35    pub(super) target: Option<git::Oid>,
36
37    /// The namespace under which this reference exists, defaults to the profiles' NID
38    #[arg(long, short, value_name = "NID")]
39    pub(super) node: Option<NodeId>,
40
41    /// How often, in milliseconds, to check the reference target
42    #[arg(long, short, value_name = "MILLIS", default_value_t = 1000)]
43    interval: u64,
44
45    /// Timeout, in milliseconds
46    ///
47    /// Valid arguments are for example "10s", "5min" or "2h 37min"
48    #[arg(long, value_parser = humantime::parse_duration)]
49    timeout: Option<std::time::Duration>,
50}
51
52impl Args {
53    /// Provide the interval duration in milliseconds.
54    pub(super) fn interval(&self) -> time::Duration {
55        time::Duration::from_millis(self.interval)
56    }
57
58    /// Provide the timeout duration in milliseconds.
59    pub(super) fn timeout(&self) -> time::Duration {
60        self.timeout
61            .unwrap_or_else(|| time::Duration::from_millis(u64::MAX))
62    }
63}
64
65#[cfg(test)]
66mod test {
67    use super::Args;
68    use clap::Parser;
69
70    #[test]
71    fn should_parse_ref_str() {
72        let args = Args::try_parse_from(["watch", "--ref", "refs/heads/master"]);
73        assert!(args.is_ok())
74    }
75}