watchexec_supervisor/command/
conversions.rs1use std::fmt;
2
3use process_wrap::tokio::{KillOnDrop, TokioCommandWrap};
4use tokio::process::Command as TokioCommand;
5use tracing::trace;
6
7use super::{Command, Program, SpawnOptions};
8
9impl Command {
10 pub fn to_spawnable(&self) -> TokioCommandWrap {
12 trace!(program=?self.program, "constructing command");
13
14 let cmd = match &self.program {
15 Program::Exec { prog, args, .. } => {
16 let mut c = TokioCommand::new(prog);
17 c.args(args);
18 c
19 }
20
21 Program::Shell {
22 shell,
23 args,
24 command,
25 } => {
26 let mut c = TokioCommand::new(shell.prog.clone());
27
28 #[cfg(windows)]
30 {
31 for opt in &shell.options {
32 c.raw_arg(opt);
33 }
34 if let Some(progopt) = &shell.program_option {
35 c.raw_arg(progopt);
36 }
37 c.raw_arg(command);
38 for arg in args {
39 c.raw_arg(arg);
40 }
41 }
42
43 #[cfg(not(windows))]
44 {
45 c.args(shell.options.clone());
46 if let Some(progopt) = &shell.program_option {
47 c.arg(progopt);
48 }
49 c.arg(command);
50 for arg in args {
51 c.arg(arg);
52 }
53 }
54
55 c
56 }
57 };
58
59 let mut cmd = TokioCommandWrap::from(cmd);
60 cmd.wrap(KillOnDrop);
61
62 match self.options {
63 #[cfg(unix)]
64 SpawnOptions { session: true, .. } => {
65 cmd.wrap(process_wrap::tokio::ProcessSession);
66 }
67 #[cfg(unix)]
68 SpawnOptions { grouped: true, .. } => {
69 cmd.wrap(process_wrap::tokio::ProcessGroup::leader());
70 }
71 #[cfg(windows)]
72 SpawnOptions { grouped: true, .. } | SpawnOptions { session: true, .. } => {
73 cmd.wrap(process_wrap::tokio::JobObject);
74 }
75 _ => {}
76 }
77
78 #[cfg(unix)]
79 if self.options.reset_sigmask {
80 cmd.wrap(process_wrap::tokio::ResetSigmask);
81 }
82
83 cmd
84 }
85}
86
87impl fmt::Display for Program {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 Self::Exec { prog, args, .. } => {
91 write!(f, "{}", prog.display())?;
92 for arg in args {
93 write!(f, " {arg}")?;
94 }
95
96 Ok(())
97 }
98 Self::Shell { command, .. } => {
99 write!(f, "{command}")
100 }
101 }
102 }
103}
104
105impl fmt::Display for Command {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 write!(f, "{}", self.program)
108 }
109}