workspacer_cli/
watch.rs

1// ---------------- [ File: workspacer-cli/src/watch.rs ]
2crate::ix!();
3
4/// Watch for changes in a single crate or the entire workspace,
5/// rebuilding/testing on file changes until canceled.
6#[derive(Debug, StructOpt)]
7pub enum WatchSubcommand {
8    /// Watch a single crate
9    Crate {
10        /// Path to the crate directory (must contain Cargo.toml)
11        #[structopt(long = "crate")]
12        crate_name: std::path::PathBuf,
13    },
14    /// Watch an entire workspace
15    Workspace {
16        /// Path to the workspace root (must contain Cargo.toml with [workspace])
17        #[structopt(long = "path")]
18        workspace_path: std::path::PathBuf,
19    },
20}
21
22impl WatchSubcommand {
23    pub async fn run(&self) -> Result<(), WorkspaceError> {
24        match self {
25            // -----------------------------------------------------------
26            // 1) Single-crate watch
27            // -----------------------------------------------------------
28            WatchSubcommand::Crate { crate_name } => {
29                // (a) Build a CrateHandle from the user-specified path
30                let single_crate = CrateHandle::new(crate_name)
31                    .await
32                    .map_err(WorkspaceError::CrateError)?;
33
34                // (b) Build or pick a CommandRunner (here, minimal).
35                let runner = Arc::new(DefaultCommandRunner);
36
37                // (c) Create a cancellation token, so we can stop the watch loop if desired.
38                let cancel_token = CancellationToken::new();
39
40                // (d) Optional: Create a channel for receiving watch events or rebuild results.
41                let (tx, mut rx) = mpsc::channel::<Result<(), CrateError>>(10);
42
43                // (e) Start watching until canceled. This call blocks while watching changes.
44                //     You might want to spawn it in a background task instead.
45                single_crate
46                    .watch_and_reload(Some(tx), runner, cancel_token.clone())
47                    .await
48                    .map_err(WorkspaceError::CrateError)?;
49
50                // If you want to handle incoming rebuild/test results, you can do so:
51                // e.g. in a separate task or after it returns. For simplicity, do nothing here.
52
53                Ok(())
54            }
55
56            // -----------------------------------------------------------
57            // 2) Entire workspace watch
58            // -----------------------------------------------------------
59            WatchSubcommand::Workspace { workspace_path } => {
60                // (a) Build the workspace from the user-specified path
61                let ws = Workspace::<std::path::PathBuf, CrateHandle>::new(workspace_path).await?;
62
63                // (b) Build a CommandRunner (use real or mock).
64                let runner = Arc::new(DefaultCommandRunner);
65
66                // (c) Create a cancellation token
67                let cancel_token = CancellationToken::new();
68
69                // (d) Optional: Create a channel
70                let (tx, mut rx) = mpsc::channel::<Result<(), WorkspaceError>>(10);
71
72                // (e) Watch & reload until canceled
73                ws.watch_and_reload(Some(tx), runner, cancel_token.clone()).await?;
74
75                // Optionally read from `rx` to see rebuild/test results
76                // e.g., in a loop or background task.
77
78                Ok(())
79            }
80        }
81    }
82}