add option for asset folder

This commit is contained in:
Moritz Hölting 2024-06-10 16:01:06 +02:00
parent 074bf4cc9d
commit 61959b17e9
7 changed files with 122 additions and 22 deletions

View File

@ -24,8 +24,8 @@ colored = "2.1.0"
serde = { version = "1.0.197", features = ["derive"] }
thiserror = "1.0.58"
toml = "0.8.12"
shulkerscript-lang = { git = "https://github.com/moritz-hoelting/shulkerscript-lang", features = ["shulkerbox"], default-features = false, rev = "09b389c2060e73f686d92df3c45290c2c1b34ecb"}
shulkerbox = { git = "https://github.com/moritz-hoelting/shulkerbox", default-features = false, rev = "296502dcc5dd29b3d930ffec91ceec3d161e0e47" }
shulkerscript-lang = { git = "https://github.com/moritz-hoelting/shulkerscript-lang", features = ["shulkerbox"], default-features = false, rev = "44d634355b4ab5b652de56b0becd61b05680c068"}
shulkerbox = { git = "https://github.com/moritz-hoelting/shulkerbox", default-features = false, rev = "b79c9ecd6d45f9319c9083a8103ef0186839b0c0" }
git2 = { version = "0.18.3", default-features = false }
path-absolutize = "3.1.1"
color-eyre = "0.6.3"

View File

