cargo_e/
e_bacon.rs

1// src/e_bacon.rs
2
3use std::error::Error;
4use std::path::Path;
5use std::process::Command;
6
7use crate::e_target::CargoTarget;
8
9// src/e_bacon.rs
10
11// #[cfg(windows)]
12// use std::os::windows::io::AsRawHandle;
13
14/// Runs the "bacon" command on the given sample in detached mode,
15/// capturing the output (stdout and stderr) into "output_bacon.txt".
16/// It passes the project directory (derived from the sample’s manifest_path)
17/// via the "--path" flag and appends any extra arguments.
18///
19/// On Windows, if the environment variable DEBUG_BACON is set, it uses `/K` and echoes
20/// the folder parameter so that you can inspect it; otherwise it uses normal detached flags.
21pub fn run_bacon(sample: &CargoTarget, _extra_args: &[String]) -> Result<(), Box<dyn Error>> {
22    println!("Running bacon for sample: {}", sample.name);
23
24    // Determine the project directory from the sample's manifest_path.
25    let manifest_path = Path::new(&sample.manifest_path);
26    let project_dir = manifest_path.parent().unwrap_or(manifest_path);
27
28    let mut cmd = Command::new("cmd");
29    let args = &[
30        "/c",
31        "START",
32        "",
33        "bacon",
34        &format!("--path={}", project_dir.to_str().unwrap_or_default()),
35    ];
36    cmd.args(args);
37
38    // Spawn the bacon process detached. We do not wait on it.
39    let child = cmd.spawn()?;
40    std::mem::forget(child);
41
42    // crossterm::terminal::enable_raw_mode()?;
43    // crossterm::execute!(std::io::stdout(), crossterm::terminal::EnterAlternateScreen, crossterm::event::EnableMouseCapture)?;
44    Ok(())
45}
46
47// /// Runs the "bacon" command on the given sample in detached mode,
48// /// capturing the output (stdout and stderr) into "output_bacon.txt".
49// /// It passes the project directory (derived from the sample’s manifest_path)
50// /// via the "--path" flag and appends any extra arguments.
51// pub fn run_bacon(sample: &Example, extra_args: &[String]) -> Result<(), Box<dyn Error>> {
52//     println!("Running bacon for sample: {}", sample.name);
53
54//     // Determine the project directory from the sample's manifest path.
55//     let manifest_path = Path::new(&sample.manifest_path);
56//     let project_dir = manifest_path.parent().unwrap_or(manifest_path);
57
58//     // Build the command.
59//     let mut cmd = Command::new("bacon");
60//     cmd.args(&["--path", project_dir.to_str().unwrap_or_default()]);
61//     if !extra_args.is_empty() {
62//         cmd.args(extra_args);
63//     }
64
65//     // Open an output file to capture the output.
66//     // This file will be created (or overwritten) in the current working directory.
67//     let output_file = std::fs::File::create("output_bacon.txt")?;
68
69//     // Redirect stdout and stderr to the output file.
70//     cmd.stdout(Stdio::from(output_file.try_clone()?))
71//        .stderr(Stdio::from(output_file));
72
73//     // Platform-specific process detachment.
74//     #[cfg(windows)]
75//     {
76//         // DETACHED_PROCESS (0x00000008) and CREATE_NEW_PROCESS_GROUP (0x00000200)
77//         // are required on Windows to detach the child process.
78//         const DETACHED_PROCESS: u32 = 0x00000008;
79//         const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
80//         cmd.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP);
81//     }
82//     #[cfg(not(windows))]
83//     {
84//         // On Unix-like systems, simply redirecting the standard I/O is enough to detach.
85//         // (Optionally you could also use a daemonizing library or fork the process.)
86//     }
87
88//     // Spawn the bacon process detached. We do not wait on it.
89//     let _child = cmd.spawn()?;
90//     println!("Bacon process detached; output is captured in 'output_bacon.txt'.");
91//     Ok(())
92// }
93
94// src/e_bacon.rs
95
96// pub fn run_bacon(sample: &Example, extra_args: &[String]) -> Result<(), Box<dyn Error>> {
97//     println!("Running bacon for sample: {}", sample.name);
98//     // Determine the project directory from the sample's manifest_path.
99//     let manifest_path = std::path::Path::new(&sample.manifest_path);
100//     let project_dir = manifest_path.parent().unwrap_or(manifest_path);
101//     let mut cmd = Command::new("bacon");
102//     cmd.args(&["--path", project_dir.to_str().unwrap_or_default()]);
103//     if !extra_args.is_empty() {
104//         cmd.args(extra_args);
105//     }
106
107//     // Detach on Windows.
108//     #[cfg(windows)]
109//     {
110//         const DETACHED_PROCESS: u32 = 0x00000008;
111//         const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
112//         cmd.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP);
113//     }
114
115//     // On Unix-like systems, detach by redirecting standard I/O.
116//     #[cfg(not(windows))]
117//     {
118//         cmd.stdin(Stdio::null())
119//             .stdout(Stdio::null())
120//             .stderr(Stdio::null());
121//     }
122
123//     // Spawn the bacon process (detached).
124//     let _child = cmd.spawn()?;
125//     println!("Bacon process detached.");
126//     Ok(())
127// }
128
129#[cfg(test)]
130mod tests {
131    use assert_cmd::Command;
132    use predicates::prelude::*;
133    // use regex::Regex;
134    // use std::process::Command as StdCommand;
135
136    #[test]
137    fn test_bacon_version() {
138        // Create a command for the binary "bacon" that is assumed to be in the environment.
139        Command::new("bacon")
140            .arg("--version")
141            .assert()
142            .stdout(predicate::str::is_match(r"^bacon\s+\d+\.\d+\.\d+").unwrap());
143    }
144
145    #[test]
146    fn test_bacon_help() {
147        Command::new("bacon")
148            .arg("--help")
149            .assert()
150            .stdout(predicate::str::contains("Usage:"));
151    }
152}