diff --git a/src/builds.rs b/src/builds.rs index 9addf1c..479e2a8 100644 --- a/src/builds.rs +++ b/src/builds.rs @@ -138,7 +138,7 @@ pub async fn handle_build_push(config_path: PathBuf, verbose: bool, message: Opt let config_dir = config_path .parent() .ok_or_else(|| anyhow::anyhow!("Config file has no parent directory"))?; - let upload_dir = config_dir.join(&wavedash_config.upload_dir); + let upload_dir = crate::util::clean_path(&config_dir.join(&wavedash_config.upload_dir)); // Verify source directory exists if !upload_dir.exists() { diff --git a/src/dev/mod.rs b/src/dev/mod.rs index 47448d8..f68139a 100644 --- a/src/dev/mod.rs +++ b/src/dev/mod.rs @@ -23,6 +23,7 @@ use url::Url; use crate::auth::AuthManager; use crate::config::{self, EngineKind, WavedashConfig}; use crate::file_staging::FileStaging; +use crate::util::clean_path; mod cert; mod entrypoint; @@ -106,7 +107,7 @@ pub async fn handle_dev(config_path: Option, verbose: bool, no_open: bo let wavedash_config = WavedashConfig::load(&config_path)?; let config_dir = config_parent_dir(&config_path)?; - let upload_dir = config_dir.join(&wavedash_config.upload_dir); + let upload_dir = clean_path(&config_dir.join(&wavedash_config.upload_dir)); if !upload_dir.exists() || !upload_dir.is_dir() { anyhow::bail!( diff --git a/src/main.rs b/src/main.rs index 7de2303..39d1082 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod dev; mod file_staging; mod init; mod updater; +mod util; use anyhow::Result; use auth::{login_with_browser, AuthManager, AuthSource}; diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..264f1ee --- /dev/null +++ b/src/util.rs @@ -0,0 +1,19 @@ +use std::path::{Component, Path, PathBuf}; + +/// Collapse `.` segments so paths rendered in logs and errors don't end up +/// with leading `./` noise when `wavedash.toml`'s `upload_dir` already starts +/// with `./`. Display-only — does not touch the filesystem and does not +/// resolve `..` (paths we consume come from `config_dir.join(upload_dir)`, so +/// the `..` case is vanishingly rare and correctly passed through to the +/// filesystem calls that follow). +pub fn clean_path(p: &Path) -> PathBuf { + let cleaned: PathBuf = p + .components() + .filter(|c| !matches!(c, Component::CurDir)) + .collect(); + if cleaned.as_os_str().is_empty() { + PathBuf::from(".") + } else { + cleaned + } +}