diff --git a/Cargo.lock b/Cargo.lock index 2bdac64..66a512e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,13 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "aho-corasick" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" -dependencies = [ - "memchr", -] +version = 3 [[package]] name = "ansi_term" @@ -97,6 +90,17 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi 0.3.9", +] + [[package]] name = "difference" version = "2.0.0" @@ -109,19 +113,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" -[[package]] -name = "env_logger" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "filetime" version = "0.2.14" @@ -178,12 +169,6 @@ dependencies = [ "libc", ] -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "inotify" version = "0.7.1" @@ -258,16 +243,14 @@ checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714" [[package]] name = "lightmon" -version = "0.2.0" +version = "0.3.0" dependencies = [ "assert_cmd", "clap", - "env_logger", - "log", + "colored", "notify", "serde_json", "serial_test", - "termcolor", "walkdir", ] @@ -445,17 +428,6 @@ dependencies = [ "bitflags 1.2.1", ] -[[package]] -name = "regex" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - [[package]] name = "regex-automata" version = "0.1.9" @@ -465,12 +437,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "regex-syntax" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" - [[package]] name = "ryu" version = "1.0.5" @@ -560,15 +526,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - [[package]] name = "textwrap" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index e2ca8f9..298bded 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lightmon" -version = "0.2.0" +version = "0.3.0" authors = ["Reagan McFarland ", "Alay Shah"] description = "A lightweight, cross-platform, language-agnostic 'run code on file change' tool, inspired by Nodemon" homepage = "https://github.com/reaganmcf/lightmon" @@ -17,9 +17,7 @@ exclude = [ notify = "4.0.12" clap = {version = "~2.27.0", features = ["yaml"]} walkdir = "2" -log = "0.4.0" -env_logger = "0.8.3" -termcolor = "1.1.2" +colored = "2" serde_json = "1.0" [dev-dependencies] diff --git a/src/cli.rs b/src/cli.rs index 76d4d09..2b7e67d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,4 @@ -use clap::{App, AppSettings, ArgMatches}; -use env_logger::Builder; -use log::LevelFilter; +use clap::{load_yaml, App, AppSettings, ArgMatches}; use serde_json::Value; use std::fs::File; use std::io::BufReader; @@ -17,8 +15,8 @@ pub(crate) enum SupportedLanguage { impl std::fmt::Display for SupportedLanguage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - SupportedLanguage::Rust => write!(f, "rust"), - SupportedLanguage::Node => write!(f, "node"), + SupportedLanguage::Rust => write!(f, "🦀 Rust"), + SupportedLanguage::Node => write!(f, "Node.js"), SupportedLanguage::Shell => write!(f, "shell"), } } @@ -41,12 +39,6 @@ impl Cli { .global_setting(AppSettings::AllowExternalSubcommands) .get_matches(); - if matches.is_present("verbose") { - Builder::new().filter_level(LevelFilter::Debug).init(); - } else { - Builder::new().filter_level(LevelFilter::Info).init(); - } - let config: Option = match matches.subcommand() { ("rust", Some(sub_matcher)) => Some(Self::build_rust_config(Some(sub_matcher))), ("node", Some(_)) => Some(Self::build_node_config()), @@ -56,7 +48,7 @@ impl Cli { // again that a subcommand was passed in. This is because an unsupported lang would // still match to this branch. if matches.subcommand_name().is_some() { - error!( + eprintln!( "{} is not supported. Consider using `lightmon shell` instead.", matches.subcommand_name().unwrap() ); @@ -74,7 +66,7 @@ impl Cli { } else if Path::new("Cargo.toml").exists() { Some(Self::build_rust_config(None)) } else { - error!("Unable to resolve configuration automatically. Consider using `lightmon shell` instead."); + eprintln!("Unable to resolve configuration automatically. Consider using `lightmon shell` instead."); None } } @@ -83,6 +75,7 @@ impl Cli { if config.is_none() { std::process::exit(1); } + config.unwrap() } @@ -97,7 +90,6 @@ impl Cli { // 1. The value at `scripts.start` // 2. `node main` where `main` is the value of the `main` key in `package.json` (the entry point of the project). fn build_node_config() -> Self { - debug!("Configuring for node mode..."); let watch_patterns: Vec = vec![ "*.jsx".to_string(), "*.js".to_string(), @@ -113,12 +105,7 @@ impl Cli { if values.is_object() { if let Some(scripts) = values.get("scripts") { - debug!("scripts found! Value is = {}", scripts); if let Some(scripts_start) = scripts.get("start") { - debug!( - "scripts.start found! Resolving exec_commands as '{}'", - scripts_start - ); exec_commands.push(scripts_start.as_str().unwrap().to_string()); } } @@ -126,10 +113,6 @@ impl Cli { // If scripts resolution failed, try getting main entry point if exec_commands.is_empty() { if let Some(main_entry_point) = values.get("main") { - debug!( - "main found! Resolving exec_commands as '{}'", - main_entry_point - ); // main_entry_point has a " on either end, so we need to trim exec_commands.push(format!("node {}", main_entry_point.as_str().unwrap())); } @@ -139,7 +122,6 @@ impl Cli { // exec commands resolution fallback if exec_commands.is_empty() { - debug!("Failed to resolve exec command using package.json, falling back to 'node index.js'"); exec_commands.push("node index.js".to_string()); } @@ -168,14 +150,12 @@ impl Cli { // Will resolve the exec command to `cargo build --bin my_bin --all-targets` fn build_rust_config(sub_matcher: Option<&ArgMatches>) -> Self { let mut exec_commands: Vec = Vec::new(); - debug!("Configuring for rust mode..."); + // attempt to match subcommand if let Some(sub_matcher) = sub_matcher { - debug!("build_rust_config received subcommand override!"); if let (external_name, Some(external_args)) = sub_matcher.subcommand() { if external_args.values_of("").is_some() { let ext_args: Vec<&str> = external_args.values_of("").unwrap().collect(); - debug!("External commands = {:?}", ext_args); exec_commands.push(format!("cargo {} {}", external_name, ext_args.join(" "))); } else { exec_commands.push(format!("cargo {}", external_name)); @@ -185,13 +165,11 @@ impl Cli { // Since no subcommand was given, resolve via project type // 1. Check if src/main.rs exists if Path::new("src/main.rs").exists() { - debug!("Cargo bin project detected"); exec_commands.push(format!("cargo {}", "run")); } else if Path::new("src/lib.rs").exists() { - debug!("Cargo lib project detected"); exec_commands.push(format!("cargo {}", "test")); } else { - error!("Could not find which type of rust project this is. Consider overriding using a cargo subcommand. Run `lightmon help rust` for more information."); + eprintln!("Could not find which type of rust project this is. Consider overriding using a cargo subcommand. Run `lightmon help rust` for more information."); std::process::exit(1); } } @@ -208,15 +186,14 @@ impl Cli { fn build_shell_config(sub_matcher: &ArgMatches) -> Self { let mut watch_patterns: Vec = Vec::new(); let mut exec_commands: Vec = Vec::new(); - debug!("Configuring for shell mode..."); - debug!("Script Path = {:?}", sub_matcher.value_of("script")); - debug!("Watch Pattern = {:?}", sub_matcher.value_of("watch")); + let split = sub_matcher.value_of("watch").unwrap().split(','); for s in split { watch_patterns.push(format!("*{}", s.to_string())); } + exec_commands.push(format!("bash {}", sub_matcher.value_of("script").unwrap())); - debug!("{:?}", exec_commands); + Cli { watch_patterns, project_language: SupportedLanguage::Shell, diff --git a/src/cli.yaml b/src/cli.yaml index 3d392d0..f8fe6fe 100644 --- a/src/cli.yaml +++ b/src/cli.yaml @@ -2,11 +2,6 @@ name: lightmon version: "v0.2.0" author: Reagan McFarland , Alay Shah about: A light-weight, cross-platform, language agnostic \"run code on file change\" tool, inspired by Nodemon -args: - - verbose: - short: v - long: verbose - help: Use verbose output subcommands: - rust: about: "Use rust preset for lightmon. Lightmon will detect the type of rust project you are working in automatically.\n Note: if you want to use a custom cargo command, you can provide the subcommand and any arguments and the exec command will get resolved accordingly." diff --git a/src/exec.rs b/src/exec.rs index 194f2d9..f15cc29 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -1,10 +1,12 @@ // Contains the method for starting a thread that will run the exec commands in parallel. -use std::process::Command; -use std::sync::mpsc::Sender; -use std::sync::Arc; -use std::thread; -use std::{io, process::Child}; +use colored::*; +use std::sync::{mpsc::Sender, Arc}; +use std::{ + io, + process::{Child, Command}, + thread, +}; use crate::cli::Cli; use crate::LightmonEvent; @@ -18,8 +20,6 @@ pub(crate) fn start( exec_child_process_sender: Sender, ) -> std::thread::JoinHandle<()> { thread::spawn(move || { - debug!("thread started"); - // Build commands from exec commands for exec_command in &cli_args.exec_commands { // split into components @@ -28,32 +28,26 @@ pub(crate) fn start( for argument in split.iter().skip(1) { cmd.arg(argument); } - debug!("final cmd = {:?}", cmd); - let child = cmd.spawn().unwrap(); - debug!("child process pid = {:?}", child.id()); - match exec_child_process_sender.send(child) { - Ok(_) => {} - Err(_) => { - error!("Unable to send event to main loop. Something seriously went wrong!"); - std::process::exit(1); - } - } + + println!( + "{}", + format!( + "[lightmon] starting `{}`", + &cli_args.exec_commands.join(" ") + ) + .green() + ); + + let child = cmd.spawn().expect("Unable to spawn process"); + + exec_child_process_sender + .send(child) + .expect("Unable to send event to main loop. Something seriously went wrong!"); + + let mut input = String::new(); loop { - let mut input = String::new(); - if let Ok(n) = io::stdin().read_line(&mut input) { - if input.eq("rs\n") { - debug!("rs RECEIEVED"); - match lightmon_event_sender.send(LightmonEvent::KillAndRestartChild) { - Ok(_) => {} - Err(_) => { - error!("Unable to kill and restart the process. Something seriously went wrong!"); - std::process::exit(1); - } - } - } else { - debug!("unknown input, bits read from input {:?}", n); - debug!("input = {:?}", input); - } + if io::stdin().read_line(&mut input).is_ok() && input.eq("rs\n") { + lightmon_event_sender.send(LightmonEvent::KillAndRestartChild).expect("Unable to kill and restart the process. Something seriously went wrong!"); } } } diff --git a/src/main.rs b/src/main.rs index c541eb5..6661bce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,9 @@ -#[macro_use] -extern crate log; -#[macro_use] -extern crate clap; - mod cli; mod exec; mod watcher; use cli::Cli; +use colored::*; use std::sync::Arc; use std::{ process::Child, @@ -40,21 +36,35 @@ fn main() { watcher::start(cli_args.clone(), lightmon_event_sender.clone()); - println!("lightmon started ({} mode)", cli_args.project_language); + println!( + "{}", + format!("[lightmon] {}", env!("CARGO_PKG_VERSION")).yellow() + ); + println!( + "{}", + "[lightmon] enter `rs` at any time to restart".yellow() + ); + println!( + "{}", + format!( + "[lightmon] running in {} mode", + format!("{}", cli_args.project_language).blue() + ) + .yellow() + ); + println!( + "{}", + format!("[lightmon] watching {:?}", cli_args.watch_patterns).yellow() + ); // event thread loop { if let Ok(lightmon_event) = lightmon_event_receiver.recv() { match lightmon_event { LightmonEvent::KillAndRestartChild => { - debug!("KILL AND RESTART RECEIEVED"); - // kill child if let Ok(mut exec_child) = exec_child_process_receiver.recv() { - match exec_child.kill() { - Ok(_) => debug!("Killed child process."), - Err(e) => debug!("Failed to kill child process! {:?}", e), - } + exec_child.kill().expect("Unable to kill the child process"); // waiting after killing sounds weird because it is. But, the following is // from the rust doc: @@ -75,7 +85,6 @@ fn main() { ); } LightmonEvent::InitExec => { - debug!("INIT EXEC RECEIVED"); exec::start( cli_args.clone(), lightmon_event_sender.clone(), diff --git a/src/watcher.rs b/src/watcher.rs index 5f4ea9c..3786e43 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -1,11 +1,11 @@ -use notify::poll::PollWatcher; -use notify::{RecursiveMode, Watcher}; -use std::collections::HashSet; -use std::ffi::OsStr; -use std::path::Path; -use std::sync::Arc; +use colored::*; +use notify::{poll::PollWatcher, RecursiveMode, Watcher}; use std::{ + collections::HashSet, + ffi::OsStr, + path::Path, sync::mpsc::{channel, Sender}, + sync::Arc, thread::JoinHandle, }; use walkdir::WalkDir; @@ -42,16 +42,18 @@ pub(crate) fn start( .filter_map(|e| e.ok()) { let mut should_watch: bool; + // Check if the file is an explicit one we should watch should_watch = explicit_files_to_watch.contains(entry.path().to_str().unwrap()); + // Check if the file ends in a type we should watch let file_name = entry.file_name().to_str().unwrap(); let file_ext = Path::new(file_name).extension().and_then(OsStr::to_str); + if let Some(file_ext) = file_ext { should_watch = should_watch || file_types_to_watch.contains(file_ext); if should_watch { - debug!("Started watch on {:?}", entry.path().to_str().unwrap()); watcher .watch(entry.path().to_str().unwrap(), RecursiveMode::NonRecursive) .unwrap(); @@ -60,21 +62,18 @@ pub(crate) fn start( } loop { - debug!("checking events..."); match rx.recv() { - Ok(event) => { - println!("Changes detected, Restarting..."); - debug!( - "changes detected {:?}\n Sending restart event to exec", - event + Ok(_) => { + println!( + "{}", + "[lightmon] Changes detected, Restarting...".bright_yellow() ); - match lightmon_event_sender.send(LightmonEvent::KillAndRestartChild) { - Ok(_) => {} - Err(e) => error!("Failed to send event to exec thread! Reason: {:?}", e), - } + lightmon_event_sender + .send(LightmonEvent::KillAndRestartChild) + .expect("Failed to send restart event to main thread"); } Err(e) => { - error!("Failed to receive event from channel {:?}", e); + panic!("Failed to receive event from watcher {:?}", e); } } } diff --git a/tests/lightmon.rs b/tests/lightmon.rs index 8df8722..e915d2b 100644 --- a/tests/lightmon.rs +++ b/tests/lightmon.rs @@ -2,11 +2,8 @@ mod utils; use assert_cmd::prelude::*; use std::process::Command; -use std::time::Duration; use utils::*; -const EP_SHELL_BASIC_PATH: &str = "./tests/example_projects/shell_basic"; - #[test] fn unsupported_configuration_fails() -> TestResult { let mut cmd = Command::cargo_bin("lightmon")?; @@ -14,17 +11,3 @@ fn unsupported_configuration_fails() -> TestResult { Ok(()) } - -#[test] -fn verbose_shows_debug_statements() -> TestResult { - // Spawn child lightmon process at - let output = run_example( - EP_SHELL_BASIC_PATH, - Duration::from_secs(5), - Some(vec!["-v", "shell", "-s", "script.sh", "-w", ".sh"]), - None, - ) - .unwrap(); - assert!(output.stderr.contains("DEBUG lightmon::cli]")); - Ok(()) -} diff --git a/tests/node.rs b/tests/node.rs index c60adc9..1d9d8fd 100644 --- a/tests/node.rs +++ b/tests/node.rs @@ -1,7 +1,8 @@ -#[macro_use] -extern crate serial_test; +#![allow(non_snake_case)] mod utils; + +use serial_test::serial; use std::time::Duration; use utils::*; @@ -10,23 +11,64 @@ const EP_NODE_BASIC_MAIN_ENTRY_POINT_PATH: &str = "./tests/example_projects/node_basic/main_entry_point"; const EP_NODE_BASIC_FALLBACK_PATH: &str = "./tests/example_projects/node_basic/fallback"; -static BASIC_START_SCRIPT_RESOLUTION_EXPECTED: &str = "lightmon started (node mode) +fn BASIC_START_SCRIPT_RESOLUTION_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in Node.js mode +[lightmon] watching ["*.jsx", "*.js", "*.html", "*.css"] +[lightmon] starting `node script_start.js` called by script.start -"; +"#, + version + ) +} -static BASIC_MAIN_RESOLUTION_EXPECTED: &str = "lightmon started (node mode) +fn BASIC_MAIN_RESOLUTION_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in Node.js mode +[lightmon] watching ["*.jsx", "*.js", "*.html", "*.css"] +[lightmon] starting `node main.js` called by main entry point -"; +"#, + version + ) +} -static BASIC_FALLBACK_RESOLUTION_EXPECTED: &str = "lightmon started (node mode) +fn BASIC_FALLBACK_RESOLUTION_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in Node.js mode +[lightmon] watching ["*.jsx", "*.js", "*.html", "*.css"] +[lightmon] starting `node index.js` called by fallback -"; +"#, + version + ) +} -static TEST_WITH_FILE_EDITS_EXPECTED: &str = "lightmon started (node mode) +fn TEST_WITH_FILE_EDITS_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in Node.js mode +[lightmon] watching ["*.jsx", "*.js", "*.html", "*.css"] +[lightmon] starting `node script_start.js` called by script.start -Changes detected, Restarting... +[lightmon] Changes detected, Restarting... +[lightmon] starting `node script_start.js` called by script.start -"; +"#, + version + ) +} // node configuration where script.start is in package.json #[test] @@ -39,7 +81,7 @@ fn node_basic_script_start_resolution() -> TestResult { None, ) .unwrap(); - assert_eq!(output.stdout, BASIC_START_SCRIPT_RESOLUTION_EXPECTED); + assert_eq!(output.stdout, BASIC_START_SCRIPT_RESOLUTION_EXPECTED()); Ok(()) } @@ -54,7 +96,7 @@ fn node_basic_main_resolution() -> TestResult { None, ) .unwrap(); - assert_eq!(output.stdout, BASIC_MAIN_RESOLUTION_EXPECTED); + assert_eq!(output.stdout, BASIC_MAIN_RESOLUTION_EXPECTED()); Ok(()) } @@ -69,7 +111,7 @@ fn node_basic_fallback_resolution() -> TestResult { None, ) .unwrap(); - assert_eq!(output.stdout, BASIC_FALLBACK_RESOLUTION_EXPECTED); + assert_eq!(output.stdout, BASIC_FALLBACK_RESOLUTION_EXPECTED()); Ok(()) } @@ -83,7 +125,7 @@ fn node_test_with_js_file_edits() -> TestResult { "test.js", ) .unwrap(); - assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED); + assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED()); Ok(()) } @@ -97,7 +139,7 @@ fn node_test_with_jsx_file_edits() -> TestResult { "test.jsx", ) .unwrap(); - assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED); + assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED()); Ok(()) } @@ -111,7 +153,7 @@ fn node_test_with_css_file_edits() -> TestResult { "test.css", ) .unwrap(); - assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED); + assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED()); Ok(()) } @@ -125,6 +167,6 @@ fn node_test_with_html_file_edits() -> TestResult { "test.html", ) .unwrap(); - assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED); + assert_eq!(output.stdout, TEST_WITH_FILE_EDITS_EXPECTED()); Ok(()) } diff --git a/tests/rust.rs b/tests/rust.rs index 8b9e898..181d912 100644 --- a/tests/rust.rs +++ b/tests/rust.rs @@ -1,7 +1,8 @@ +#![allow(non_snake_case)] + mod utils; -#[macro_use] -extern crate serial_test; +use serial_test::serial; use std::time::Duration; use utils::*; @@ -9,22 +10,43 @@ const EP_RUST_BASIC_BIN_PATH: &str = "./tests/example_projects/rust_basic_bin"; const EP_RUST_BASIC_LIB_PATH: &str = "./tests/example_projects/rust_basic_lib"; const EP_RUST_INVALID_PATH: &str = "./tests/example_projects/rust_invalid"; -static BASIC_BIN_CONFIGURATION_EXPECTED: &str = "lightmon started (rust mode) +fn BASIC_BIN_CONFIGURATION_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in 🦀 Rust mode +[lightmon] watching ["*.rs", "Cargo.toml"] +[lightmon] starting `cargo run` Hello, World! -"; +"#, + version + ) +} -static BASIC_BIN_WITH_FILE_EDITS_EXPECTED: &str = "lightmon started (rust mode) +fn BASIC_BIN_WITH_FILE_EDITS_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in 🦀 Rust mode +[lightmon] watching ["*.rs", "Cargo.toml"] +[lightmon] starting `cargo run` Hello, World! -Changes detected, Restarting... +[lightmon] Changes detected, Restarting... +[lightmon] starting `cargo run` Hello, World! -"; +"#, + version + ) +} #[test] #[serial(rust)] fn rust_basic_bin_configuration() -> TestResult { // Spawn child lightmon process at rust directory let output = run_example(EP_RUST_BASIC_BIN_PATH, Duration::from_secs(5), None, None).unwrap(); - assert_eq!(output.stdout, BASIC_BIN_CONFIGURATION_EXPECTED); + assert_eq!(output.stdout, BASIC_BIN_CONFIGURATION_EXPECTED()); Ok(()) } @@ -50,7 +72,7 @@ fn rust_invalid_configuration_errors_out() -> TestResult { .unwrap(); assert!(output .stderr - .contains("ERROR lightmon::cli] Could not find which type of rust project this is.")); + .contains("Could not find which type of rust project this is.")); assert!(output.stdout.is_empty()); Ok(()) } @@ -96,6 +118,6 @@ fn rust_basic_bin_test_with_rs_file_edits() -> TestResult { "src/test.rs", ) .unwrap(); - assert_eq!(output.stdout, BASIC_BIN_WITH_FILE_EDITS_EXPECTED); + assert_eq!(output.stdout, BASIC_BIN_WITH_FILE_EDITS_EXPECTED()); Ok(()) } diff --git a/tests/shell.rs b/tests/shell.rs index 49a31d2..9ef8b72 100644 --- a/tests/shell.rs +++ b/tests/shell.rs @@ -1,15 +1,43 @@ -#[macro_use] -extern crate serial_test; +#![allow(non_snake_case)] mod utils; + +use serial_test::serial; use std::time::Duration; use utils::*; const EP_SHELL_BASIC_PATH: &str = "./tests/example_projects/shell_basic"; -static BASIC_CONFIGURATION_EXPECTED: &str = "lightmon started (shell mode) +fn BASIC_CONFIGURATION_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in shell mode +[lightmon] watching ["*.sh"] +[lightmon] starting `bash script.sh` Hello, World! -"; +"#, + version + ) +} + +fn BASIC_WITH_FILE_EDITS_EXPECTED() -> String { + let version = env!("CARGO_PKG_VERSION"); + format!( + r#"[lightmon] {} +[lightmon] enter `rs` at any time to restart +[lightmon] running in shell mode +[lightmon] watching ["*.c"] +[lightmon] starting `bash script.sh` +Hello, World! +[lightmon] Changes detected, Restarting... +[lightmon] starting `bash script.sh` +Hello, World! +"#, + version + ) +} static NO_SCRIPT_PATH_EXPECTED: &str = "error: The following required arguments were not provided: --script-path @@ -30,12 +58,6 @@ USAGE: For more information try --help "; -static BASIC_WITH_FILE_EDITS_EXPECTED: &str = "lightmon started (shell mode) -Hello, World! -Changes detected, Restarting... -Hello, World! -"; - #[cfg(not(target_os = "windows"))] #[test] #[serial(shell)] @@ -47,7 +69,7 @@ fn shell_basic_configuration() -> TestResult { None, ) .unwrap(); - assert_eq!(output.stdout, BASIC_CONFIGURATION_EXPECTED); + assert_eq!(output.stdout, BASIC_CONFIGURATION_EXPECTED()); Ok(()) } @@ -83,7 +105,7 @@ fn shell_should_error_with_no_watch_patterns() -> TestResult { #[cfg(not(target_os = "windows"))] #[test] -#[serial(shell)] +//#[serial(shell)] fn shell_basic_with_file_changes() -> TestResult { let output = run_example_with_file_change( EP_SHELL_BASIC_PATH, @@ -92,6 +114,6 @@ fn shell_basic_with_file_changes() -> TestResult { "test.c", ) .unwrap(); - assert_eq!(output.stdout, BASIC_WITH_FILE_EDITS_EXPECTED); + assert_eq!(output.stdout, BASIC_WITH_FILE_EDITS_EXPECTED()); Ok(()) } diff --git a/tests/utils.rs b/tests/utils.rs index 02801aa..411af90 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -41,11 +41,10 @@ pub fn run_example( std::thread::sleep(sleep_time); // Kill it - if let None = is_going_to_fail { - assert!( - child.kill().is_ok(), - "child process should be able to be killed" - ); + if is_going_to_fail.is_none() { + if let Err(e) = child.kill() { + panic!("Could not kill child process: {}", e); + } } // read stdout and stderr into strings @@ -53,14 +52,14 @@ pub fn run_example( let mut stderr = String::new(); let std_out_read_attempt = child.stdout.unwrap().read_to_string(&mut stdout); let std_err_read_attempt = child.stderr.unwrap().read_to_string(&mut stderr); - assert!( - std_out_read_attempt.is_ok(), - "should always be able to read child stdout" - ); - assert!( - std_err_read_attempt.is_ok(), - "should always be able to read child stderr" - ); + + if let Err(e) = std_out_read_attempt { + panic!("failed to read stdout: {}", e) + } + + if let Err(e) = std_err_read_attempt { + panic!("failed to read stderr: {}", e) + } println!("child stdout = '{}'\nchild stderr = '{}'", stdout, stderr); Ok(CommandOutput { stdout, stderr }) @@ -104,24 +103,24 @@ pub fn run_example_with_file_change( std::thread::sleep(sleep_time); // Kill it - assert!( - lightmon_child.kill().is_ok(), - "child process should be able to be killed" - ); + #[cfg(not(target_os = "win"))] + if let Err(e) = lightmon_child.kill() { + panic!("Could not kill child process: {}", e); + } // read stdout into string let mut stdout = String::new(); let mut stderr = String::new(); let std_out_read_attempt = lightmon_child.stdout.unwrap().read_to_string(&mut stdout); let std_err_read_attempt = lightmon_child.stderr.unwrap().read_to_string(&mut stderr); - assert!( - std_out_read_attempt.is_ok(), - "should always be able to read child stdout" - ); - assert!( - std_err_read_attempt.is_ok(), - "should always be able to read child stderr" - ); + + if let Err(e) = std_out_read_attempt { + panic!("failed to read stdout: {}", e) + } + + if let Err(e) = std_err_read_attempt { + panic!("failed to read stderr: {}", e) + } println!("child stdout = '{}'\nchild stderr = '{}'", stdout, stderr); Ok(CommandOutput { stdout, stderr })