mirror of
https://github.com/denoland/deno.git
synced 2025-10-01 22:51:14 +00:00
feat(cli): add "--no-clear-screen" flag (#13454)
This commit adds "--no-clear-screen" flag which can be used with "--watch" flag to disable clearing of terminal screen on each file change.
This commit is contained in:
parent
3e566bb457
commit
5490cfed20
8 changed files with 321 additions and 37 deletions
|
@ -91,18 +91,19 @@ where
|
||||||
paths_to_watch,
|
paths_to_watch,
|
||||||
result,
|
result,
|
||||||
} => {
|
} => {
|
||||||
// Clear screen first
|
|
||||||
eprint!("{}", CLEAR_SCREEN);
|
|
||||||
info!(
|
|
||||||
"{} File change detected! Restarting!",
|
|
||||||
colors::intense_blue("Watcher"),
|
|
||||||
);
|
|
||||||
return (paths_to_watch, result);
|
return (paths_to_watch, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PrintConfig {
|
||||||
|
/// printing watcher status to terminal.
|
||||||
|
pub job_name: String,
|
||||||
|
/// determine whether to clear the terminal screen
|
||||||
|
pub clear_screen: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a file watcher, which will call `resolver` with every file change.
|
/// Creates a file watcher, which will call `resolver` with every file change.
|
||||||
///
|
///
|
||||||
/// - `resolver` is used for resolving file paths to be watched at every restarting
|
/// - `resolver` is used for resolving file paths to be watched at every restarting
|
||||||
|
@ -113,12 +114,10 @@ where
|
||||||
/// - `operation` is the actual operation we want to run every time the watcher detects file
|
/// - `operation` is the actual operation we want to run every time the watcher detects file
|
||||||
/// changes. For example, in the case where we would like to bundle, then `operation` would
|
/// changes. For example, in the case where we would like to bundle, then `operation` would
|
||||||
/// have the logic for it like bundling the code.
|
/// have the logic for it like bundling the code.
|
||||||
///
|
|
||||||
/// - `job_name` is just used for printing watcher status to terminal.
|
|
||||||
pub async fn watch_func<R, O, T, F1, F2>(
|
pub async fn watch_func<R, O, T, F1, F2>(
|
||||||
mut resolver: R,
|
mut resolver: R,
|
||||||
mut operation: O,
|
mut operation: O,
|
||||||
job_name: &str,
|
print_config: PrintConfig,
|
||||||
) -> Result<(), AnyError>
|
) -> Result<(), AnyError>
|
||||||
where
|
where
|
||||||
R: FnMut(Option<Vec<PathBuf>>) -> F1,
|
R: FnMut(Option<Vec<PathBuf>>) -> F1,
|
||||||
|
@ -128,11 +127,26 @@ where
|
||||||
{
|
{
|
||||||
let (sender, mut receiver) = DebouncedReceiver::new_with_sender();
|
let (sender, mut receiver) = DebouncedReceiver::new_with_sender();
|
||||||
|
|
||||||
|
let PrintConfig {
|
||||||
|
job_name,
|
||||||
|
clear_screen,
|
||||||
|
} = print_config;
|
||||||
|
|
||||||
// Store previous data. If module resolution fails at some point, the watcher will try to
|
// Store previous data. If module resolution fails at some point, the watcher will try to
|
||||||
// continue watching files using these data.
|
// continue watching files using these data.
|
||||||
let mut paths_to_watch;
|
let mut paths_to_watch;
|
||||||
let mut resolution_result;
|
let mut resolution_result;
|
||||||
|
|
||||||
|
let print_after_restart = || {
|
||||||
|
if clear_screen {
|
||||||
|
eprint!("{}", CLEAR_SCREEN);
|
||||||
|
}
|
||||||
|
info!(
|
||||||
|
"{} File change detected! Restarting!",
|
||||||
|
colors::intense_blue("Watcher"),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
match resolver(None).await {
|
match resolver(None).await {
|
||||||
ResolutionResult::Ignore => {
|
ResolutionResult::Ignore => {
|
||||||
// The only situation where it makes sense to ignore the initial 'change'
|
// The only situation where it makes sense to ignore the initial 'change'
|
||||||
|
@ -149,6 +163,8 @@ where
|
||||||
let (paths, result) = next_restart(&mut resolver, &mut receiver).await;
|
let (paths, result) = next_restart(&mut resolver, &mut receiver).await;
|
||||||
paths_to_watch = paths;
|
paths_to_watch = paths;
|
||||||
resolution_result = result;
|
resolution_result = result;
|
||||||
|
|
||||||
|
print_after_restart();
|
||||||
}
|
}
|
||||||
ResolutionResult::Restart {
|
ResolutionResult::Restart {
|
||||||
paths_to_watch: paths,
|
paths_to_watch: paths,
|
||||||
|
@ -159,8 +175,10 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clear screen first
|
if clear_screen {
|
||||||
eprint!("{}", CLEAR_SCREEN);
|
eprint!("{}", CLEAR_SCREEN);
|
||||||
|
}
|
||||||
|
|
||||||
info!("{} {} started.", colors::intense_blue("Watcher"), job_name,);
|
info!("{} {} started.", colors::intense_blue("Watcher"), job_name,);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -175,6 +193,8 @@ where
|
||||||
paths_to_watch = paths;
|
paths_to_watch = paths;
|
||||||
}
|
}
|
||||||
resolution_result = result;
|
resolution_result = result;
|
||||||
|
|
||||||
|
print_after_restart();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
_ = fut => {},
|
_ = fut => {},
|
||||||
|
@ -202,6 +222,8 @@ where
|
||||||
}
|
}
|
||||||
resolution_result = result;
|
resolution_result = result;
|
||||||
|
|
||||||
|
print_after_restart();
|
||||||
|
|
||||||
drop(watcher);
|
drop(watcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
178
cli/flags.rs
178
cli/flags.rs
|
@ -254,6 +254,7 @@ pub struct Flags {
|
||||||
pub v8_flags: Vec<String>,
|
pub v8_flags: Vec<String>,
|
||||||
pub version: bool,
|
pub version: bool,
|
||||||
pub watch: Option<Vec<PathBuf>>,
|
pub watch: Option<Vec<PathBuf>>,
|
||||||
|
pub no_clear_screen: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join_paths(allowlist: &[PathBuf], d: &str) -> String {
|
fn join_paths(allowlist: &[PathBuf], d: &str) -> String {
|
||||||
|
@ -561,6 +562,7 @@ fn bundle_subcommand<'a>() -> App<'a> {
|
||||||
.arg(Arg::new("source_file").takes_value(true).required(true))
|
.arg(Arg::new("source_file").takes_value(true).required(true))
|
||||||
.arg(Arg::new("out_file").takes_value(true).required(false))
|
.arg(Arg::new("out_file").takes_value(true).required(false))
|
||||||
.arg(watch_arg(false))
|
.arg(watch_arg(false))
|
||||||
|
.arg(no_clear_screen_arg())
|
||||||
.about("Bundle module and dependencies into single file")
|
.about("Bundle module and dependencies into single file")
|
||||||
.long_about(
|
.long_about(
|
||||||
"Output a single JavaScript file with all dependencies.
|
"Output a single JavaScript file with all dependencies.
|
||||||
|
@ -900,6 +902,7 @@ Ignore formatting a file by adding an ignore comment at the top of the file:
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
.arg(watch_arg(false))
|
.arg(watch_arg(false))
|
||||||
|
.arg(no_clear_screen_arg())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("options-use-tabs")
|
Arg::new("options-use-tabs")
|
||||||
.long("options-use-tabs")
|
.long("options-use-tabs")
|
||||||
|
@ -1169,6 +1172,7 @@ Ignore linting a file by adding an ignore comment at the top of the file:
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
.arg(watch_arg(false))
|
.arg(watch_arg(false))
|
||||||
|
.arg(no_clear_screen_arg())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repl_subcommand<'a>() -> App<'a> {
|
fn repl_subcommand<'a>() -> App<'a> {
|
||||||
|
@ -1191,6 +1195,7 @@ fn run_subcommand<'a>() -> App<'a> {
|
||||||
.conflicts_with("inspect")
|
.conflicts_with("inspect")
|
||||||
.conflicts_with("inspect-brk"),
|
.conflicts_with("inspect-brk"),
|
||||||
)
|
)
|
||||||
|
.arg(no_clear_screen_arg())
|
||||||
.setting(AppSettings::TrailingVarArg)
|
.setting(AppSettings::TrailingVarArg)
|
||||||
.arg(script_arg().required(true))
|
.arg(script_arg().required(true))
|
||||||
.about("Run a JavaScript or TypeScript program")
|
.about("Run a JavaScript or TypeScript program")
|
||||||
|
@ -1320,6 +1325,7 @@ fn test_subcommand<'a>() -> App<'a> {
|
||||||
.conflicts_with("no-run")
|
.conflicts_with("no-run")
|
||||||
.conflicts_with("coverage"),
|
.conflicts_with("coverage"),
|
||||||
)
|
)
|
||||||
|
.arg(no_clear_screen_arg())
|
||||||
.arg(script_arg().last(true))
|
.arg(script_arg().last(true))
|
||||||
.about("Run tests")
|
.about("Run tests")
|
||||||
.long_about(
|
.long_about(
|
||||||
|
@ -1672,6 +1678,13 @@ Only local files from entry point module graph are watched.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn no_clear_screen_arg<'a>() -> Arg<'a> {
|
||||||
|
Arg::new("no-clear-screen")
|
||||||
|
.requires("watch")
|
||||||
|
.long("no-clear-screen")
|
||||||
|
.help("Do not clear terminal screen when under watch mode")
|
||||||
|
}
|
||||||
|
|
||||||
fn no_check_arg<'a>() -> Arg<'a> {
|
fn no_check_arg<'a>() -> Arg<'a> {
|
||||||
Arg::new("no-check")
|
Arg::new("no-check")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
|
@ -1910,6 +1923,7 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
config_arg_parse(flags, matches);
|
config_arg_parse(flags, matches);
|
||||||
watch_arg_parse(flags, matches, false);
|
watch_arg_parse(flags, matches, false);
|
||||||
|
|
||||||
let files = match matches.values_of("files") {
|
let files = match matches.values_of("files") {
|
||||||
Some(f) => f.map(PathBuf::from).collect(),
|
Some(f) => f.map(PathBuf::from).collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
|
@ -2451,6 +2465,10 @@ fn watch_arg_parse(
|
||||||
} else if matches.is_present("watch") {
|
} else if matches.is_present("watch") {
|
||||||
flags.watch = Some(vec![]);
|
flags.watch = Some(vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches.is_present("no-clear-screen") {
|
||||||
|
flags.no_clear_screen = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ry) move this to utility module and add test.
|
// TODO(ry) move this to utility module and add test.
|
||||||
|
@ -2580,6 +2598,30 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn run_watch_with_no_clear_screen() {
|
||||||
|
let r = flags_from_vec(svec![
|
||||||
|
"deno",
|
||||||
|
"run",
|
||||||
|
"--watch",
|
||||||
|
"--no-clear-screen",
|
||||||
|
"script.ts"
|
||||||
|
]);
|
||||||
|
|
||||||
|
let flags = r.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
flags,
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Run(RunFlags {
|
||||||
|
script: "script.ts".to_string(),
|
||||||
|
}),
|
||||||
|
watch: Some(vec![]),
|
||||||
|
no_clear_screen: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_reload_allow_write() {
|
fn run_reload_allow_write() {
|
||||||
let r =
|
let r =
|
||||||
|
@ -2813,6 +2855,28 @@ mod tests {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let r =
|
||||||
|
flags_from_vec(svec!["deno", "fmt", "--watch", "--no-clear-screen"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
||||||
|
ignore: vec![],
|
||||||
|
check: false,
|
||||||
|
files: vec![],
|
||||||
|
ext: "ts".to_string(),
|
||||||
|
use_tabs: None,
|
||||||
|
line_width: None,
|
||||||
|
indent_width: None,
|
||||||
|
single_quote: None,
|
||||||
|
prose_wrap: None,
|
||||||
|
}),
|
||||||
|
watch: Some(vec![]),
|
||||||
|
no_clear_screen: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
let r = flags_from_vec(svec![
|
let r = flags_from_vec(svec![
|
||||||
"deno",
|
"deno",
|
||||||
"fmt",
|
"fmt",
|
||||||
|
@ -2941,6 +3005,62 @@ mod tests {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec![
|
||||||
|
"deno",
|
||||||
|
"lint",
|
||||||
|
"--watch",
|
||||||
|
"script_1.ts",
|
||||||
|
"script_2.ts"
|
||||||
|
]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
|
files: vec![
|
||||||
|
PathBuf::from("script_1.ts"),
|
||||||
|
PathBuf::from("script_2.ts")
|
||||||
|
],
|
||||||
|
rules: false,
|
||||||
|
maybe_rules_tags: None,
|
||||||
|
maybe_rules_include: None,
|
||||||
|
maybe_rules_exclude: None,
|
||||||
|
json: false,
|
||||||
|
ignore: vec![],
|
||||||
|
}),
|
||||||
|
watch: Some(vec![]),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec![
|
||||||
|
"deno",
|
||||||
|
"lint",
|
||||||
|
"--watch",
|
||||||
|
"--no-clear-screen",
|
||||||
|
"script_1.ts",
|
||||||
|
"script_2.ts"
|
||||||
|
]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
|
files: vec![
|
||||||
|
PathBuf::from("script_1.ts"),
|
||||||
|
PathBuf::from("script_2.ts")
|
||||||
|
],
|
||||||
|
rules: false,
|
||||||
|
maybe_rules_tags: None,
|
||||||
|
maybe_rules_include: None,
|
||||||
|
maybe_rules_exclude: None,
|
||||||
|
json: false,
|
||||||
|
ignore: vec![],
|
||||||
|
}),
|
||||||
|
watch: Some(vec![]),
|
||||||
|
no_clear_screen: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
let r =
|
let r =
|
||||||
flags_from_vec(svec!["deno", "lint", "--ignore=script_1.ts,script_2.ts"]);
|
flags_from_vec(svec!["deno", "lint", "--ignore=script_1.ts,script_2.ts"]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -3611,6 +3731,29 @@ mod tests {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bundle_watch_with_no_clear_screen() {
|
||||||
|
let r = flags_from_vec(svec![
|
||||||
|
"deno",
|
||||||
|
"bundle",
|
||||||
|
"--watch",
|
||||||
|
"--no-clear-screen",
|
||||||
|
"source.ts"
|
||||||
|
]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Bundle(BundleFlags {
|
||||||
|
source_file: "source.ts".to_string(),
|
||||||
|
out_file: None,
|
||||||
|
}),
|
||||||
|
watch: Some(vec![]),
|
||||||
|
no_clear_screen: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_import_map() {
|
fn run_import_map() {
|
||||||
let r = flags_from_vec(svec![
|
let r = flags_from_vec(svec![
|
||||||
|
@ -4371,6 +4514,31 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_watch_with_no_clear_screen() {
|
||||||
|
let r =
|
||||||
|
flags_from_vec(svec!["deno", "test", "--watch", "--no-clear-screen"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Test(TestFlags {
|
||||||
|
no_run: false,
|
||||||
|
doc: false,
|
||||||
|
fail_fast: None,
|
||||||
|
filter: None,
|
||||||
|
allow_none: false,
|
||||||
|
shuffle: None,
|
||||||
|
include: None,
|
||||||
|
ignore: vec![],
|
||||||
|
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||||
|
}),
|
||||||
|
watch: Some(vec![]),
|
||||||
|
no_clear_screen: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bundle_with_cafile() {
|
fn bundle_with_cafile() {
|
||||||
let r = flags_from_vec(svec![
|
let r = flags_from_vec(svec![
|
||||||
|
@ -4676,4 +4844,14 @@ mod tests {
|
||||||
vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")]
|
vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_no_clear_watch_flag_without_watch_flag() {
|
||||||
|
let r = flags_from_vec(svec!["deno", "run", "--no-clear-screen", "foo.js"]);
|
||||||
|
assert!(r.is_err());
|
||||||
|
let error_message = r.unwrap_err().to_string();
|
||||||
|
assert!(&error_message
|
||||||
|
.contains("error: The following required arguments were not provided:"));
|
||||||
|
assert!(&error_message.contains("--watch=<FILES>..."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
33
cli/main.rs
33
cli/main.rs
|
@ -529,15 +529,7 @@ async fn lint_command(
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ps = ProcState::build(flags.clone()).await?;
|
tools::lint::lint(flags, lint_flags).await?;
|
||||||
let maybe_lint_config = if let Some(config_file) = &ps.maybe_config_file {
|
|
||||||
config_file.to_lint_config()?
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
tools::lint::lint(maybe_lint_config, lint_flags, flags.watch.is_some())
|
|
||||||
.await?;
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,7 +845,15 @@ async fn bundle_command(
|
||||||
};
|
};
|
||||||
|
|
||||||
if flags.watch.is_some() {
|
if flags.watch.is_some() {
|
||||||
file_watcher::watch_func(resolver, operation, "Bundle").await?;
|
file_watcher::watch_func(
|
||||||
|
resolver,
|
||||||
|
operation,
|
||||||
|
file_watcher::PrintConfig {
|
||||||
|
job_name: "Bundle".to_string(),
|
||||||
|
clear_screen: !flags.no_clear_screen,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
let module_graph =
|
let module_graph =
|
||||||
if let ResolutionResult::Restart { result, .. } = resolver(None).await {
|
if let ResolutionResult::Restart { result, .. } = resolver(None).await {
|
||||||
|
@ -894,8 +894,7 @@ async fn format_command(
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
tools::fmt::format(fmt_flags, flags.watch.is_some(), maybe_fmt_config)
|
tools::fmt::format(flags, fmt_flags, maybe_fmt_config).await?;
|
||||||
.await?;
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,7 +1117,15 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
file_watcher::watch_func(resolver, operation, "Process").await?;
|
file_watcher::watch_func(
|
||||||
|
resolver,
|
||||||
|
operation,
|
||||||
|
file_watcher::PrintConfig {
|
||||||
|
job_name: "Process".to_string(),
|
||||||
|
clear_screen: !flags.no_clear_screen,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -997,3 +997,51 @@ fn test_watch_module_graph_error_referrer() {
|
||||||
wait_for("Process failed", &mut stderr_lines);
|
wait_for("Process failed", &mut stderr_lines);
|
||||||
check_alive_then_kill(child);
|
check_alive_then_kill(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn watch_with_no_clear_screen_flag() {
|
||||||
|
let t = TempDir::new().unwrap();
|
||||||
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
|
write(&file_to_watch, "export const foo = 0;").unwrap();
|
||||||
|
|
||||||
|
// choose deno run subcommand to test --no-clear-screen flag
|
||||||
|
let mut child = util::deno_cmd()
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg("--watch")
|
||||||
|
.arg("--no-clear-screen")
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg(&file_to_watch)
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.stdout(std::process::Stdio::piped())
|
||||||
|
.stderr(std::process::Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let (_, mut stderr_lines) = child_lines(&mut child);
|
||||||
|
|
||||||
|
let next_line = stderr_lines.next().unwrap();
|
||||||
|
|
||||||
|
// no clear screen
|
||||||
|
assert!(!&next_line.contains(CLEAR_SCREEN));
|
||||||
|
assert_contains!(&next_line, "Process started");
|
||||||
|
assert_contains!(
|
||||||
|
stderr_lines.next().unwrap(),
|
||||||
|
"Process finished. Restarting on file change..."
|
||||||
|
);
|
||||||
|
|
||||||
|
// Change content of the file
|
||||||
|
write(&file_to_watch, "export const bar = 0;").unwrap();
|
||||||
|
|
||||||
|
let next_line = stderr_lines.next().unwrap();
|
||||||
|
|
||||||
|
// no clear screen
|
||||||
|
assert!(!&next_line.contains(CLEAR_SCREEN));
|
||||||
|
|
||||||
|
assert_contains!(&next_line, "Watcher File change detected! Restarting!");
|
||||||
|
assert_contains!(
|
||||||
|
stderr_lines.next().unwrap(),
|
||||||
|
"Process finished. Restarting on file change..."
|
||||||
|
);
|
||||||
|
|
||||||
|
check_alive_then_kill(child);
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::config_file::ProseWrap;
|
||||||
use crate::diff::diff;
|
use crate::diff::diff;
|
||||||
use crate::file_watcher;
|
use crate::file_watcher;
|
||||||
use crate::file_watcher::ResolutionResult;
|
use crate::file_watcher::ResolutionResult;
|
||||||
use crate::flags::FmtFlags;
|
use crate::flags::{Flags, FmtFlags};
|
||||||
use crate::fs_util::specifier_to_file_path;
|
use crate::fs_util::specifier_to_file_path;
|
||||||
use crate::fs_util::{collect_files, get_extension};
|
use crate::fs_util::{collect_files, get_extension};
|
||||||
use crate::text_encoding;
|
use crate::text_encoding;
|
||||||
|
@ -39,8 +39,8 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
/// Format JavaScript/TypeScript files.
|
/// Format JavaScript/TypeScript files.
|
||||||
pub async fn format(
|
pub async fn format(
|
||||||
|
flags: Flags,
|
||||||
fmt_flags: FmtFlags,
|
fmt_flags: FmtFlags,
|
||||||
watch: bool,
|
|
||||||
maybe_fmt_config: Option<FmtConfig>,
|
maybe_fmt_config: Option<FmtConfig>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let FmtFlags {
|
let FmtFlags {
|
||||||
|
@ -136,8 +136,16 @@ pub async fn format(
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
if watch {
|
if flags.watch.is_some() {
|
||||||
file_watcher::watch_func(resolver, operation, "Fmt").await?;
|
file_watcher::watch_func(
|
||||||
|
resolver,
|
||||||
|
operation,
|
||||||
|
file_watcher::PrintConfig {
|
||||||
|
job_name: "Fmt".to_string(),
|
||||||
|
clear_screen: !flags.no_clear_screen,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
let files =
|
let files =
|
||||||
collect_files(&include_files, &exclude_files, is_supported_ext_fmt)
|
collect_files(&include_files, &exclude_files, is_supported_ext_fmt)
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
//! the same functions as ops available in JS runtime.
|
//! the same functions as ops available in JS runtime.
|
||||||
use crate::config_file::LintConfig;
|
use crate::config_file::LintConfig;
|
||||||
use crate::file_watcher::ResolutionResult;
|
use crate::file_watcher::ResolutionResult;
|
||||||
use crate::flags::LintFlags;
|
use crate::flags::{Flags, LintFlags};
|
||||||
use crate::fmt_errors;
|
use crate::fmt_errors;
|
||||||
use crate::fs_util::{collect_files, is_supported_ext, specifier_to_file_path};
|
use crate::fs_util::{collect_files, is_supported_ext, specifier_to_file_path};
|
||||||
|
use crate::proc_state::ProcState;
|
||||||
use crate::tools::fmt::run_parallelized;
|
use crate::tools::fmt::run_parallelized;
|
||||||
use crate::{colors, file_watcher};
|
use crate::{colors, file_watcher};
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
|
@ -48,11 +49,7 @@ fn create_reporter(kind: LintReporterKind) -> Box<dyn LintReporter + Send> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn lint(
|
pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> {
|
||||||
maybe_lint_config: Option<LintConfig>,
|
|
||||||
lint_flags: LintFlags,
|
|
||||||
watch: bool,
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
let LintFlags {
|
let LintFlags {
|
||||||
maybe_rules_tags,
|
maybe_rules_tags,
|
||||||
maybe_rules_include,
|
maybe_rules_include,
|
||||||
|
@ -69,6 +66,13 @@ pub async fn lint(
|
||||||
let mut include_files = args.clone();
|
let mut include_files = args.clone();
|
||||||
let mut exclude_files = ignore.clone();
|
let mut exclude_files = ignore.clone();
|
||||||
|
|
||||||
|
let ps = ProcState::build(flags.clone()).await?;
|
||||||
|
let maybe_lint_config = if let Some(config_file) = &ps.maybe_config_file {
|
||||||
|
config_file.to_lint_config()?
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(lint_config) = maybe_lint_config.as_ref() {
|
if let Some(lint_config) = maybe_lint_config.as_ref() {
|
||||||
if include_files.is_empty() {
|
if include_files.is_empty() {
|
||||||
include_files = lint_config
|
include_files = lint_config
|
||||||
|
@ -166,13 +170,21 @@ pub async fn lint(
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
if watch {
|
if flags.watch.is_some() {
|
||||||
if args.len() == 1 && args[0].to_string_lossy() == "-" {
|
if args.len() == 1 && args[0].to_string_lossy() == "-" {
|
||||||
return Err(generic_error(
|
return Err(generic_error(
|
||||||
"Lint watch on standard input is not supported.",
|
"Lint watch on standard input is not supported.",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
file_watcher::watch_func(resolver, operation, "Lint").await?;
|
file_watcher::watch_func(
|
||||||
|
resolver,
|
||||||
|
operation,
|
||||||
|
file_watcher::PrintConfig {
|
||||||
|
job_name: "Lint".to_string(),
|
||||||
|
clear_screen: !flags.no_clear_screen,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
if args.len() == 1 && args[0].to_string_lossy() == "-" {
|
if args.len() == 1 && args[0].to_string_lossy() == "-" {
|
||||||
let reporter_lock =
|
let reporter_lock =
|
||||||
|
|
|
@ -248,5 +248,6 @@ pub fn compile_to_runtime_flags(
|
||||||
v8_flags: flags.v8_flags,
|
v8_flags: flags.v8_flags,
|
||||||
version: false,
|
version: false,
|
||||||
watch: None,
|
watch: None,
|
||||||
|
no_clear_screen: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1279,7 +1279,15 @@ pub async fn run_tests_with_watch(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
file_watcher::watch_func(resolver, operation, "Test").await?;
|
file_watcher::watch_func(
|
||||||
|
resolver,
|
||||||
|
operation,
|
||||||
|
file_watcher::PrintConfig {
|
||||||
|
job_name: "Test".to_string(),
|
||||||
|
clear_screen: !flags.no_clear_screen,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue