allow running commands in subfolder of project
This commit is contained in:
parent
8c9e32e0ec
commit
bc6975e52f
|
@ -43,3 +43,4 @@ inquire = { git = "https://github.com/moritz-hoelting/rust-inquire.git", branch
|
||||||
camino = "1.1.7"
|
camino = "1.1.7"
|
||||||
human-panic = "2.0.0"
|
human-panic = "2.0.0"
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
|
pathdiff = "0.2.1"
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::{
|
||||||
config::ProjectConfig,
|
config::ProjectConfig,
|
||||||
error::Error,
|
error::Error,
|
||||||
terminal_output::{print_error, print_info, print_success, print_warning},
|
terminal_output::{print_error, print_info, print_success, print_warning},
|
||||||
|
util,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
@ -47,7 +48,7 @@ pub fn build(args: &BuildArgs) -> Result<()> {
|
||||||
return Err(Error::FeatureNotEnabledError("zip".to_string()).into());
|
return Err(Error::FeatureNotEnabledError("zip".to_string()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = args.path.as_path();
|
let path = util::get_project_path(&args.path).unwrap_or(args.path.clone());
|
||||||
let dist_path = args
|
let dist_path = args
|
||||||
.output
|
.output
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -56,12 +57,16 @@ pub fn build(args: &BuildArgs) -> Result<()> {
|
||||||
|
|
||||||
let and_package_msg = if args.zip { " and packaging" } else { "" };
|
let and_package_msg = if args.zip { " and packaging" } else { "" };
|
||||||
|
|
||||||
|
let mut path_display = format!("{}", path.display());
|
||||||
|
if path_display.is_empty() {
|
||||||
|
path_display.push('.');
|
||||||
|
}
|
||||||
|
|
||||||
print_info(format!(
|
print_info(format!(
|
||||||
"Building{and_package_msg} project at {}",
|
"Building{and_package_msg} project at {path_display}"
|
||||||
path.absolutize()?.display()
|
|
||||||
));
|
));
|
||||||
|
|
||||||
let (project_config, toml_path) = get_pack_config(path)?;
|
let (project_config, toml_path) = get_pack_config(&path)?;
|
||||||
|
|
||||||
let script_paths = get_script_paths(
|
let script_paths = get_script_paths(
|
||||||
&toml_path
|
&toml_path
|
||||||
|
@ -198,6 +203,7 @@ fn _get_script_paths(path: &Path, prefix: &str) -> std::io::Result<Vec<(String,
|
||||||
/// - If the specified path does not exist.
|
/// - If the specified path does not exist.
|
||||||
/// - If the specified directory does not contain a pack.toml file.
|
/// - If the specified directory does not contain a pack.toml file.
|
||||||
pub(super) fn get_pack_config(path: &Path) -> Result<(ProjectConfig, PathBuf)> {
|
pub(super) fn get_pack_config(path: &Path) -> Result<(ProjectConfig, PathBuf)> {
|
||||||
|
let path = path.absolutize()?;
|
||||||
let toml_path = if !path.exists() {
|
let toml_path = if !path.exists() {
|
||||||
print_error("The specified path does not exist.");
|
print_error("The specified path does not exist.");
|
||||||
return Err(Error::PathNotFoundError(path.to_path_buf()))?;
|
return Err(Error::PathNotFoundError(path.to_path_buf()))?;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use std::{borrow::Cow, path::PathBuf};
|
use std::{borrow::Cow, path::PathBuf};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use path_absolutize::Absolutize;
|
use path_absolutize::Absolutize as _;
|
||||||
|
|
||||||
use crate::terminal_output::{print_error, print_info, print_success};
|
use crate::{
|
||||||
|
terminal_output::{print_error, print_info, print_success},
|
||||||
|
util,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct CleanArgs {
|
pub struct CleanArgs {
|
||||||
|
@ -26,7 +29,7 @@ pub struct CleanArgs {
|
||||||
|
|
||||||
pub fn clean(args: &CleanArgs) -> Result<()> {
|
pub fn clean(args: &CleanArgs) -> Result<()> {
|
||||||
let verbose = args.verbose;
|
let verbose = args.verbose;
|
||||||
let path = args.path.as_path();
|
let path = util::get_project_path(&args.path).unwrap_or(args.path.clone());
|
||||||
let dist_path = args
|
let dist_path = args
|
||||||
.output
|
.output
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -35,7 +38,7 @@ pub fn clean(args: &CleanArgs) -> Result<()> {
|
||||||
|
|
||||||
let mut delete_paths = Vec::new();
|
let mut delete_paths = Vec::new();
|
||||||
|
|
||||||
let (project_config, _) = super::build::get_pack_config(path)?;
|
let (project_config, _) = super::build::get_pack_config(&path)?;
|
||||||
|
|
||||||
if args.all {
|
if args.all {
|
||||||
if args.force {
|
if args.force {
|
||||||
|
@ -50,7 +53,7 @@ pub fn clean(args: &CleanArgs) -> Result<()> {
|
||||||
|
|
||||||
print_info(format!(
|
print_info(format!(
|
||||||
"Cleaning project at {}",
|
"Cleaning project at {}",
|
||||||
path.absolutize_from(path)?.display()
|
path.absolutize_from(&path)?.display()
|
||||||
));
|
));
|
||||||
|
|
||||||
for delete_path in delete_paths {
|
for delete_path in delete_paths {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||||
use shulkerscript::base::FsProvider;
|
use shulkerscript::base::FsProvider;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::config::PackConfig;
|
use crate::{config::PackConfig, util};
|
||||||
|
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
pub struct LangDebugArgs {
|
pub struct LangDebugArgs {
|
||||||
|
@ -49,7 +49,11 @@ pub fn lang_debug(args: &LangDebugArgs) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DumpState::Datapack => {
|
DumpState::Datapack => {
|
||||||
let program_paths = super::build::get_script_paths(&args.path.join("src"))?;
|
let program_paths = super::build::get_script_paths(
|
||||||
|
&util::get_project_path(&args.path)
|
||||||
|
.unwrap_or(args.path.clone())
|
||||||
|
.join("src"),
|
||||||
|
)?;
|
||||||
let datapack = shulkerscript::transpile(
|
let datapack = shulkerscript::transpile(
|
||||||
&file_provider,
|
&file_provider,
|
||||||
PackConfig::DEFAULT_PACK_FORMAT,
|
PackConfig::DEFAULT_PACK_FORMAT,
|
||||||
|
|
|
@ -7,12 +7,14 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use colored::Colorize;
|
||||||
use notify_debouncer_mini::{new_debouncer, notify::*, DebounceEventResult};
|
use notify_debouncer_mini::{new_debouncer, notify::*, DebounceEventResult};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::Args,
|
cli::Args,
|
||||||
error::Result,
|
error::Result,
|
||||||
terminal_output::{print_error, print_info, print_warning},
|
terminal_output::{print_error, print_info, print_warning},
|
||||||
|
util,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, clap::Args, Clone)]
|
#[derive(Debug, clap::Args, Clone)]
|
||||||
|
@ -57,7 +59,12 @@ pub struct WatchArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn watch(args: &WatchArgs) -> Result<()> {
|
pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
print_info(format!("Watching project at {}", args.path.display()));
|
let path = util::get_project_path(&args.path).unwrap_or(args.path.clone());
|
||||||
|
print_info(format!("Watching project at {}", path.display()));
|
||||||
|
print_info(format!(
|
||||||
|
"Press {} to stop watching",
|
||||||
|
"Ctrl-C".underline().blue()
|
||||||
|
));
|
||||||
|
|
||||||
let commands = args
|
let commands = args
|
||||||
.execute
|
.execute
|
||||||
|
@ -78,9 +85,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
env::current_dir().ok()
|
env::current_dir().ok()
|
||||||
};
|
};
|
||||||
|
|
||||||
if !args.no_inital
|
if !args.no_inital && (current_dir.is_none() || env::set_current_dir(&path).is_err()) {
|
||||||
&& (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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,28 +119,25 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
env::set_current_dir(prev_cwd).expect("Failed to change working directory back");
|
env::set_current_dir(prev_cwd).expect("Failed to change working directory back");
|
||||||
}
|
}
|
||||||
|
|
||||||
let assets_path = super::build::get_pack_config(&args.path)
|
let assets_path = super::build::get_pack_config(&path)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|(conf, _)| conf.compiler.and_then(|c| c.assets));
|
.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(path.join("src").as_path(), RecursiveMode::Recursive)
|
||||||
.expect("Failed to watch project src");
|
.expect("Failed to watch project src");
|
||||||
watcher
|
watcher
|
||||||
.watch(
|
.watch(path.join("pack.png").as_path(), RecursiveMode::NonRecursive)
|
||||||
args.path.join("pack.png").as_path(),
|
|
||||||
RecursiveMode::NonRecursive,
|
|
||||||
)
|
|
||||||
.expect("Failed to watch project pack.png");
|
.expect("Failed to watch project pack.png");
|
||||||
watcher
|
watcher
|
||||||
.watch(
|
.watch(
|
||||||
args.path.join("pack.toml").as_path(),
|
path.join("pack.toml").as_path(),
|
||||||
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 {
|
if let Some(assets_path) = assets_path {
|
||||||
let full_assets_path = args.path.join(assets_path);
|
let full_assets_path = path.join(assets_path);
|
||||||
if full_assets_path.exists() {
|
if full_assets_path.exists() {
|
||||||
watcher
|
watcher
|
||||||
.watch(full_assets_path.as_path(), RecursiveMode::Recursive)
|
.watch(full_assets_path.as_path(), RecursiveMode::Recursive)
|
||||||
|
@ -147,7 +149,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
for path in args.watch.iter() {
|
for path in args.watch.iter() {
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
watcher
|
watcher
|
||||||
.watch(path.as_path(), RecursiveMode::Recursive)
|
.watch(path, RecursiveMode::Recursive)
|
||||||
.expect("Failed to watch custom path");
|
.expect("Failed to watch custom path");
|
||||||
} else {
|
} else {
|
||||||
print_warning(format!(
|
print_warning(format!(
|
||||||
|
@ -157,7 +159,7 @@ pub fn watch(args: &WatchArgs) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if env::set_current_dir(args.path.as_path()).is_err() {
|
if env::set_current_dir(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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
src/util.rs
31
src/util.rs
|
@ -1,8 +1,37 @@
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
collections::HashMap,
|
||||||
|
env,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use camino::Utf8PathBuf;
|
use camino::Utf8PathBuf;
|
||||||
|
|
||||||
use inquire::{autocompletion::Replacement, Autocomplete};
|
use inquire::{autocompletion::Replacement, Autocomplete};
|
||||||
|
use path_absolutize::Absolutize;
|
||||||
|
|
||||||
|
pub fn get_project_path<P>(base_path: P) -> Option<PathBuf>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let base_path = base_path.as_ref();
|
||||||
|
if base_path.is_absolute() {
|
||||||
|
Cow::Borrowed(base_path)
|
||||||
|
} else {
|
||||||
|
base_path.absolutize().ok()?
|
||||||
|
}
|
||||||
|
.ancestors()
|
||||||
|
.find(|p| p.join("pack.toml").exists())
|
||||||
|
.map(|p| relativize(p).unwrap_or_else(|| p.to_path_buf()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn relativize<P>(path: P) -> Option<PathBuf>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let cwd = env::current_dir().ok()?;
|
||||||
|
pathdiff::diff_paths(path, cwd)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||||
pub struct PathAutocomplete {
|
pub struct PathAutocomplete {
|
||||||
|
|
Loading…
Reference in New Issue