@ -1,12 +1,15 @@
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ProjectConfig {
pub pack: PackConfig,
pub compiler: Option<CompilerConfig>,
}
impl ProjectConfig {
pub fn new(pack: PackConfig) -> Self {
Self { pack }
pub fn new(pack: PackConfig, compiler: Option<CompilerConfig>) -> Self {
Self { pack, compiler }
}
}
@ -47,3 +50,15 @@ impl Default for PackConfig {
fn default_pack_format() -> u8 {
26
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompilerConfig {
/// The path of a folder which files and subfolders will be copied to the root of the datapack.
pub assets: Option<PathBuf>,
}
impl CompilerConfig {
pub fn new(assets: Option<PathBuf>) -> Self {
Self { assets }
}
}

View File

@ -1,10 +1,11 @@
use color_eyre::eyre::Result;
use path_absolutize::Absolutize;
use shulkerbox::virtual_fs::VFolder;
use crate::{
config::ProjectConfig,
error::Error,
terminal_output::{print_error, print_info},
terminal_output::{print_error, print_info, print_warning},
};
use std::{
env, fs,
@ -17,8 +18,13 @@ pub struct BuildArgs {
#[clap(default_value = ".")]
pub path: PathBuf,
/// The path of the directory to place the compiled datapack.
/// Overrides the `DATAPACK_DIR` environment variable.
#[clap(short, long)]
pub output: Option<PathBuf>,
/// 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.
#[clap(short, long)]
pub assets: Option<PathBuf>,
}
pub fn build(_verbose: bool, args: &BuildArgs) -> Result<()> {
@ -29,7 +35,7 @@ pub fn build(_verbose: bool, args: &BuildArgs) -> Result<()> {
.or_else(|| env::var("DATAPACK_DIR").ok().map(PathBuf::from))
.unwrap_or_else(|| path.join("dist"));
print_info(&format!(
print_info(format!(
"Building project at {}",
path.absolutize()?.display()
));
@ -51,11 +57,39 @@ pub fn build(_verbose: bool, args: &BuildArgs) -> Result<()> {
let compiled = shulkerscript_lang::compile(&script_paths)?;
let assets_path = args.assets.clone().or(project_config
.compiler
.as_ref()
.and_then(|c| c.assets.as_ref().map(|p| path.join(p))));
let output = if let Some(assets_path) = assets_path {
let assets = VFolder::try_from(assets_path.as_path());
if assets.is_err() {
print_error(format!(
"The specified assets path does not exist: {}",
assets_path.display()
));
}
let mut assets = assets?;
let replaced = assets.merge(compiled);
for replaced in replaced {
print_warning(format!(
"Template file {} was replaced by a file in the compiled datapack",
replaced
));
}
assets
} else {
compiled
};
let dist_path = dist_path.join(project_config.pack.name);
compiled.place(&dist_path)?;
output.place(&dist_path)?;
print_info(&format!(
print_info(format!(
"Finished building project to {}",
dist_path.absolutize_from(path)?.display()
));

View File

@ -44,7 +44,7 @@ pub fn clean(verbose: bool, args: &CleanArgs) -> Result<()> {
delete_paths.push(dist_path.join(project_config.pack.name + ".zip"));
}
print_info(&format!(
print_info(format!(
"Cleaning project at {}",
path.absolutize_from(path)?.display()
));
@ -67,7 +67,7 @@ pub fn clean(verbose: bool, args: &CleanArgs) -> Result<()> {
&& dist_path.read_dir()?.next().is_none()
{
if verbose {
print_info(&format!("Deleting {:?}, as it is empty", dist_path));
print_info(format!("Deleting {:?}, as it is empty", dist_path));
}
std::fs::remove_dir(&dist_path)?;
}

View File

@ -118,7 +118,7 @@ fn create_pack_config(
fs::write(&path, toml::to_string_pretty(&content)?)?;
if verbose {
print_info(&format!(
print_info(format!(
"Created pack.toml file at {}.",
path.absolutize()?.display()
));
@ -130,7 +130,7 @@ fn create_dir(path: &Path, verbose: bool) -> std::io::Result<()> {
if !path.exists() {
fs::create_dir(path)?;
if verbose {
print_info(&format!(
print_info(format!(
"Created directory at {}.",
path.absolutize()?.display()
));
@ -143,7 +143,7 @@ fn create_gitignore(path: &Path, verbose: bool) -> std::io::Result<()> {
let gitignore = path.join(".gitignore");
fs::write(&gitignore, "/dist\n")?;
if verbose {
print_info(&format!(
print_info(format!(
"Created .gitignore file at {}.",
gitignore.absolutize()?.display()
));
@ -155,7 +155,7 @@ fn create_pack_png(path: &Path, verbose: bool) -> std::io::Result<()> {
let pack_png = path.join("pack.png");
fs::write(&pack_png, include_bytes!("../../assets/default-icon.png"))?;
if verbose {
print_info(&format!(
print_info(format!(
"Created pack.png file at {}.",
pack_png.absolutize()?.display()
));
@ -173,7 +173,7 @@ fn create_main_file(path: &Path, namespace: &str, verbose: bool) -> std::io::Res
),
)?;
if verbose {
print_info(&format!(
print_info(format!(
"Created main.shu file at {}.",
main_file.absolutize()?.display()
));

View File

@ -2,8 +2,12 @@ use std::{env, path::PathBuf};
use color_eyre::eyre::Result;
use path_absolutize::Absolutize;
use shulkerbox::virtual_fs::VFolder;
use crate::{error::Error, terminal_output::print_info};
use crate::{
error::Error,
terminal_output::{print_error, print_info, print_warning},
};
use super::BuildArgs;
@ -22,7 +26,7 @@ pub fn package(_verbose: bool, args: &PackageArgs) -> Result<()> {
.or_else(|| env::var("DATAPACK_DIR").ok().map(PathBuf::from))
.unwrap_or_else(|| path.join("dist"));
print_info(&format!(
print_info(format!(
"Packaging project at {}",
path.absolutize()?.display()
));
@ -38,11 +42,39 @@ pub fn package(_verbose: bool, args: &PackageArgs) -> Result<()> {
let compiled = shulkerscript_lang::compile(&script_paths)?;
let assets_path = args.build_args.assets.clone().or(project_config
.compiler
.as_ref()
.and_then(|c| c.assets.as_ref().map(|p| path.join(p))));
let output = if let Some(assets_path) = assets_path {
let assets = VFolder::try_from(assets_path.as_path());
if assets.is_err() {
print_error(format!(
"The specified assets path does not exist: {}",
assets_path.display()
));
}
let mut assets = assets?;
let replaced = assets.merge(compiled);
for replaced in replaced {
print_warning(format!(
"Template file {} was replaced by a file in the compiled datapack",
replaced
));
}
assets
} else {
compiled
};
let dist_path = dist_path.join(project_config.pack.name + ".zip");
compiled.zip(&dist_path)?;
output.zip(&dist_path)?;
print_info(&format!(
print_info(format!(
"Finished packaging project to {}",
dist_path.absolutize_from(path)?.display()
));

View File

@ -1,12 +1,31 @@
use std::fmt::Display;
use colored::Colorize;
pub fn print_info(msg: &str) {
pub fn print_info<D>(msg: D)
where
D: Display,
{
println!("[{}] {msg}", "INFO".blue())
}
pub fn print_success(msg: &str) {
pub fn print_success<D>(msg: D)
where
D: Display,
{
println!("[{}] {msg}", "SUCCESS".green())
}
pub fn print_error(msg: &str) {
pub fn print_warning<D>(msg: D)
where
D: Display,
{
println!("[{}] {msg}", "WARNING".yellow())
}
pub fn print_error<D>(msg: D)
where
D: Display,
{
println!("[{}] {msg}", "ERROR".red())
}