Breaking changes for --shell (#817)

This commit is contained in:
Félix Saparelli 2024-04-20 22:58:29 +12:00 committed by GitHub
parent af24252f21
commit 317221584a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 63 additions and 63 deletions

View file

@ -19,7 +19,7 @@ _watchexec() {
case "${cmd}" in
watchexec)
opts="-w -c -o -W -r -s -k -d -p -n -E -1 -N -q -e -f -j -i -v -h -V --watch --clear --on-busy-update --watch-when-idle --restart --signal --kill --stop-signal --stop-timeout --map-signal --debounce --stdin-quit --no-vcs-ignore --no-project-ignore --no-global-ignore --no-default-ignore --no-discover-ignore --ignore-nothing --postpone --delay-run --poll --shell --no-shell-long --no-environment --emit-events-to --only-emit-events --env --no-process-group --notify --color --timings --quiet --bell --project-origin --workdir --exts --filter --filter-file --filter-prog --ignore --ignore-file --fs-events --no-meta --print-events --verbose --log-file --manual --completions --help --version [COMMAND]..."
opts="-w -c -o -W -r -s -k -d -p -n -E -1 -N -q -e -f -j -i -v -h -V --watch --clear --on-busy-update --watch-when-idle --restart --signal --kill --stop-signal --stop-timeout --map-signal --debounce --stdin-quit --no-vcs-ignore --no-project-ignore --no-global-ignore --no-default-ignore --no-discover-ignore --ignore-nothing --postpone --delay-run --poll --shell --no-environment --emit-events-to --only-emit-events --env --no-process-group --notify --color --timings --quiet --bell --project-origin --workdir --exts --filter --filter-file --filter-prog --ignore --ignore-file --fs-events --no-meta --print-events --verbose --log-file --manual --completions --help --version [COMMAND]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0

View file

@ -69,7 +69,6 @@ set edit:completion:arg-completer[watchexec] = {|@words|
cand -p 'Wait until first change before running command'
cand --postpone 'Wait until first change before running command'
cand -n 'Don''t use a shell'
cand --no-shell-long 'Don''t use a shell'
cand --no-environment 'Shorthand for ''--emit-events=none'''
cand --only-emit-events 'Only emit events to stdout, run no commands'
cand --no-process-group 'Don''t use a process group'

View file

@ -35,7 +35,6 @@ complete -c watchexec -l no-discover-ignore -d 'Don\'t discover ignore files at
complete -c watchexec -l ignore-nothing -d 'Don\'t ignore anything at all'
complete -c watchexec -s p -l postpone -d 'Wait until first change before running command'
complete -c watchexec -s n -d 'Don\'t use a shell'
complete -c watchexec -l no-shell-long -d 'Don\'t use a shell'
complete -c watchexec -l no-environment -d 'Shorthand for \'--emit-events=none\''
complete -c watchexec -l only-emit-events -d 'Only emit events to stdout, run no commands'
complete -c watchexec -l no-process-group -d 'Don\'t use a process group'

View file

@ -50,7 +50,6 @@ module completions {
--poll: string # Poll for filesystem changes
--shell: string # Use a different shell
-n # Don't use a shell
--no-shell-long # Don't use a shell
--no-environment # Shorthand for '--emit-events=none'
--emit-events-to: string@"nu-complete watchexec emit_events_to" # Configure event emission
--only-emit-events # Only emit events to stdout, run no commands

View file

@ -72,7 +72,6 @@ Register-ArgumentCompleter -Native -CommandName 'watchexec' -ScriptBlock {
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Wait until first change before running command')
[CompletionResult]::new('--postpone', 'postpone', [CompletionResultType]::ParameterName, 'Wait until first change before running command')
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Don''t use a shell')
[CompletionResult]::new('--no-shell-long', 'no-shell-long', [CompletionResultType]::ParameterName, 'Don''t use a shell')
[CompletionResult]::new('--no-environment', 'no-environment', [CompletionResultType]::ParameterName, 'Shorthand for ''--emit-events=none''')
[CompletionResult]::new('--only-emit-events', 'only-emit-events', [CompletionResultType]::ParameterName, 'Only emit events to stdout, run no commands')
[CompletionResult]::new('--no-process-group', 'no-process-group', [CompletionResultType]::ParameterName, 'Don''t use a process group')

View file

@ -66,7 +66,6 @@ _watchexec() {
'-p[Wait until first change before running command]' \
'--postpone[Wait until first change before running command]' \
'-n[Don'\''t use a shell]' \
'--no-shell-long[Don'\''t use a shell]' \
'--no-environment[Shorthand for '\''--emit-events=none'\'']' \
'(--completions --manual)--only-emit-events[Only emit events to stdout, run no commands]' \
'--no-process-group[Don'\''t use a process group]' \

View file

@ -438,18 +438,18 @@ pub struct Args {
/// Use a different shell
///
/// By default, Watchexec will use 'sh' on unix and 'cmd' (CMD.EXE) on Windows. With this, you
/// can override that and use a different shell, for example one with more features or one which
/// has your custom aliases and functions.
/// By default, Watchexec will use '$SHELL' if it's defined or a default of 'sh' on Unix-likes,
/// and either 'pwsh', 'powershell', or 'cmd' (CMD.EXE) on Windows, depending on what Watchexec
/// detects is the running shell.
///
/// With this option, you can override that and use a different shell, for example one with more
/// features or one which has your custom aliases and functions.
///
/// If the value has spaces, it is parsed as a command line, and the first word used as the
/// shell program, with the rest as arguments to the shell.
///
/// The command is run with the '-c' flag (except for 'cmd' on Windows, where it's '/C').
///
/// Note that the default shell will change at the next major release: the value of '$SHELL'
/// will be respected, falling back to 'sh' on unix and to PowerShell on Windows.
///
/// The special value 'none' can be used to disable shell use entirely. In that case, the
/// command provided to Watchexec will be parsed, with the first word being the executable and
/// the rest being the arguments, and executed directly. Note that this parsing is rudimentary,
@ -469,7 +469,7 @@ pub struct Args {
///
/// $ watchexec --shell=pwsh -- Test-Connection localhost
///
/// Use with cmd (default on Windows):
/// Use with CMD.exe:
///
/// $ watchexec --shell=cmd -- dir
///
@ -496,17 +496,6 @@ pub struct Args {
)]
pub no_shell: bool,
/// Don't use a shell
///
/// This is a deprecated alias for '--shell=none'.
#[arg(
long,
hide = true,
help_heading = OPTSET_COMMAND,
alias = "no-shell", // deprecated
)]
pub no_shell_long: bool,
/// Shorthand for '--emit-events=none'
///
/// This is the old way to disable event emission into the environment. See '--emit-events' for

View file

@ -1,7 +1,7 @@
use std::{
borrow::Cow,
collections::HashMap,
env::current_dir,
env::{current_dir, var},
ffi::{OsStr, OsString},
fs::File,
io::{IsTerminal, Write},
@ -469,35 +469,52 @@ fn interpret_command_args(args: &Args) -> Result<Arc<Command>> {
panic!("(clap) Bug: command is not present");
}
let shell = match if args.no_shell || args.no_shell_long {
let shell = if args.no_shell {
None
} else {
args.shell.as_deref().or(Some("default"))
} {
Some("") => return Err(RuntimeError::CommandShellEmptyShell).into_diagnostic(),
Some("none") | None => None,
#[cfg(windows)]
Some("default") | Some("cmd") | Some("cmd.exe") | Some("CMD") | Some("CMD.EXE") => {
Some(Shell::cmd())
}
#[cfg(not(windows))]
Some("default") => Some(Shell::new("sh")),
Some(other) => {
let sh = other.split_ascii_whitespace().collect::<Vec<_>>();
// UNWRAP: checked by Some("")
#[allow(clippy::unwrap_used)]
let (shprog, shopts) = sh.split_first().unwrap();
Some(Shell {
prog: shprog.into(),
options: shopts.iter().map(|s| (*s).to_string()).collect(),
program_option: Some(Cow::Borrowed(OsStr::new("-c"))),
let shell = args.shell.clone().or_else(|| var("SHELL").ok());
match shell
.as_deref()
.or_else(|| {
if cfg!(not(windows)) {
Some("sh")
} else if var("POWERSHELL_DISTRIBUTION_CHANNEL").is_ok()
&& (which::which("pwsh").is_ok() || which::which("pwsh.exe").is_ok())
{
trace!("detected pwsh");
Some("pwsh")
} else if var("PSModulePath").is_ok()
&& (which::which("powershell").is_ok()
|| which::which("powershell.exe").is_ok())
{
trace!("detected powershell");
Some("powershell")
} else {
Some("cmd")
}
})
.or(Some("default"))
{
Some("") => return Err(RuntimeError::CommandShellEmptyShell).into_diagnostic(),
Some("none") | None => None,
#[cfg(windows)]
Some("cmd") | Some("cmd.exe") | Some("CMD") | Some("CMD.EXE") => Some(Shell::cmd()),
Some(other) => {
let sh = other.split_ascii_whitespace().collect::<Vec<_>>();
// UNWRAP: checked by Some("")
#[allow(clippy::unwrap_used)]
let (shprog, shopts) = sh.split_first().unwrap();
Some(Shell {
prog: shprog.into(),
options: shopts.iter().map(|s| (*s).to_string()).collect(),
program_option: Some(Cow::Borrowed(OsStr::new("-c"))),
})
}
}
};

View file

@ -216,14 +216,14 @@ Aliased as \*(Aq\-\-force\-poll\*(Aq.
\fB\-\-shell\fR=\fISHELL\fR
Use a different shell
By default, Watchexec will use \*(Aqsh\*(Aq on unix and \*(Aqcmd\*(Aq (CMD.EXE) on Windows. With this, you can override that and use a different shell, for example one with more features or one which has your custom aliases and functions.
By default, Watchexec will use \*(Aq$SHELL\*(Aq if it\*(Aqs defined or a default of \*(Aqsh\*(Aq on Unix\-likes, and either \*(Aqpwsh\*(Aq, \*(Aqpowershell\*(Aq, or \*(Aqcmd\*(Aq (CMD.EXE) on Windows, depending on what Watchexec detects is the running shell.
With this option, you can override that and use a different shell, for example one with more features or one which has your custom aliases and functions.
If the value has spaces, it is parsed as a command line, and the first word used as the shell program, with the rest as arguments to the shell.
The command is run with the \*(Aq\-c\*(Aq flag (except for \*(Aqcmd\*(Aq on Windows, where it\*(Aqs \*(Aq/C\*(Aq).
Note that the default shell will change at the next major release: the value of \*(Aq$SHELL\*(Aq will be respected, falling back to \*(Aqsh\*(Aq on unix and to PowerShell on Windows.
The special value \*(Aqnone\*(Aq can be used to disable shell use entirely. In that case, the command provided to Watchexec will be parsed, with the first word being the executable and the rest being the arguments, and executed directly. Note that this parsing is rudimentary, and may not work as expected in all cases.
Using \*(Aqnone\*(Aq is a little more efficient and can enable a stricter interpretation of the input, but it also means that you can\*(Aqt use shell features like globbing, redirection, control flow, logic, or pipes.
@ -238,7 +238,7 @@ Use with powershell core:
$ watchexec \-\-shell=pwsh \-\- Test\-Connection localhost
Use with cmd (default on Windows):
Use with CMD.exe:
$ watchexec \-\-shell=cmd \-\- dir

View file

@ -348,9 +348,12 @@ Aliased as \--force-poll.
: Use a different shell
By default, Watchexec will use sh on unix and cmd (CMD.EXE) on Windows.
With this, you can override that and use a different shell, for example
one with more features or one which has your custom aliases and
By default, Watchexec will use \$SHELL if its defined or a default of sh
on Unix-likes, and either pwsh, powershell, or cmd (CMD.EXE) on Windows,
depending on what Watchexec detects is the running shell.
With this option, you can override that and use a different shell, for
example one with more features or one which has your custom aliases and
functions.
If the value has spaces, it is parsed as a command line, and the first
@ -359,10 +362,6 @@ word used as the shell program, with the rest as arguments to the shell.
The command is run with the -c flag (except for cmd on Windows, where
its /C).
Note that the default shell will change at the next major release: the
value of \$SHELL will be respected, falling back to sh on unix and to
PowerShell on Windows.
The special value none can be used to disable shell use entirely. In
that case, the command provided to Watchexec will be parsed, with the
first word being the executable and the rest being the arguments, and
@ -383,7 +382,7 @@ Use with powershell core:
\$ watchexec \--shell=pwsh \-- Test-Connection localhost
Use with cmd (default on Windows):
Use with CMD.exe:
\$ watchexec \--shell=cmd \-- dir