turtle_build/infrastructure/command_runner/
os.rs1use crate::infrastructure::{CommandError, CommandRunner};
2use async_trait::async_trait;
3use std::process::{ExitStatus, Output, Stdio};
4use tokio::{process::Command, sync::Semaphore};
5
6#[derive(Debug)]
8pub struct OsCommandRunner {
9 semaphore: Semaphore,
10}
11
12impl OsCommandRunner {
13 pub fn new(job_limit: usize) -> Self {
15 Self {
16 semaphore: Semaphore::new(job_limit),
17 }
18 }
19
20 fn create_command(command: &str) -> Command {
21 if cfg!(target_os = "windows") {
22 let components = command.split_whitespace().collect::<Vec<_>>();
23 let mut process = Command::new(components[0]);
24
25 process.args(&components[1..]);
26 process
27 } else {
28 let mut process = Command::new("sh");
29
30 process.arg("-ec").arg(command);
31 process
32 }
33 }
34}
35
36#[async_trait]
37impl CommandRunner for OsCommandRunner {
38 async fn run(&self, command: &str) -> Result<Output, CommandError> {
39 let _permit = self.semaphore.acquire().await?;
40
41 Ok(Self::create_command(command)
42 .stdin(Stdio::null())
43 .output()
44 .await?)
45 }
46
47 async fn run_with_console(&self, command: &str) -> Result<ExitStatus, CommandError> {
48 let _permit = self.semaphore.acquire().await?;
49
50 Ok(Self::create_command(command).status().await?)
52 }
53}