radicle_cli/commands/
watch.rs1mod 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}