fix working_dir in watch command

This commit is contained in:
Moritz Hölting 2024-06-13 20:45:16 +02:00
parent eaeb4166da
commit 9a14d547ce
5 changed files with 68 additions and 8 deletions

View File

@ -18,7 +18,7 @@ Where [PATH] is the path of the folder to initialize in [default: `.`]
Options: Options:
- `--name <NAME>` The name of the project - `--name <NAME>` The name of the project
- `--description <DESCRIPTION>` The description of the project - `--description <DESCRIPTION>` The description of the project
- `--pack-format <PACK_FORMAT>` The pack format version - `--pack-format <FORMAT>` The pack format version
- `--force` Force initialization even if the directory is not empty - `--force` Force initialization even if the directory is not empty
### Build a project ### Build a project
@ -57,7 +57,8 @@ Where [PATH] is the path of the project folder to watch [default: `.`]
Options: Options:
- `--no-initial` Do not run the command initially - `--no-initial` Do not run the command initially
- `--debounce-time <DEBOUNCE_TIME>` The time to wait in ms after the last change before running the command [default: `2000`] - `--debounce-time <TIME_IN_MS>` The time to wait in ms after the last change before running the command [default: `2000`]
- `--watch <PATH>` The directories to watch for changes [multi-arg, default: `src`, `pack.toml`, `pack.png`, assets directory]
- `--execute <COMMAND>` The commands (cli subcommands or shell commands) to execute in the project when changes have been detected [multi-arg, default: `build`] - `--execute <COMMAND>` The commands (cli subcommands or shell commands) to execute in the project when changes have been detected [multi-arg, default: `build`]
## Contributing ## Contributing

View File

@ -50,3 +50,15 @@ impl Command {
Ok(()) Ok(())
} }
} }
#[cfg(test)]
mod tests {
use clap::CommandFactory;
use super::*;
#[test]
fn verify_cli() {
Args::command().debug_assert();
}
}

View File

@ -28,7 +28,7 @@ pub struct InitArgs {
#[clap(short, long)] #[clap(short, long)]
pub description: Option<String>, pub description: Option<String>,
/// The pack format version. /// The pack format version.
#[clap(short, long)] #[clap(short, long, value_name = "FORMAT")]
pub pack_format: Option<u8>, pub pack_format: Option<u8>,
/// Force initialization even if the directory is not empty. /// Force initialization even if the directory is not empty.
#[clap(short, long)] #[clap(short, long)]

View File

@ -9,7 +9,7 @@ pub struct LangDebugArgs {
#[clap(default_value = ".")] #[clap(default_value = ".")]
pub path: PathBuf, pub path: PathBuf,
/// The state to dump. /// The state to dump.
#[clap(short, long, default_value = "ast")] #[clap(short, long, value_name = "STATE", default_value = "ast")]
pub dump: DumpState, pub dump: DumpState,
/// Pretty-print the output. /// Pretty-print the output.
#[clap(short, long)] #[clap(short, long)]

View File

@ -24,10 +24,14 @@ pub struct WatchArgs {
#[clap(short, long)] #[clap(short, long)]
pub no_inital: bool, pub no_inital: bool,
/// The time to wait in ms before running the command after changes are detected. /// 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, pub debounce_time: u64,
/// The commands to run in the project directory when changes are detected. /// Additional paths to watch for changes.
#[clap(short = 'x', long, default_value = "build .")] /// 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<PathBuf>,
/// 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<String>, pub execute: Vec<String>,
} }
@ -58,7 +62,16 @@ pub fn watch(_verbose: bool, args: &WatchArgs) -> Result<()> {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
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."); 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"); .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(); let watcher = debouncer.watcher();
watcher watcher
.watch(args.path.join("src").as_path(), RecursiveMode::Recursive) .watch(args.path.join("src").as_path(), RecursiveMode::Recursive)
@ -101,6 +122,32 @@ pub fn watch(_verbose: bool, args: &WatchArgs) -> Result<()> {
RecursiveMode::NonRecursive, RecursiveMode::NonRecursive,
) )
.expect("Failed to watch project pack.toml"); .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 { loop {
thread::sleep(Duration::from_secs(60)); thread::sleep(Duration::from_secs(60));