fix incorrect pack version and setup human panic

This commit is contained in:
Moritz Hölting 2024-06-24 21:55:06 +02:00
parent 7da26c9590
commit 8c9e32e0ec
10 changed files with 99 additions and 61 deletions

View File

@ -29,11 +29,10 @@ colored = "2.1.0"
serde = { version = "1.0.197", features = ["derive"] }
thiserror = "1.0.58"
toml = "0.8.12"
shulkerscript = { git = "https://github.com/moritz-hoelting/shulkerscript-lang", features = ["shulkerbox"], default-features = false, rev = "dd79541ae914140df4141fe90f71e74fb961f3a3" }
shulkerbox = { git = "https://github.com/moritz-hoelting/shulkerbox", default-features = false, rev = "e31f9f904a5f5905e912907d988c189ffc8cf313" }
shulkerscript = { git = "https://github.com/moritz-hoelting/shulkerscript-lang.git", features = ["shulkerbox"], default-features = false, rev = "a0a27cda96e1922b019b216961c39f7ef7991d22" }
shulkerbox = { git = "https://github.com/moritz-hoelting/shulkerbox.git", default-features = false, rev = "a2d20dab8ea97bbd873edafb23afaad34292457f" }
git2 = { version = "0.19.0", default-features = false }
path-absolutize = "3.1.1"
color-eyre = "0.6.3"
dotenvy = "0.15.7"
notify-debouncer-mini = { version = "0.4.1", default-features = false, optional = true }
ctrlc = { version = "3.4.4", optional = true }
@ -42,3 +41,5 @@ tracing-subscriber = "0.3.18"
# waiting for pull request to be merged
inquire = { git = "https://github.com/moritz-hoelting/rust-inquire.git", branch = "main", package = "inquire" }
camino = "1.1.7"
human-panic = "2.0.0"
anyhow = "1.0.86"

View File

@ -32,6 +32,7 @@ Where [PATH] is the path of the project folder to build [default: `.`]
Options:
- `--assets <ASSETS>` The path to the assets directory [default: `./assets`]
- `--output <OUTPUT>` The output directory, overrides the `DATAPACK_DIR` environment variable
- `--no-validate` Do not validate the output to be compatible with the pack format
- `--zip` Package the output into a zip file
Environment variables:

View File

