Make export selection consistent between platforms and allow selecting which projects to export (#789)

* Experimenting with tests

* Overhaul handling of paths for pack files to always use standardized style

Also allows disabling export of all items

* Minor improvements

* Revert test things

* Minor tweaks

* Fix clippy warning
This commit is contained in:
Jackson Kruger
2023-10-09 12:34:19 -05:00
committed by GitHub
parent e76a7d57c0
commit 772597ce2a
10 changed files with 117 additions and 118 deletions

View File

@@ -383,7 +383,7 @@ pub async fn init_watcher() -> crate::Result<Debouncer<RecommendedWatcher>> {
// At this point, new_path is the path to the profile, and subfile is whether it's a subfile of the profile or not
let profile_path_id =
ProfilePathId::new(&PathBuf::from(
ProfilePathId::new(PathBuf::from(
new_path.file_name().unwrap_or_default(),
));

View File

@@ -72,8 +72,8 @@ impl ProfilePathId {
}
// Create a new ProfilePathId from a relative path
pub fn new(path: &Path) -> Self {
ProfilePathId(PathBuf::from(path))
pub fn new(path: impl Into<PathBuf>) -> Self {
ProfilePathId(path.into())
}
pub async fn get_full_path(&self) -> crate::Result<PathBuf> {
@@ -95,6 +95,45 @@ impl std::fmt::Display for ProfilePathId {
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)]
#[serde(into = "RawProjectPath", from = "RawProjectPath")]
pub struct InnerProjectPathUnix(pub String);
impl InnerProjectPathUnix {
pub fn get_topmost_two_components(&self) -> String {
self.to_string()
.split('/')
.take(2)
.collect::<Vec<_>>()
.join("/")
}
}
impl std::fmt::Display for InnerProjectPathUnix {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<RawProjectPath> for InnerProjectPathUnix {
fn from(value: RawProjectPath) -> Self {
// Convert windows path to unix path.
// .mrpacks no longer generate windows paths, but this is here for backwards compatibility before this was fixed
// https://github.com/modrinth/theseus/issues/595
InnerProjectPathUnix(value.0.replace('\\', "/"))
}
}
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
struct RawProjectPath(pub String);
impl From<InnerProjectPathUnix> for RawProjectPath {
fn from(value: InnerProjectPathUnix) -> Self {
RawProjectPath(value.0)
}
}
/// newtype wrapper over a Profile path, to be usable as a clear identifier for the kind of path used
/// eg: for "a/b/c/profiles/My Mod/mods/myproj", the ProjectPathId would be "mods/myproj"
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)]
@@ -102,11 +141,11 @@ impl std::fmt::Display for ProfilePathId {
pub struct ProjectPathId(pub PathBuf);
impl ProjectPathId {
// Create a new ProjectPathId from a full file path
pub async fn from_fs_path(path: PathBuf) -> crate::Result<Self> {
let path: PathBuf = io::canonicalize(path)?;
pub async fn from_fs_path(path: &PathBuf) -> crate::Result<Self> {
let profiles_dir: PathBuf = io::canonicalize(
State::get().await?.directories.profiles_dir().await,
)?;
let path: PathBuf = io::canonicalize(path)?;
let path = path
.strip_prefix(profiles_dir)
.ok()
@@ -131,13 +170,14 @@ impl ProjectPathId {
// Gets inner path in unix convention as a String
// ie: 'mods\myproj' -> 'mods/myproj'
// Used for exporting to mrpack, which should have a singular convention
pub fn get_inner_path_unix(&self) -> crate::Result<String> {
Ok(self
.0
.components()
.map(|c| c.as_os_str().to_string_lossy().to_string())
.collect::<Vec<_>>()
.join("/"))
pub fn get_inner_path_unix(&self) -> InnerProjectPathUnix {
InnerProjectPathUnix(
self.0
.components()
.map(|c| c.as_os_str().to_string_lossy().to_string())
.collect::<Vec<_>>()
.join("/"),
)
}
// Create a new ProjectPathId from a relative path

View File

@@ -815,7 +815,7 @@ pub async fn infer_data_from_files(
let mut corrected_hashmap = HashMap::new();
let mut stream = tokio_stream::iter(return_projects);
while let Some((h, v)) = stream.next().await {
let h = ProjectPathId::from_fs_path(h).await?;
let h = ProjectPathId::from_fs_path(&h).await?;
corrected_hashmap.insert(h, v);
}