mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 12:55:47 +02:00
feat(watch): implement --debounce flag with duration (#16187)
- fixes #16178 - `watch --debounce-ms` deprecated Co-authored-by: Luca Scherzer <luca.scherzer@de.clara.net>
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
# Security Policy
|
||||
|
||||
As a shell and programming language Nushell provides you with great powers and the potential to do dangerous things to your computer and data. Whenever there is a risk that a malicious actor can abuse a bug or a violation of documented behavior/assumptions in Nushell to harm you this is a *security* risk.
|
||||
As a shell and programming language Nushell provides you with great powers and the potential to do dangerous things to your computer and data. Whenever there is a risk that a malicious actor can abuse a bug or a violation of documented behavior/assumptions in Nushell to harm you this is a *security* risk.
|
||||
We want to fix those issues without exposing our users to unnecessary risk. Thus we want to explain our security policy.
|
||||
Additional issues may be part of *safety* where the behavior of Nushell as designed and implemented can cause unintended harm or a bug causes damage without the involvement of a third party.
|
||||
|
||||
@ -11,7 +11,7 @@ Only if you provide a strong reasoning and the necessary resources, will we cons
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you suspect that a bug or behavior of Nushell can affect security or may be potentially exploitable, please report the issue to us in private.
|
||||
If you suspect that a bug or behavior of Nushell can affect security or may be potentially exploitable, please report the issue to us in private.
|
||||
Either reach out to the core team on [our Discord server](https://discord.gg/NtAbbGn) to arrange a private channel or use the [GitHub vulnerability reporting form](https://github.com/nushell/nushell/security/advisories/new).
|
||||
Please try to answer the following questions:
|
||||
- How can we reach you for further questions?
|
||||
|
@ -6,7 +6,11 @@ use notify_debouncer_full::{
|
||||
},
|
||||
};
|
||||
use nu_engine::{ClosureEval, command_prelude::*};
|
||||
use nu_protocol::{engine::Closure, report_shell_error, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
DeprecationEntry, DeprecationType, ReportMode, engine::Closure, report_shell_error,
|
||||
shell_error::io::IoError,
|
||||
};
|
||||
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
sync::mpsc::{RecvTimeoutError, channel},
|
||||
@ -33,6 +37,16 @@ impl Command for Watch {
|
||||
vec!["watcher", "reload", "filesystem"]
|
||||
}
|
||||
|
||||
fn deprecation_info(&self) -> Vec<DeprecationEntry> {
|
||||
vec![DeprecationEntry {
|
||||
ty: DeprecationType::Flag("--debounce-ms".into()),
|
||||
report_mode: ReportMode::FirstUse,
|
||||
since: Some("0.107.0".into()),
|
||||
expected_removal: Some("0.109.0".into()),
|
||||
help: Some("`--debounce-ms` will be removed in favour of `--debounce`".into()),
|
||||
}]
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
Signature::build("watch")
|
||||
.input_output_types(vec![(Type::Nothing, Type::table())])
|
||||
@ -43,7 +57,13 @@ impl Command for Watch {
|
||||
.named(
|
||||
"debounce-ms",
|
||||
SyntaxShape::Int,
|
||||
"Debounce changes for this many milliseconds (default: 100). Adjust if you find that single writes are reported as multiple events",
|
||||
"Debounce changes for this many milliseconds (default: 100). Adjust if you find that single writes are reported as multiple events (deprecated)",
|
||||
None,
|
||||
)
|
||||
.named(
|
||||
"debounce",
|
||||
SyntaxShape::Duration,
|
||||
"Debounce changes for this duration (default: 100ms). Adjust if you find that single writes are reported as multiple events",
|
||||
Some('d'),
|
||||
)
|
||||
.named(
|
||||
@ -95,11 +115,25 @@ impl Command for Watch {
|
||||
|
||||
let quiet = call.has_flag(engine_state, stack, "quiet")?;
|
||||
|
||||
let debounce_duration_flag: Option<Spanned<i64>> =
|
||||
let debounce_duration_flag_ms: Option<Spanned<i64>> =
|
||||
call.get_flag(engine_state, stack, "debounce-ms")?;
|
||||
let debounce_duration = match debounce_duration_flag {
|
||||
Some(val) => match u64::try_from(val.item) {
|
||||
Ok(val) => Duration::from_millis(val),
|
||||
|
||||
let debounce_duration_flag: Option<Spanned<Value>> =
|
||||
call.get_flag(engine_state, stack, "debounce")?;
|
||||
|
||||
let debounce_duration: Duration = match (debounce_duration_flag, debounce_duration_flag_ms)
|
||||
{
|
||||
(None, None) => DEFAULT_WATCH_DEBOUNCE_DURATION,
|
||||
(Some(l), Some(r)) => {
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "Here".to_string(),
|
||||
left_span: l.span,
|
||||
right_message: "and here".to_string(),
|
||||
right_span: r.span,
|
||||
});
|
||||
}
|
||||
(None, Some(val)) => match u64::try_from(val.item) {
|
||||
Ok(v) => Duration::from_millis(v),
|
||||
Err(_) => {
|
||||
return Err(ShellError::TypeMismatch {
|
||||
err_message: "Debounce duration is invalid".to_string(),
|
||||
@ -107,7 +141,18 @@ impl Command for Watch {
|
||||
});
|
||||
}
|
||||
},
|
||||
None => DEFAULT_WATCH_DEBOUNCE_DURATION,
|
||||
(Some(v), None) => {
|
||||
let Value::Duration { val, .. } = v.item else {
|
||||
return Err(ShellError::TypeMismatch {
|
||||
err_message: "Debounce duration must be a duration".to_string(),
|
||||
span: v.item.span(),
|
||||
});
|
||||
};
|
||||
Duration::from_nanos(u64::try_from(val).map_err(|_| ShellError::TypeMismatch {
|
||||
err_message: "Debounce duration is invalid".to_string(),
|
||||
span: v.item.span(),
|
||||
})?)
|
||||
}
|
||||
};
|
||||
|
||||
let glob_flag: Option<Spanned<String>> = call.get_flag(engine_state, stack, "glob")?;
|
||||
@ -294,6 +339,11 @@ impl Command for Watch {
|
||||
example: r#"watch /foo/bar { |op, path| $"($op) - ($path)(char nl)" | save --append changes_in_bar.log }"#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Print file changes with a debounce time of 5 minutes",
|
||||
example: r#"watch /foo/bar --debounce 5min { |op, path| $"Registered ($op) on ($path)" | print }"#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Note: if you are looking to run a command every N units of time, this can be accomplished with a loop and sleep",
|
||||
example: r#"loop { command; sleep duration }"#,
|
||||
|
@ -89,6 +89,7 @@ pub enum Value {
|
||||
internal_span: Span,
|
||||
},
|
||||
Duration {
|
||||
/// The duration in nanoseconds.
|
||||
val: i64,
|
||||
/// note: spans are being refactored out of Value
|
||||
/// please use .span() instead of matching this span value
|
||||
|
12
toolkit.nu
12
toolkit.nu
@ -307,13 +307,13 @@ export def "check pr" [
|
||||
export def run [
|
||||
--experimental-options: oneof<list<string>, string> # enable or disable experimental options
|
||||
] {
|
||||
let experimental_options_arg = $experimental_options
|
||||
| default []
|
||||
| [$in]
|
||||
| flatten
|
||||
| str join ","
|
||||
let experimental_options_arg = $experimental_options
|
||||
| default []
|
||||
| [$in]
|
||||
| flatten
|
||||
| str join ","
|
||||
| $"[($in)]"
|
||||
|
||||
|
||||
^cargo run -- ...[
|
||||
--experimental-options $experimental_options_arg
|
||||
-e "$env.PROMPT_COMMAND_RIGHT = $'(ansi magenta_reverse)trying Nushell inside Cargo(ansi reset)'"
|
||||
|
Reference in New Issue
Block a user