diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 40e731f..f96e097 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -642,6 +642,22 @@ pub struct Args { )] pub no_process_group: bool, + /// Configure how the process is wrapped + /// + /// By default, Watchexec will run the command in a process group in Unix, and in a Job Object + /// in Windows. + /// + /// Some Unix programs prefer running in a session, while others do not work in a process group. + /// + /// Use 'group' to use a process group, 'session' to use a process session, and 'none' to run + /// the command directly. On Windows, either of 'group' or 'session' will use a Job Object. + #[arg( + long, + help_heading = OPTSET_COMMAND, + value_name = "MODE", + )] + pub wrap_process: WrapMode, + /// Testing only: exit Watchexec after the first run #[arg(short = '1', hide = true)] pub once: bool, @@ -999,6 +1015,14 @@ pub enum OnBusyUpdate { Signal, } +#[derive(Clone, Copy, Debug, Default, ValueEnum)] +pub enum WrapMode { + #[default] + Group, + Session, + None, +} + #[derive(Clone, Copy, Debug, Default, ValueEnum)] pub enum ClearMode { #[default] diff --git a/crates/cli/src/config.rs b/crates/cli/src/config.rs index c3e3e01..41a4620 100644 --- a/crates/cli/src/config.rs +++ b/crates/cli/src/config.rs @@ -32,7 +32,7 @@ use watchexec_events::{Event, Keyboard, ProcessEnd, Tag}; use watchexec_signals::Signal; use crate::{ - args::{Args, ClearMode, ColourMode, EmitEvents, OnBusyUpdate, SignalMapping}, + args::{Args, ClearMode, ColourMode, EmitEvents, OnBusyUpdate, SignalMapping, WrapMode}, state::RotatingTempFile, }; use crate::{emits::events_to_simple_format, state::State}; @@ -545,7 +545,8 @@ fn interpret_command_args(args: &Args) -> Result> { Ok(Arc::new(Command { program, options: SpawnOptions { - grouped: !args.no_process_group, + grouped: matches!(args.wrap_process, WrapMode::Group), + session: matches!(args.wrap_process, WrapMode::Session), ..Default::default() }, }))