From 1c1d07dd938496cf80f3d6aec0239fe839148c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=B6lting=2C=20Moritz=20=28Intern=29?= Date: Wed, 27 Aug 2025 12:58:37 +0200 Subject: [PATCH] update to use shulkerscript branch feature/variables --- Cargo.lock | 26 ++++++++++++-------------- Cargo.toml | 31 ++++++++++++++++--------------- src/cli.rs | 8 ++++---- src/config.rs | 3 +++ src/error.rs | 4 ++-- src/main.rs | 16 +++++++++++++--- src/subcommands/build.rs | 32 ++++++++++++++++++++++---------- src/subcommands/clean.rs | 2 +- src/subcommands/lang_debug.rs | 2 ++ src/subcommands/migrate.rs | 7 +++---- src/subcommands/watch.rs | 6 +++--- src/util.rs | 27 +++++++++++++++++++++++++++ 12 files changed, 108 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecfdef5..c49916c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "arbitrary" @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -207,9 +207,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -550,9 +550,9 @@ dependencies = [ [[package]] name = "human-panic" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c5a08ed290eac04006e21e63d32e90086b6182c7cd0452d10f4264def1fec9a" +checksum = "80b84a66a325082740043a6c28bbea400c129eac0d3a27673a1de971e44bf1f7" dependencies = [ "anstream", "anstyle", @@ -977,9 +977,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" [[package]] name = "percent-encoding" @@ -1134,9 +1134,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -1171,8 +1171,6 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "shulkerbox" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18704338e25effa7d02ab8d83c453814a54163b66464693bb4aac0012f05db8b" dependencies = [ "chksum-md5", "getset", diff --git a/Cargo.toml b/Cargo.toml index 205163b..07cb315 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,24 +28,25 @@ watch = ["dep:notify-debouncer-mini", "dep:ctrlc"] zip = ["shulkerscript/zip"] [dependencies] -anyhow = "1.0.89" -clap = { version = "4.5.18", features = ["deprecated", "derive", "env"] } -colored = "2.1.0" -const_format = "0.2.33" +anyhow = "1.0.95" +clap = { version = "4.5.32", features = ["deprecated", "derive", "env"] } +colored = "3.0.0" +const_format = "0.2.34" ctrlc = { version = "3.4.5", optional = true } dotenvy = "0.15.7" -git2 = { version = "0.19.0", default-features = false } -human-panic = "2.0.1" +git2 = { version = "0.20.0", default-features = false } +human-panic = "2.0.2" indoc = { version = "2.0.5", optional = true } inquire = "0.7.5" -notify-debouncer-mini = { version = "0.4.1", default-features = false, optional = true } +notify-debouncer-mini = { version = "0.7.0", default-features = false, optional = true } path-absolutize = "3.1.1" -pathdiff = "0.2.1" -serde = { version = "1.0.210", features = ["derive"] } -serde_json = { version = "1.0.128", optional = true } -shulkerscript = { version = "0.1.0", features = ["fs_access", "shulkerbox", "zip"], default-features = false } -thiserror = "1.0.63" -toml = "0.8.19" -tracing = "0.1.40" -tracing-subscriber = "0.3.18" +pathdiff = "0.2.3" +serde = { version = "1.0.217", features = ["derive"] } +serde_json = { version = "1.0.138", optional = true } +# shulkerscript = { version = "0.1.0", features = ["fs_access", "shulkerbox"], default-features = false } +shulkerscript = { git = "https://github.com/moritz-hoelting/shulkerscript-lang", features = ["fs_access", "shulkerbox"], default-features = false, rev = "d9f2d99c3a5e09488fc85ad792501a209387a89d" } +thiserror = "2.0.11" +toml = "0.9.5" +tracing = "0.1.41" +tracing-subscriber = "0.3.19" walkdir = { version = "2.5.0", optional = true } diff --git a/src/cli.rs b/src/cli.rs index 9a33acf..2036654 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -13,8 +13,8 @@ static VERSION: &str = formatcp!( ); #[derive(Debug, Clone, Parser)] -#[command(name = "shulkerscript", about, version = VERSION, long_about = None, disable_version_flag = false)] -pub struct Args { +#[command(name = "shulkerscript", version = VERSION, about, long_about = None)] +pub struct Cli { #[command(subcommand)] cmd: Command, /// Enable tracing output @@ -61,7 +61,7 @@ pub enum TracingLevel { Error, } -impl Args { +impl Cli { pub fn run(&self) -> Result<()> { if let Some(level) = self.trace { setup_tracing(level)?; @@ -123,6 +123,6 @@ mod tests { #[test] fn verify_cli() { - Args::command().debug_assert(); + Cli::command().debug_assert(); } } diff --git a/src/config.rs b/src/config.rs index 5d980c3..73dd528 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,8 @@ pub struct ProjectConfig { pub struct PackConfig { pub name: String, pub description: String, + #[serde(alias = "main-namespace")] + pub main_namespace: Option, #[serde(rename = "format", alias = "pack_format")] pub pack_format: u8, pub version: String, @@ -29,6 +31,7 @@ impl Default for PackConfig { Self { name: Self::DEFAULT_NAME.to_string(), description: Self::DEFAULT_DESCRIPTION.to_string(), + main_namespace: None, pack_format: Self::DEFAULT_PACK_FORMAT, version: "0.1.0".to_string(), } diff --git a/src/error.rs b/src/error.rs index c9a6abb..c0a39d4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,8 +11,8 @@ pub enum Error { NotDirectoryError(PathBuf), #[error("An error occured because the path is neither a pack directory or a pack.toml file.")] InvalidPackPathError(PathBuf), - #[error("An error occured because the feature {0} is not enabled.")] - FeatureNotEnabledError(String), + #[error("An error occured because {0} is not allowed as a namespace.")] + InvalidNamespaceError(String), #[error("An error occured because the pack version does not support a used feature")] IncompatiblePackVersionError, } diff --git a/src/main.rs b/src/main.rs index f1edc5e..50c8aeb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,15 +2,25 @@ use std::process::ExitCode; use clap::Parser; -use shulkerscript_cli::{cli::Args, terminal_output::print_info}; +use shulkerscript_cli::{cli::Cli, terminal_output::print_info}; fn main() -> ExitCode { - human_panic::setup_panic!(); + human_panic::setup_panic!(human_panic::Metadata::new( + env!("CARGO_PKG_NAME"), + const_format::formatcp!( + "{cli_version};lib={lib_version}", + cli_version = env!("CARGO_PKG_VERSION"), + lib_version = shulkerscript::VERSION + ), + ) + .authors(env!("CARGO_PKG_AUTHORS").replace(":", ", ")) + .homepage(env!("CARGO_PKG_HOMEPAGE"))); + if dotenvy::dotenv().is_ok() { print_info("Using environment variables from .env file"); } - let args = Args::parse(); + let args = Cli::parse(); match args.run() { Ok(_) => ExitCode::SUCCESS, diff --git a/src/subcommands/build.rs b/src/subcommands/build.rs index c7d5ed9..461ec37 100644 --- a/src/subcommands/build.rs +++ b/src/subcommands/build.rs @@ -12,7 +12,7 @@ use crate::{ config::ProjectConfig, error::Error, terminal_output::{print_error, print_info, print_success, print_warning}, - util, + util::{self, get_project_main_namespace}, }; use std::{ borrow::Cow, @@ -37,22 +37,19 @@ pub struct BuildArgs { #[arg(short, long)] pub assets: Option, /// Package the project to a zip file. - #[cfg_attr(not(feature = "zip"), doc = "Disabled because not compiled with `zip` feature")] + #[cfg(feature = "zip")] + #[arg(short, long)] pub zip: bool, /// Skip validating the project for pack format compatibility. #[arg(long)] pub no_validate: bool, /// Check if the project can be built without actually building it. - #[arg(long, conflicts_with_all = ["output", "zip"])] + #[arg(long, conflicts_with = "output")] + #[cfg_attr(feature = "zip", arg(conflicts_with = "zip"))] pub check: bool, } pub fn build(args: &BuildArgs) -> Result<()> { - if args.zip && !cfg!(feature = "zip") { - print_error("The zip feature is not enabled. Please install with the `zip` feature enabled to use the `--zip` option."); - return Err(Error::FeatureNotEnabledError("zip".to_string()).into()); - } - let path = util::get_project_path(&args.path).unwrap_or(args.path.clone()); let dist_path = args .output @@ -60,7 +57,16 @@ pub fn build(args: &BuildArgs) -> Result<()> { .map(Cow::Borrowed) .unwrap_or_else(|| Cow::Owned(path.join("dist"))); - let and_package_msg = if args.zip { " and packaging" } else { "" }; + let zip = { + #[cfg(feature = "zip")] + { + args.zip + } + #[cfg(not(feature = "zip"))] + false + }; + + let and_package_msg = if zip { " and packaging" } else { "" }; let mut path_display = format!("{}", path.display()); if path_display.is_empty() { @@ -83,6 +89,12 @@ pub fn build(args: &BuildArgs) -> Result<()> { let datapack = shulkerscript::transpile( &PrintHandler::new(), &FsProvider::default(), + &get_project_main_namespace(&project_config).map_err(|namespace| { + print_error(format!( + "The automatically generated namespace is too short: '{namespace}'. Please specify a namespace in the pack.toml file.", + )); + Error::InvalidNamespaceError(namespace) + })?, project_config.pack.pack_format, &script_paths, )?; @@ -133,7 +145,7 @@ pub fn build(args: &BuildArgs) -> Result<()> { compiled }; - let dist_extension = if args.zip { ".zip" } else { "" }; + let dist_extension = if zip { ".zip" } else { "" }; let dist_path = dist_path.join(project_config.pack.name + dist_extension); diff --git a/src/subcommands/clean.rs b/src/subcommands/clean.rs index 9db7ab6..aa001d4 100644 --- a/src/subcommands/clean.rs +++ b/src/subcommands/clean.rs @@ -59,7 +59,7 @@ pub fn clean(args: &CleanArgs) -> Result<()> { for delete_path in delete_paths { if delete_path.exists() { if verbose { - print_info(&format!("Deleting {:?}", delete_path)); + print_info(format!("Deleting {:?}", delete_path)); } if delete_path.is_file() { std::fs::remove_file(&delete_path)?; diff --git a/src/subcommands/lang_debug.rs b/src/subcommands/lang_debug.rs index 15930ea..9fadffd 100644 --- a/src/subcommands/lang_debug.rs +++ b/src/subcommands/lang_debug.rs @@ -26,6 +26,7 @@ pub enum DumpState { Tokens, #[default] Ast, + #[value(alias = "dp")] Datapack, } @@ -71,6 +72,7 @@ pub fn lang_debug(args: &LangDebugArgs) -> Result<()> { let datapack = shulkerscript::transpile( &PrintHandler::new(), &file_provider, + "main_namespace", PackConfig::DEFAULT_PACK_FORMAT, &program_paths, )?; diff --git a/src/subcommands/migrate.rs b/src/subcommands/migrate.rs index 71e4409..c93ce66 100644 --- a/src/subcommands/migrate.rs +++ b/src/subcommands/migrate.rs @@ -106,7 +106,7 @@ struct McMetaPack { } fn is_mcmeta_compatible(mcmeta: &serde_json::Value) -> bool { - mcmeta.as_object().map_or(false, |mcmeta| { + mcmeta.as_object().is_some_and(|mcmeta| { mcmeta.len() == 1 && mcmeta.contains_key("pack") && mcmeta["pack"] @@ -136,9 +136,8 @@ fn generate_pack_toml(base_path: &Path, mcmeta: &McMeta) -> Result { } }) }) - .map_err(|e| { + .inspect_err(|_| { err = true; - e }) .unwrap_or_default() } else { @@ -268,7 +267,7 @@ fn handle_function( let function_name = function_path .split('/') - .last() + .next_back() .expect("split always returns at least one element") .replace(|c: char| !c.is_ascii_alphanumeric(), "_"); diff --git a/src/subcommands/watch.rs b/src/subcommands/watch.rs index 0b278ab..e772fb1 100644 --- a/src/subcommands/watch.rs +++ b/src/subcommands/watch.rs @@ -11,7 +11,7 @@ use colored::Colorize; use notify_debouncer_mini::{new_debouncer, notify::*, DebounceEventResult}; use crate::{ - cli::Args, + cli::Cli, error::Result, terminal_output::{print_error, print_info, print_warning}, util, @@ -74,7 +74,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> { let prog_name = std::env::args() .next() .unwrap_or(env!("CARGO_PKG_NAME").to_string()); - Args::parse_from(iter::once(prog_name.as_str()).chain(split.clone())) + Cli::parse_from(iter::once(prog_name.as_str()).chain(split.clone())) }) .collect::>(); @@ -168,7 +168,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> { } } -fn run_cmds(cmds: &[Args], no_execute: bool, shell_cmds: &[String], initial: bool) { +fn run_cmds(cmds: &[Cli], no_execute: bool, shell_cmds: &[String], initial: bool) { if initial { print_info("Running commands initially..."); } else { diff --git a/src/util.rs b/src/util.rs index f01a494..5113eef 100644 --- a/src/util.rs +++ b/src/util.rs @@ -8,6 +8,8 @@ use std::{ use inquire::{autocompletion::Replacement, Autocomplete}; use path_absolutize::Absolutize; +use crate::config::ProjectConfig; + pub fn get_project_path

(base_path: P) -> Option where P: AsRef, @@ -23,6 +25,31 @@ where .map(|p| p.relativize().unwrap_or_else(|| p.to_path_buf())) } +pub fn get_project_main_namespace(project_config: &ProjectConfig) -> Result { + project_config + .pack + .main_namespace + .as_ref() + .cloned() + .map_or_else( + || { + let namespace = project_config + .pack + .name + .to_lowercase() + .chars() + .filter(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | '.')) + .collect::(); + if namespace.len() < 5 { + Err(namespace) + } else { + Ok(namespace) + } + }, + Ok, + ) +} + pub trait Relativize { fn relativize(&self) -> Option; }