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}