diff --git a/README.md b/README.md index ceadc53..830cd67 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Where [PATH] is the path of the folder to initialize in [default: `.`] Options: - `--name ` The name of the project - `--description ` The description of the project -- `--pack-format ` The pack format version +- `--pack-format ` The pack format version - `--force` Force initialization even if the directory is not empty ### Build a project @@ -57,7 +57,8 @@ Where [PATH] is the path of the project folder to watch [default: `.`] Options: - `--no-initial` Do not run the command initially -- `--debounce-time ` The time to wait in ms after the last change before running the command [default: `2000`] +- `--debounce-time ` The time to wait in ms after the last change before running the command [default: `2000`] +- `--watch ` The directories to watch for changes [multi-arg, default: `src`, `pack.toml`, `pack.png`, assets directory] - `--execute ` The commands (cli subcommands or shell commands) to execute in the project when changes have been detected [multi-arg, default: `build`] ## Contributing diff --git a/src/cli.rs b/src/cli.rs index 08cb1f3..9d3decd 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -50,3 +50,15 @@ impl Command { Ok(()) } } + +#[cfg(test)] +mod tests { + use clap::CommandFactory; + + use super::*; + + #[test] + fn verify_cli() { + Args::command().debug_assert(); + } +} diff --git a/src/subcommands/init.rs b/src/subcommands/init.rs index 8f4a206..332bdd8 100644 --- a/src/subcommands/init.rs +++ b/src/subcommands/init.rs @@ -28,7 +28,7 @@ pub struct InitArgs { #[clap(short, long)] pub description: Option, /// The pack format version. - #[clap(short, long)] + #[clap(short, long, value_name = "FORMAT")] pub pack_format: Option, /// Force initialization even if the directory is not empty. #[clap(short, long)] diff --git a/src/subcommands/lang_debug.rs b/src/subcommands/lang_debug.rs index 0cc4a7c..9088fb4 100644 --- a/src/subcommands/lang_debug.rs +++ b/src/subcommands/lang_debug.rs @@ -9,7 +9,7 @@ pub struct LangDebugArgs { #[clap(default_value = ".")] pub path: PathBuf, /// The state to dump. - #[clap(short, long, default_value = "ast")] + #[clap(short, long, value_name = "STATE", default_value = "ast")] pub dump: DumpState, /// Pretty-print the output. #[clap(short, long)] diff --git a/src/subcommands/watch.rs b/src/subcommands/watch.rs index b806641..bd83f11 100644 --- a/src/subcommands/watch.rs +++ b/src/subcommands/watch.rs @@ -24,10 +24,14 @@ pub struct WatchArgs { #[clap(short, long)] pub no_inital: bool, /// The time to wait in ms before running the command after changes are detected. - #[clap(short, long, default_value = "2000")] + #[clap(short, long, value_name = "TIME_IN_MS", default_value = "2000")] pub debounce_time: u64, - /// The commands to run in the project directory when changes are detected. - #[clap(short = 'x', long, default_value = "build .")] + /// Additional paths to watch for changes. + /// By default, the `src` directory, `pack.png`, and `pack.toml` as well as the defined assets directory in the config are watched. + #[clap(short, long, value_name = "PATH")] + pub watch: Vec, + /// The commands to run in the project directory when changes are detected. Use multiple times to run multiple commands. + #[clap(short = 'x', long, value_name = "COMMAND", default_value = "build .")] pub execute: Vec, } @@ -58,7 +62,16 @@ pub fn watch(_verbose: bool, args: &WatchArgs) -> Result<()> { }) .collect::>(); - if env::set_current_dir(args.path.as_path()).is_err() { + let current_dir = if args.no_inital { + print_info("Skipping initial commands because of cli flag."); + None + } else { + env::current_dir().ok() + }; + + if !args.no_inital + && (current_dir.is_none() || env::set_current_dir(args.path.as_path()).is_err()) + { print_warning("Failed to change working directory to project path. Commands may not work."); } @@ -85,6 +98,14 @@ pub fn watch(_verbose: bool, args: &WatchArgs) -> Result<()> { ) .expect("Failed to initialize watcher"); + if let Some(prev_cwd) = current_dir { + env::set_current_dir(prev_cwd).expect("Failed to change working directory back"); + } + + let assets_path = super::build::get_pack_config(&args.path) + .ok() + .and_then(|(conf, _)| conf.compiler.and_then(|c| c.assets)); + let watcher = debouncer.watcher(); watcher .watch(args.path.join("src").as_path(), RecursiveMode::Recursive) @@ -101,6 +122,32 @@ pub fn watch(_verbose: bool, args: &WatchArgs) -> Result<()> { RecursiveMode::NonRecursive, ) .expect("Failed to watch project pack.toml"); + if let Some(assets_path) = assets_path { + let full_assets_path = args.path.join(assets_path); + if full_assets_path.exists() { + watcher + .watch(full_assets_path.as_path(), RecursiveMode::Recursive) + .expect("Failed to watch project assets"); + } + } + + // custom watch paths + for path in args.watch.iter() { + if path.exists() { + watcher + .watch(path.as_path(), RecursiveMode::Recursive) + .expect("Failed to watch custom path"); + } else { + print_warning(format!( + "Path {} does not exist. Skipping...", + path.display() + )); + } + } + + if env::set_current_dir(args.path.as_path()).is_err() { + print_warning("Failed to change working directory to project path. Commands may not work."); + } loop { thread::sleep(Duration::from_secs(60));