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