From 40a5acc3db7911f251fe256446c3c6c3224b9025 Mon Sep 17 00:00:00 2001 From: Antonius Naumann Date: Sun, 15 Oct 2023 20:32:28 +0200 Subject: [PATCH] Use relative path for target dir --- src/lib.rs | 1 + src/metadata.rs | 17 +++++++++-------- src/path.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 src/path.rs diff --git a/src/lib.rs b/src/lib.rs index 9199b94..e4ca88e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ pub(crate) mod console { mod bindings; mod lib_type; mod metadata; +mod path; mod swiftpackage; mod targets; mod templating; diff --git a/src/metadata.rs b/src/metadata.rs index 6988950..5f1467c 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -1,7 +1,11 @@ +use std::borrow::Cow; + use camino::Utf8Path; use cargo_metadata::{Metadata, MetadataCommand, Package}; use lazy_static::lazy_static; +use crate::path::PathExt; + pub(crate) fn metadata() -> &'static Metadata { lazy_static! { static ref METADATA: Metadata = MetadataCommand::new() @@ -16,21 +20,18 @@ pub(crate) fn metadata() -> &'static Metadata { } pub(crate) trait MetadataExt { - fn target_dir(&self) -> &Utf8Path; + fn target_dir(&self) -> Cow; fn uniffi_crates(&self) -> Vec<&Package>; } impl MetadataExt for Metadata { - fn target_dir(&self) -> &Utf8Path { + fn target_dir(&self) -> Cow { let target_dir = self.target_directory.as_path(); - let relative = target_dir - // TODO: Error handling - .strip_prefix(std::env::current_dir().unwrap()) - .ok(); + let relative = target_dir.to_relative(); match relative { - Some(dir) => dir, - None => target_dir, + Ok(relative) => Cow::from(relative), + Err(_) => Cow::from(target_dir), } } diff --git a/src/path.rs b/src/path.rs new file mode 100644 index 0000000..5db3527 --- /dev/null +++ b/src/path.rs @@ -0,0 +1,49 @@ +use std::ops::Deref; + +use camino::{FromPathBufError, Utf8Path, Utf8PathBuf}; + +use crate::Result; + +pub(crate) trait PathExt { + fn to_relative(&self) -> Result; + fn find_common_path(&self, other: &Utf8Path) -> Utf8PathBuf; +} + +impl PathExt for Utf8Path { + fn to_relative(&self) -> Result { + let cwd = std::env::current_dir()?; + let cwd: Utf8PathBuf = cwd.try_into().map_err(|e: FromPathBufError| { + format!( + "Current working directory is not a valid UTF-8 path: {}", + e.into_path_buf().to_string_lossy() + ) + })?; + let common = self.find_common_path(&cwd); + let remaining = cwd.strip_prefix(common.deref()).unwrap(); + let prefix = remaining + .components() + .map(|_| "..") + .collect::(); + + let relative = prefix.join(self.strip_prefix(common).unwrap()); + + Ok(relative) + } + + fn find_common_path(&self, other: &Utf8Path) -> Utf8PathBuf { + let mut self_components = self.components(); + let mut other_components = other.components(); + let mut common_path = Utf8PathBuf::new(); + while let (Some(self_component), Some(other_component)) = + (self_components.next(), other_components.next()) + { + if self_component == other_component { + common_path.push(self_component); + } else { + break; + } + } + + common_path + } +}