Skip to main content

cargo_tangle/command/dev/
status.rs

1//! `cargo-tangle dev status` — show whether the local devnet is up and where.
2
3use std::fs;
4use std::path::{Path, PathBuf};
5
6use color_eyre::eyre::Result;
7
8use crate::workspace::{TangleWorkspace, WORKSPACE_FILE};
9
10const DEV_DIR: &str = ".tangle/dev";
11
12pub fn execute() -> Result<()> {
13    let dev_dir = PathBuf::from(DEV_DIR);
14    let ws_path = Path::new(WORKSPACE_FILE);
15
16    if !dev_dir.exists() && !ws_path.exists() {
17        println!("No devnet in this directory. Run `cargo-tangle dev up` to start one.");
18        return Ok(());
19    }
20
21    if ws_path.exists() {
22        match TangleWorkspace::load(ws_path) {
23            Ok(ws) => {
24                println!("Workspace:    {}", ws.source.display());
25                println!("Active net:   {}", ws.active);
26                if let Ok(net) = ws.active_network() {
27                    println!("HTTP RPC:     {}", net.http_rpc_url);
28                    println!("WS RPC:       {}", net.ws_rpc_url);
29                    println!("Tangle:       {}", net.tangle_contract);
30                }
31                if let Some(p) = &ws.defaults.keystore_path {
32                    println!("Keystore:     {}", p.display());
33                }
34            }
35            Err(e) => eprintln!("⚠ {WORKSPACE_FILE} exists but failed to parse: {e}"),
36        }
37    }
38
39    for (label, file) in [("anvil", "anvil.pid"), ("manager", "manager.pid")] {
40        let path = dev_dir.join(file);
41        match read_pid(&path) {
42            Some(pid) if pid_alive(pid) => println!("{label:10}  running (PID {pid})"),
43            Some(pid) => println!("{label:10}  stale PID {pid} (not running)"),
44            None => println!("{label:10}  not started"),
45        }
46    }
47
48    Ok(())
49}
50
51fn read_pid(path: &Path) -> Option<u32> {
52    fs::read_to_string(path)
53        .ok()
54        .and_then(|s| s.trim().parse().ok())
55}
56
57fn pid_alive(pid: u32) -> bool {
58    use nix::sys::signal::kill;
59    use nix::unistd::Pid;
60    kill(Pid::from_raw(pid as i32), None).is_ok()
61}