seperate shell and internal commands in watch subcommand
This commit is contained in:
parent
916901e81a
commit
e8ac54f231
|
@ -13,7 +13,7 @@ pub struct Args {
|
||||||
/// Enable tracing output
|
/// Enable tracing output
|
||||||
///
|
///
|
||||||
/// When specified without a value, defaults to `info`.
|
/// When specified without a value, defaults to `info`.
|
||||||
#[clap(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
global = true,
|
global = true,
|
||||||
default_missing_value = "info",
|
default_missing_value = "info",
|
||||||
|
|
|
@ -16,21 +16,21 @@ use std::{
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct BuildArgs {
|
pub struct BuildArgs {
|
||||||
/// The path of the project to build.
|
/// The path of the project to build.
|
||||||
#[clap(default_value = ".")]
|
#[arg(default_value = ".")]
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
/// Path of output directory
|
/// Path of output directory
|
||||||
///
|
///
|
||||||
/// The path of the directory to place the compiled datapack.
|
/// The path of the directory to place the compiled datapack.
|
||||||
#[clap(short, long, env = "DATAPACK_DIR")]
|
#[arg(short, long, env = "DATAPACK_DIR")]
|
||||||
pub output: Option<PathBuf>,
|
pub output: Option<PathBuf>,
|
||||||
/// Path of the assets folder
|
/// Path of the assets folder
|
||||||
///
|
///
|
||||||
/// The path of a folder which files and subfolders will be copied to the root of the datapack.
|
/// The path of a folder which files and subfolders will be copied to the root of the datapack.
|
||||||
/// Overrides the `assets` field in the pack.toml file.
|
/// Overrides the `assets` field in the pack.toml file.
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
pub assets: Option<PathBuf>,
|
pub assets: Option<PathBuf>,
|
||||||
/// Package the project to a zip file.
|
/// Package the project to a zip file.
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
pub zip: bool,
|
pub zip: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,19 +8,19 @@ use crate::terminal_output::{print_error, print_info, print_success};
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct CleanArgs {
|
pub struct CleanArgs {
|
||||||
/// The path of the project to clean.
|
/// The path of the project to clean.
|
||||||
#[clap(default_value = ".")]
|
#[arg(default_value = ".")]
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
/// The path of the directory where the compiled datapacks are placed.
|
/// The path of the directory where the compiled datapacks are placed.
|
||||||
#[clap(short, long, env = "DATAPACK_DIR")]
|
#[arg(short, long, env = "DATAPACK_DIR")]
|
||||||
pub output: Option<PathBuf>,
|
pub output: Option<PathBuf>,
|
||||||
/// Clean the whole output folder
|
/// Clean the whole output folder
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
pub all: bool,
|
pub all: bool,
|
||||||
/// Force clean
|
/// Force clean
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
pub force: bool,
|
pub force: bool,
|
||||||
/// Enable verbose output.
|
/// Enable verbose output.
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,25 +19,25 @@ use crate::{
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct InitArgs {
|
pub struct InitArgs {
|
||||||
/// The path of the folder to initialize in.
|
/// The path of the folder to initialize in.
|
||||||
#[clap(default_value = ".")]
|
#[arg(default_value = ".")]
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
/// The name of the project.
|
/// The name of the project.
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
/// The description of the project.
|
/// The description of the project.
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
/// The pack format version.
|
/// The pack format version.
|
||||||
#[clap(short, long, value_name = "FORMAT")]
|
#[arg(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)]
|
#[arg(short, long)]
|
||||||
pub force: bool,
|
pub force: bool,
|
||||||
/// The version control system to initialize.
|
/// The version control system to initialize.
|
||||||
#[clap(long, default_value = "git")]
|
#[arg(long, default_value = "git")]
|
||||||
pub vcs: VersionControlSystem,
|
pub vcs: VersionControlSystem,
|
||||||
/// Enable verbose output.
|
/// Enable verbose output.
|
||||||
#[clap(short, long)]
|
#[arg(short, long)]
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@ use std::path::PathBuf;
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct LangDebugArgs {
|
pub struct LangDebugArgs {
|
||||||
/// The path of the project to compile.
|
/// The path of the project to compile.
|
||||||
#[clap(default_value = ".")]
|
#[arg(default_value = ".")]
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
/// The state to dump.
|
/// The state to dump.
|
||||||
///
|
///
|
||||||
/// Output can be the raw tokens, the abstract syntax tree, or the transpiled datapack.
|
/// Output can be the raw tokens, the abstract syntax tree, or the transpiled datapack.
|
||||||
#[clap(short, long, value_name = "STATE", default_value = "ast")]
|
#[arg(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)]
|
#[arg(short, long)]
|
||||||
pub pretty: bool,
|
pub pretty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,33 +18,42 @@ use crate::{
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct WatchArgs {
|
pub struct WatchArgs {
|
||||||
/// The path of the project to watch.
|
/// The path of the project to watch.
|
||||||
#[clap(default_value = ".")]
|
#[arg(default_value = ".")]
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
/// Only run after changes are detected.
|
/// Only run after changes are detected.
|
||||||
///
|
///
|
||||||
/// Skips the initial run of the commands.
|
/// Skips the initial run of the commands.
|
||||||
#[clap(short, long)]
|
#[arg(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, value_name = "TIME_IN_MS", default_value = "2000")]
|
#[arg(short, long, value_name = "TIME_IN_MS", default_value = "2000")]
|
||||||
pub debounce_time: u64,
|
pub debounce_time: u64,
|
||||||
/// Additional paths to watch for changes.
|
/// Additional paths to watch for changes.
|
||||||
///
|
///
|
||||||
/// By default, the `src` directory, `pack.png`, and `pack.toml` as well as the defined
|
/// By default, the `src` directory, `pack.png`, and `pack.toml` as well as the defined
|
||||||
/// assets directory in the config are watched.
|
/// assets directory in the config are watched.
|
||||||
#[clap(short, long, value_name = "PATH")]
|
#[arg(short, long, value_name = "PATH")]
|
||||||
pub watch: Vec<PathBuf>,
|
pub watch: Vec<PathBuf>,
|
||||||
/// The commands to run in the project directory when changes are detected.
|
/// The shulkerscript commands to run in the project directory when changes are detected.
|
||||||
///
|
///
|
||||||
/// Use multiple times to run multiple commands.
|
/// Use multiple times to run multiple commands.
|
||||||
#[clap(short = 'x', long, value_name = "COMMAND", default_value = "build .")]
|
/// Internal commands will always run before shell commands and a command will only run if the
|
||||||
|
/// previous one exited successfully.
|
||||||
|
///
|
||||||
|
/// Use the `--no-execute` flag to disable running these commands, useful when only wanting to
|
||||||
|
/// run shell commands and not default build command.
|
||||||
|
#[arg(short = 'x', long, value_name = "COMMAND", default_value = "build .")]
|
||||||
pub execute: Vec<String>,
|
pub execute: Vec<String>,
|
||||||
}
|
/// Do not run the internal shulkerscript commands specified by `--execute` (and the default one).
|
||||||
|
#[arg(short = 'X', long)]
|
||||||
#[derive(Debug, Clone)]
|
pub no_execute: bool,
|
||||||
enum WatchCommand {
|
/// The shell commands to run in the project directory when changes are detected.
|
||||||
Internal(Args),
|
///
|
||||||
External(String),
|
/// Use multiple times to run multiple commands.
|
||||||
|
/// Shell commands will always run after shulkerscript commands and a command will only run
|
||||||
|
/// if the previous one exited successfully.
|
||||||
|
#[arg(short, long, value_name = "COMMAND")]
|
||||||
|
pub shell: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn watch(args: &WatchArgs) -> Result<()> {
|
pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
|
@ -58,13 +67,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
let prog_name = std::env::args()
|
let prog_name = std::env::args()
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or(env!("CARGO_PKG_NAME").to_string());
|
.unwrap_or(env!("CARGO_PKG_NAME").to_string());
|
||||||
if let Ok(args) =
|
Args::parse_from(iter::once(prog_name.as_str()).chain(split.clone()))
|
||||||
Args::try_parse_from(iter::once(prog_name.as_str()).chain(split.clone()))
|
|
||||||
{
|
|
||||||
WatchCommand::Internal(args)
|
|
||||||
} else {
|
|
||||||
WatchCommand::External(cmd.to_owned())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -83,7 +86,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
|
|
||||||
#[allow(clippy::collapsible_if)]
|
#[allow(clippy::collapsible_if)]
|
||||||
if !args.no_inital {
|
if !args.no_inital {
|
||||||
run_cmds(&commands, true);
|
run_cmds(&commands, args.no_execute, &args.shell, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrlc::set_handler(move || {
|
ctrlc::set_handler(move || {
|
||||||
|
@ -92,11 +95,14 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
})
|
})
|
||||||
.expect("Error setting Ctrl-C handler");
|
.expect("Error setting Ctrl-C handler");
|
||||||
|
|
||||||
|
let shell_commands = args.shell.clone();
|
||||||
|
let no_execute = args.no_execute;
|
||||||
|
|
||||||
let mut debouncer = new_debouncer(
|
let mut debouncer = new_debouncer(
|
||||||
Duration::from_millis(args.debounce_time),
|
Duration::from_millis(args.debounce_time),
|
||||||
move |res: DebounceEventResult| {
|
move |res: DebounceEventResult| {
|
||||||
if res.is_ok() {
|
if res.is_ok() {
|
||||||
run_cmds(&commands, false)
|
run_cmds(&commands, no_execute, &shell_commands, false)
|
||||||
} else {
|
} else {
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
@ -160,40 +166,38 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_cmds(cmds: &[WatchCommand], initial: bool) {
|
fn run_cmds(cmds: &[Args], no_execute: bool, shell_cmds: &[String], initial: bool) {
|
||||||
if initial {
|
if initial {
|
||||||
print_info("Running commands initially...");
|
print_info("Running commands initially...");
|
||||||
} else {
|
} else {
|
||||||
print_info("Changes have been detected. Running commands...");
|
print_info("Changes have been detected. Running commands...");
|
||||||
}
|
}
|
||||||
for (index, cmd) in cmds.iter().enumerate() {
|
if !no_execute {
|
||||||
match cmd {
|
for (index, args) in cmds.iter().enumerate() {
|
||||||
WatchCommand::Internal(args) => {
|
|
||||||
if args.run().is_err() {
|
if args.run().is_err() {
|
||||||
print_error(format!("Error running command: {}", index + 1));
|
print_error(format!("Error running command: {}", index + 1));
|
||||||
print_error("Not running further commands.");
|
print_error("Not running further commands.");
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WatchCommand::External(cmd) => {
|
}
|
||||||
|
for (index, cmd) in shell_cmds.iter().enumerate() {
|
||||||
let status = run_shell_cmd(cmd);
|
let status = run_shell_cmd(cmd);
|
||||||
match status {
|
match status {
|
||||||
Ok(status) if !status.success() => {
|
Ok(status) if !status.success() => {
|
||||||
print_error(format!(
|
print_error(format!(
|
||||||
"Command {} exited unsuccessfully with status code {}",
|
"Shell command {} exited unsuccessfully with status code {}",
|
||||||
index + 1,
|
index + 1,
|
||||||
status.code().unwrap_or(1)
|
status.code().unwrap_or(1)
|
||||||
));
|
));
|
||||||
print_error("Not running further commands.");
|
print_error("Not running further shell commands.");
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
print_error(format!("Error running command: {}", index + 1));
|
print_error(format!("Error running shell command: {}", index + 1));
|
||||||
print_error("Not running further commands.");
|
print_error("Not running further shell commands.");
|
||||||
break;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue