Skip to main content

radicle_cli/commands/
watch.rs

1mod args;
2
3use std::{thread, time};
4
5use anyhow::anyhow;
6
7use radicle::git;
8use radicle::git::raw::ErrorExt as _;
9use radicle::prelude::NodeId;
10use radicle::storage::{ReadRepository, ReadStorage};
11
12use crate::terminal as term;
13use crate::terminal::args::rid_or_cwd;
14
15pub use args::Args;
16
17pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
18    let profile = ctx.profile()?;
19    let storage = &profile.storage;
20    let qualified = args
21        .refstr
22        .qualified()
23        .ok_or_else(|| anyhow!("reference must be fully-qualified, eg. 'refs/heads/master'"))?;
24    let nid = args.node.unwrap_or(*profile.id());
25    let (_, rid) = rid_or_cwd(args.repo)?;
26    let repo = storage.repository(rid)?;
27    let now = time::SystemTime::now();
28    let timeout = args.timeout();
29    let interval = args.interval();
30
31    if let Some(target) = args.target {
32        while reference(&repo, &nid, &qualified)? != Some(target) {
33            thread::sleep(interval);
34            if now.elapsed()? >= timeout {
35                anyhow::bail!("timed out after {}ms", timeout.as_millis());
36            }
37        }
38    } else {
39        let initial = reference(&repo, &nid, &qualified)?;
40
41        loop {
42            thread::sleep(interval);
43            let oid = reference(&repo, &nid, &qualified)?;
44            if oid != initial {
45                term::info!("{}", oid.unwrap_or(git::Oid::ZERO_SHA1));
46                break;
47            }
48            if now.elapsed()? >= timeout {
49                anyhow::bail!("timed out after {}ms", timeout.as_millis());
50            }
51        }
52    }
53    Ok(())
54}
55
56fn reference<R: ReadRepository>(
57    repo: &R,
58    nid: &NodeId,
59    qual: &git::fmt::Qualified,
60) -> Result<Option<git::Oid>, git::raw::Error> {
61    match repo.reference_oid(nid, qual) {
62        Ok(oid) => Ok(Some(oid)),
63        Err(e) if e.is_not_found() => Ok(None),
64        Err(e) => Err(e),
65    }
66}