@ -1,7 +1,7 @@
use crate::subcommands::{self, BuildArgs, CleanArgs, InitArgs};
use anyhow::Result;
use clap::{Parser, Subcommand, ValueEnum};
use color_eyre::eyre::Result;
use tracing::Level;
use tracing_subscriber::FmtSubscriber;
@ -54,7 +54,7 @@ pub enum TracingLevel {
impl Args {
pub fn run(&self) -> Result<()> {
if let Some(level) = self.trace {
setup_tracing(level);
setup_tracing(level)?;
}
self.cmd.run()
@ -89,7 +89,7 @@ impl From<TracingLevel> for Level {
}
}
fn setup_tracing(level: TracingLevel) {
fn setup_tracing(level: TracingLevel) -> Result<()> {
// a builder for `FmtSubscriber`.
let subscriber = FmtSubscriber::builder()
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
@ -98,7 +98,9 @@ fn setup_tracing(level: TracingLevel) {
// completes the builder.
.finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
tracing::subscriber::set_global_default(subscriber)?;
Ok(())
}
#[cfg(test)]

View File

@ -13,6 +13,8 @@ pub enum Error {
InvalidPackPathError(PathBuf),
#[error("An error occured because the feature {0} is not enabled.")]
FeatureNotEnabledError(String),
#[error("An error occured because the pack version does not support a used feature")]
IncompatiblePackVersionError,
}
#[allow(dead_code)]

6
src/lib.rs Normal file
View File

@ -0,0 +1,6 @@
pub mod cli;
pub mod config;
pub mod error;
pub mod subcommands;
pub mod terminal_output;
pub mod util;

View File

@ -1,18 +1,14 @@
mod cli;
mod config;
mod error;
mod subcommands;
mod terminal_output;
mod util;
use std::process::ExitCode;
use clap::Parser;
use cli::Args;
use shulkerscript_cli::{cli::Args, terminal_output::print_info};
fn main() -> ExitCode {
color_eyre::install().unwrap();
let _ = dotenvy::dotenv();
human_panic::setup_panic!();
if dotenvy::dotenv().is_ok() {
print_info("Using environment variables from .env file");
}
let args = Args::parse();

View File

@ -1,6 +1,10 @@
use color_eyre::eyre::{Report, Result};
use anyhow::Result;
use path_absolutize::Absolutize;
use shulkerbox::virtual_fs::{VFile, VFolder};
use shulkerbox::{
util::compile::CompileOptions,
virtual_fs::{VFile, VFolder},
};
use shulkerscript::base::FsProvider;
use crate::{
config::ProjectConfig,
@ -32,25 +36,15 @@ pub struct BuildArgs {
/// Package the project to a zip file.
#[arg(short, long)]
pub zip: bool,
}
impl Default for BuildArgs {
fn default() -> Self {
Self {
path: PathBuf::from("."),
output: None,
assets: None,
zip: false,
}
}
/// Skip validating the project for pack format compatibility.
#[arg(long)]
pub no_validate: 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(Report::from(Error::FeatureNotEnabledError(
"zip".to_string(),
)));
return Err(Error::FeatureNotEnabledError("zip".to_string()).into());
}
let path = args.path.as_path();
@ -76,7 +70,21 @@ pub fn build(args: &BuildArgs) -> Result<()> {
.join("src"),
)?;
let mut compiled = shulkerscript::compile(&script_paths)?;
let datapack = shulkerscript::transpile(
&FsProvider::default(),
project_config.pack.pack_format,
&script_paths,
)?;
if !args.no_validate && !datapack.validate() {
print_warning(format!(
"The datapack is not compatible with the specified pack format: {}",
project_config.pack.pack_format
));
return Err(Error::IncompatiblePackVersionError.into());
}
let mut compiled = datapack.compile(&CompileOptions::default());
let icon_path = toml_path.parent().unwrap().join("pack.png");
@ -120,7 +128,13 @@ pub fn build(args: &BuildArgs) -> Result<()> {
#[cfg(feature = "zip")]
if args.zip {
output.zip(&dist_path)?;
output.zip_with_comment(
&dist_path,
format!(
"{} - v{}",
&project_config.pack.description, &project_config.pack.version
),
)?;
} else {
output.place(&dist_path)?;
}

View File

@ -1,6 +1,6 @@
use std::{borrow::Cow, path::PathBuf};
use color_eyre::eyre::Result;
use anyhow::Result;
use path_absolutize::Absolutize;
use crate::terminal_output::{print_error, print_info, print_success};

View File

@ -5,8 +5,8 @@ use std::{
path::{Path, PathBuf},
};
use anyhow::Result;
use clap::ValueEnum;
use color_eyre::eyre::Result;
use git2::{
IndexAddOption as GitIndexAddOption, Repository as GitRepository, Signature as GitSignature,
};
@ -143,28 +143,36 @@ fn initialize_interactive(args: &InitArgs) -> Result<()> {
if !path.exists() {
if force {
fs::create_dir_all(path)?;
} else if let Ok(true) =
inquire::Confirm::new("The specified path does not exist. Do you want to create it?")
} else {
match inquire::Confirm::new(
"The specified path does not exist. Do you want to create it?",
)
.with_default(true)
.prompt()
{
fs::create_dir_all(path)?;
} else {
Ok(true) => fs::create_dir_all(path)?,
Ok(false) | Err(_) => {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
}
}
} else if !path.is_dir() {
print_error("The specified path is not a directory.");
Err(Error::NotDirectoryError(path.to_path_buf()))?
} else if !force && path.read_dir()?.next().is_some() {
if let Ok(false) =
inquire::Confirm::new("The specified directory is not empty. Do you want to continue?")
match inquire::Confirm::new(
"The specified directory is not empty. Do you want to continue?",
)
.with_default(false)
.with_help_message("This may overwrite existing files in the directory.")
.prompt()
{
Ok(false) | Err(_) => {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
Ok(true) => {}
}
}
@ -195,7 +203,7 @@ fn initialize_interactive(args: &InitArgs) -> Result<()> {
if interrupted {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
let description = description.map(Cow::Borrowed).or_else(|| {
@ -213,7 +221,7 @@ fn initialize_interactive(args: &InitArgs) -> Result<()> {
if interrupted {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
let pack_format = pack_format.or_else(|| {
@ -231,7 +239,7 @@ fn initialize_interactive(args: &InitArgs) -> Result<()> {
if interrupted {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
let vcs = args.vcs.unwrap_or_else(|| {
@ -252,7 +260,7 @@ fn initialize_interactive(args: &InitArgs) -> Result<()> {
if interrupted {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
let icon_path = args.icon_path.as_deref().map(Cow::Borrowed).or_else(|| {
@ -277,7 +285,7 @@ fn initialize_interactive(args: &InitArgs) -> Result<()> {
if interrupted {
print_info(ABORT_MSG);
return Ok(());
return Err(inquire::InquireError::OperationCanceled.into());
}
print_info("Initializing a new Shulkerscript project...");

View File

@ -1,8 +1,11 @@
use clap::ValueEnum;
use color_eyre::eyre::Result;
use anyhow::Result;
use shulkerscript::base::FsProvider;
use std::path::PathBuf;
use crate::config::PackConfig;
#[derive(Debug, clap::Args, Clone)]
pub struct LangDebugArgs {
/// The path of the project to compile.
@ -27,9 +30,10 @@ pub enum DumpState {
}
pub fn lang_debug(args: &LangDebugArgs) -> Result<()> {
let file_provider = FsProvider::default();
match args.dump {
DumpState::Tokens => {
let tokens = shulkerscript::tokenize(&args.path)?;
let tokens = shulkerscript::tokenize(&file_provider, &args.path)?;
if args.pretty {
println!("{:#?}", tokens);
} else {
@ -37,7 +41,7 @@ pub fn lang_debug(args: &LangDebugArgs) -> Result<()> {
}
}
DumpState::Ast => {
let ast = shulkerscript::parse(&args.path)?;
let ast = shulkerscript::parse(&file_provider, &args.path)?;
if args.pretty {
println!("{:#?}", ast);
} else {
@ -46,7 +50,11 @@ pub fn lang_debug(args: &LangDebugArgs) -> Result<()> {
}
DumpState::Datapack => {
let program_paths = super::build::get_script_paths(&args.path.join("src"))?;
let datapack = shulkerscript::transpile(&program_paths)?;
let datapack = shulkerscript::transpile(
&file_provider,
PackConfig::DEFAULT_PACK_FORMAT,
&program_paths,
)?;
if args.pretty {
println!("{:#?}", datapack);
} else {