summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/flags.rs90
-rw-r--r--cli/main.rs18
-rw-r--r--cli/tests/integration/watcher_tests.rs41
-rw-r--r--cli/tools/standalone.rs2
4 files changed, 123 insertions, 28 deletions
diff --git a/cli/flags.rs b/cli/flags.rs
index a879be299..452c2fd9a 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -251,7 +251,7 @@ pub struct Flags {
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
pub v8_flags: Vec<String>,
pub version: bool,
- pub watch: bool,
+ pub watch: Option<Vec<PathBuf>>,
}
fn join_paths(allowlist: &[PathBuf], d: &str) -> String {
@@ -549,7 +549,7 @@ fn bundle_subcommand<'a, 'b>() -> App<'a, 'b> {
.required(true),
)
.arg(Arg::with_name("out_file").takes_value(true).required(false))
- .arg(watch_arg())
+ .arg(watch_arg(false))
.about("Bundle module and dependencies into single file")
.long_about(
"Output a single JavaScript file with all dependencies.
@@ -882,7 +882,7 @@ Ignore formatting a file by adding an ignore comment at the top of the file:
.multiple(true)
.required(false),
)
- .arg(watch_arg())
+ .arg(watch_arg(false))
.arg(
Arg::with_name("options-use-tabs")
.long("options-use-tabs")
@@ -1158,7 +1158,7 @@ Ignore linting a file by adding an ignore comment at the top of the file:
.multiple(true)
.required(false),
)
- .arg(watch_arg())
+ .arg(watch_arg(false))
}
fn repl_subcommand<'a, 'b>() -> App<'a, 'b> {
@@ -1177,7 +1177,7 @@ fn repl_subcommand<'a, 'b>() -> App<'a, 'b> {
fn run_subcommand<'a, 'b>() -> App<'a, 'b> {
runtime_args(SubCommand::with_name("run"), true, true)
.arg(
- watch_arg()
+ watch_arg(true)
.conflicts_with("inspect")
.conflicts_with("inspect-brk"),
)
@@ -1305,7 +1305,7 @@ fn test_subcommand<'a, 'b>() -> App<'a, 'b> {
.multiple(true),
)
.arg(
- watch_arg()
+ watch_arg(false)
.conflicts_with("no-run")
.conflicts_with("coverage"),
)
@@ -1640,14 +1640,29 @@ fn compat_arg<'a, 'b>() -> Arg<'a, 'b> {
.help("Node compatibility mode. Currently only enables built-in node modules like 'fs' and globals like 'process'.")
}
-fn watch_arg<'a, 'b>() -> Arg<'a, 'b> {
- Arg::with_name("watch")
+fn watch_arg<'a, 'b>(takes_files: bool) -> Arg<'a, 'b> {
+ let arg = Arg::with_name("watch")
.long("watch")
- .help("UNSTABLE: Watch for file changes and restart process automatically")
- .long_help(
+ .help("UNSTABLE: Watch for file changes and restart process automatically");
+
+ if takes_files {
+ arg
+ .value_name("FILES")
+ .min_values(0)
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .long_help(
+ "UNSTABLE: Watch for file changes and restart process automatically.
+Local files from entry point module graph are watched by default.
+Additional paths might be watched by passing them as arguments to this flag.",
+ )
+ } else {
+ arg.long_help(
"UNSTABLE: Watch for file changes and restart process automatically.
Only local files from entry point module graph are watched.",
)
+ }
}
fn no_check_arg<'a, 'b>() -> Arg<'a, 'b> {
@@ -1743,7 +1758,7 @@ fn bundle_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
None
};
- flags.watch = matches.is_present("watch");
+ watch_arg_parse(flags, matches, false);
flags.subcommand = DenoSubcommand::Bundle(BundleFlags {
source_file,
@@ -1874,7 +1889,7 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
config_arg_parse(flags, matches);
- flags.watch = matches.is_present("watch");
+ watch_arg_parse(flags, matches, false);
let files = match matches.values_of("files") {
Some(f) => f.map(PathBuf::from).collect(),
None => vec![],
@@ -1996,7 +2011,7 @@ fn lsp_parse(flags: &mut Flags, _matches: &clap::ArgMatches) {
fn lint_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
config_arg_parse(flags, matches);
- flags.watch = matches.is_present("watch");
+ watch_arg_parse(flags, matches, false);
let files = match matches.values_of("files") {
Some(f) => f.map(PathBuf::from).collect(),
None => vec![],
@@ -2061,7 +2076,7 @@ fn run_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.argv.push(v);
}
- flags.watch = matches.is_present("watch");
+ watch_arg_parse(flags, matches, true);
flags.subcommand = DenoSubcommand::Run(RunFlags { script });
}
@@ -2135,7 +2150,7 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
};
flags.coverage_dir = matches.value_of("coverage").map(String::from);
- flags.watch = matches.is_present("watch");
+ watch_arg_parse(flags, matches, false);
flags.subcommand = DenoSubcommand::Test(TestFlags {
no_run,
doc,
@@ -2409,6 +2424,20 @@ fn inspect_arg_validate(val: String) -> Result<(), String> {
}
}
+fn watch_arg_parse(
+ flags: &mut Flags,
+ matches: &clap::ArgMatches,
+ allow_extra: bool,
+) {
+ if allow_extra {
+ if let Some(f) = matches.values_of("watch") {
+ flags.watch = Some(f.map(PathBuf::from).collect());
+ }
+ } else if matches.is_present("watch") {
+ flags.watch = Some(vec![]);
+ }
+}
+
// TODO(ry) move this to utility module and add test.
/// Strips fragment part of URL. Panics on bad URL.
pub fn resolve_urls(urls: Vec<String>) -> Vec<String> {
@@ -2513,7 +2542,24 @@ mod tests {
subcommand: DenoSubcommand::Run(RunFlags {
script: "script.ts".to_string(),
}),
- watch: true,
+ watch: Some(vec![]),
+ ..Flags::default()
+ }
+ );
+ }
+
+ #[test]
+ fn run_watch_with_external() {
+ let r =
+ flags_from_vec(svec!["deno", "run", "--watch=file1,file2", "script.ts"]);
+ let flags = r.unwrap();
+ assert_eq!(
+ flags,
+ Flags {
+ subcommand: DenoSubcommand::Run(RunFlags {
+ script: "script.ts".to_string(),
+ }),
+ watch: Some(vec![PathBuf::from("file1"), PathBuf::from("file2")]),
..Flags::default()
}
);
@@ -2746,7 +2792,7 @@ mod tests {
single_quote: None,
prose_wrap: None,
}),
- watch: true,
+ watch: Some(vec![]),
..Flags::default()
}
);
@@ -2773,7 +2819,7 @@ mod tests {
single_quote: None,
prose_wrap: None,
}),
- watch: true,
+ watch: Some(vec![]),
..Flags::default()
}
);
@@ -2821,7 +2867,7 @@ mod tests {
prose_wrap: None,
}),
config_path: Some("deno.jsonc".to_string()),
- watch: true,
+ watch: Some(vec![]),
..Flags::default()
}
);
@@ -3543,7 +3589,7 @@ mod tests {
source_file: "source.ts".to_string(),
out_file: None,
}),
- watch: true,
+ watch: Some(vec![]),
..Flags::default()
}
)
@@ -4280,7 +4326,7 @@ mod tests {
ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
}),
- watch: false,
+ watch: None,
..Flags::default()
}
);
@@ -4303,7 +4349,7 @@ mod tests {
ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
}),
- watch: true,
+ watch: Some(vec![]),
..Flags::default()
}
);
diff --git a/cli/main.rs b/cli/main.rs
index 891aa1ac5..bffe6f329 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -577,7 +577,8 @@ async fn lint_command(
None
};
- tools::lint::lint(maybe_lint_config, lint_flags, flags.watch).await?;
+ tools::lint::lint(maybe_lint_config, lint_flags, flags.watch.is_some())
+ .await?;
Ok(0)
}
@@ -894,7 +895,7 @@ async fn bundle_command(
}
};
- if flags.watch {
+ if flags.watch.is_some() {
file_watcher::watch_func(resolver, operation, "Bundle").await?;
} else {
let module_graph =
@@ -943,7 +944,8 @@ async fn format_command(
return Ok(0);
}
- tools::fmt::format(fmt_flags, flags.watch, maybe_fmt_config).await?;
+ tools::fmt::format(fmt_flags, flags.watch.is_some(), maybe_fmt_config)
+ .await?;
Ok(0)
}
@@ -1011,6 +1013,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
let script1 = script.clone();
let script2 = script.clone();
let flags = flags.clone();
+ let watch_flag = flags.watch.clone();
async move {
let main_module = resolve_url_or_path(&script1)?;
let ps = ProcState::build(flags).await?;
@@ -1067,6 +1070,11 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
})
.collect();
+ // Add the extra files listed in the watch flag
+ if let Some(watch_paths) = watch_flag {
+ paths_to_watch.extend(watch_paths);
+ }
+
if let Some(import_map) = ps.flags.import_map_path.as_ref() {
paths_to_watch
.push(fs_util::resolve_from_cwd(std::path::Path::new(import_map))?);
@@ -1180,7 +1188,7 @@ async fn run_command(
return run_from_stdin(flags).await;
}
- if flags.watch {
+ if flags.watch.is_some() {
return run_with_watch(flags, run_flags.script).await;
}
@@ -1294,7 +1302,7 @@ async fn test_command(
);
}
- if flags.watch {
+ if flags.watch.is_some() {
tools::test::run_tests_with_watch(
flags,
test_flags.include,
diff --git a/cli/tests/integration/watcher_tests.rs b/cli/tests/integration/watcher_tests.rs
index ddfccd837..02367d780 100644
--- a/cli/tests/integration/watcher_tests.rs
+++ b/cli/tests/integration/watcher_tests.rs
@@ -576,6 +576,47 @@ fn run_watch() {
}
#[test]
+fn run_watch_external_watch_files() {
+ let t = TempDir::new().unwrap();
+ let file_to_watch = t.path().join("file_to_watch.js");
+ write(&file_to_watch, "console.log('Hello world');").unwrap();
+
+ let external_file_to_watch = t.path().join("external_file_to_watch.txt");
+ write(&external_file_to_watch, "Hello world").unwrap();
+
+ let mut watch_arg = "--watch=".to_owned();
+ let external_file_to_watch_str = external_file_to_watch
+ .clone()
+ .into_os_string()
+ .into_string()
+ .unwrap();
+ watch_arg.push_str(&external_file_to_watch_str);
+
+ let mut child = util::deno_cmd()
+ .current_dir(util::testdata_path())
+ .arg("run")
+ .arg(watch_arg)
+ .arg("--unstable")
+ .arg(&file_to_watch)
+ .env("NO_COLOR", "1")
+ .stdout(std::process::Stdio::piped())
+ .stderr(std::process::Stdio::piped())
+ .spawn()
+ .unwrap();
+ let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
+
+ assert_contains!(stdout_lines.next().unwrap(), "Hello world");
+ wait_for("Process finished", &mut stderr_lines);
+
+ // Change content of the external file
+ write(&external_file_to_watch, "Hello world2").unwrap();
+
+ assert_contains!(stderr_lines.next().unwrap(), "Restarting");
+ wait_for("Process finished", &mut stderr_lines);
+ check_alive_then_kill(child);
+}
+
+#[test]
fn run_watch_load_unload_events() {
let t = TempDir::new().unwrap();
let file_to_watch = t.path().join("file_to_watch.js");
diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs
index d8ec14dc6..2277c7697 100644
--- a/cli/tools/standalone.rs
+++ b/cli/tools/standalone.rs
@@ -239,6 +239,6 @@ pub fn compile_to_runtime_flags(
unstable: flags.unstable,
v8_flags: flags.v8_flags,
version: false,
- watch: false,
+ watch: None,
})
}