From 1d365d9fdd36ef6c1b65d1848851f34ea69a94a4 Mon Sep 17 00:00:00 2001 From: FernTheDev <15272073+Fernthedev@users.noreply.github.com> Date: Sat, 30 Dec 2023 21:22:42 -0400 Subject: [PATCH 1/6] Unlock tag for v1.0.0 --- Cargo.lock | 34 +++++++++++++++++----------------- Cargo.toml | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18943b71..6bede915 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,9 +114,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9" +checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" [[package]] name = "async-broadcast" @@ -294,9 +294,9 @@ checksum = "e1d90cd0b264dfdd8eb5bad0a2c217c1f88fa96a8573f40e7b12de23fb468f46" [[package]] name = "async-trait" -version = "0.1.75" +version = "0.1.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" +checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ "proc-macro2", "quote", @@ -691,9 +691,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] @@ -1769,12 +1769,12 @@ dependencies = [ [[package]] name = "os_pipe" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1983,8 +1983,8 @@ dependencies = [ [[package]] name = "qpm_package" -version = "0.3.0" -source = "git+https://github.com/QuestPackageManager/QPM.Package.git#a329c9253eb67dacc1aeecda871c17b1fa7b5347" +version = "1.0.0" +source = "git+https://github.com/QuestPackageManager/QPM.Package.git#92a0646a975b1b89a988b28fc783323a8e4c2f19" dependencies = [ "cursed-semver-parser", "semver", @@ -2503,9 +2503,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597" +checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" [[package]] name = "slab" @@ -2681,18 +2681,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d" +checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3" +checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index c5c0d3da..3de1bb4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ trycmd = "0.14" [dependencies] #qpm -qpm_package = { git = "https://github.com/QuestPackageManager/QPM.Package.git", tag = "v0.3.0"} +qpm_package = { git = "https://github.com/QuestPackageManager/QPM.Package.git"} qpm_qmod = { git = "https://github.com/QuestPackageManager/QPM.Qmod.git" } qpm_arg_tokenizer = { git = "https://github.com/QuestPackageManager/QPM.arg_tokenizer.git" } templatr = { git = "https://github.com/QuestPackageManager/templatr.git", optional = true } From 8ce76131f2caffe0dd7eb3b4c705640e968be0a2 Mon Sep 17 00:00:00 2001 From: FernTheDev <15272073+Fernthedev@users.noreply.github.com> Date: Mon, 1 Jan 2024 00:29:44 -0400 Subject: [PATCH 2/6] Housekeeping and major changes: - Use QPM.Package 1.0.0 - Properly support `dynamicLibOut` and `staticLibOut` - Store `libDependencyType` in `qpm.shared.json` - Refactor qpm qmod build for more flexibility - Refactor `qpm install` to use `dynamicLibOut` and/or `staticLibOut` - Allow choosing to restore header only, static or dynamic - No longer excluding `modloader` by default - Remove debug dynamic libraries - Remove `overrideSoName` - CMake `COMPILE_ID` now uses `qpm.json` id --- Cargo.lock | 6 +- src/commands/install.rs | 79 +++---- src/commands/package/create.rs | 14 +- src/commands/package/edit_extra.rs | 27 --- src/commands/qmod/mod.rs | 31 ++- src/models/package.rs | 243 ++++++++++++-------- src/models/package_dependeny.rs | 76 ++++-- src/repository/local.rs | 357 +++++++++++++---------------- src/repository/qpackages.rs | 98 ++++---- src/resolver/dependency.rs | 18 +- src/tests/mocks/repo.rs | 3 + src/utils/cmake.rs | 8 +- src/utils/fs.rs | 4 +- 13 files changed, 488 insertions(+), 476 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bede915..d1873bec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1918,9 +1918,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "a293318316cf6478ec1ad2a21c49390a8d5b5eae9fab736467d93fbc0edc29c5" dependencies = [ "unicode-ident", ] @@ -1984,7 +1984,7 @@ dependencies = [ [[package]] name = "qpm_package" version = "1.0.0" -source = "git+https://github.com/QuestPackageManager/QPM.Package.git#92a0646a975b1b89a988b28fc783323a8e4c2f19" +source = "git+https://github.com/QuestPackageManager/QPM.Package.git#6010e21053491ad5a0e40fe192bb42cbfafe9ac5" dependencies = [ "cursed-semver-parser", "semver", diff --git a/src/commands/install.rs b/src/commands/install.rs index 1098d371..a268bec9 100644 --- a/src/commands/install.rs +++ b/src/commands/install.rs @@ -1,13 +1,11 @@ use std::path::PathBuf; use clap::Args; -use color_eyre::eyre::Context; -use qpm_package::{models::{dependency::SharedPackageConfig, package::PackageConfig}, extensions::package_metadata::PackageMetadataExtensions}; + +use qpm_package::models::{dependency::SharedPackageConfig, package::PackageConfig}; use crate::{ - models::{ - package::{PackageConfigExtensions, SharedPackageConfigExtensions} - }, + models::package::{PackageConfigExtensions, SharedPackageConfigExtensions}, repository::{local::FileRepository, multi::MultiDependencyRepository}, }; @@ -17,10 +15,6 @@ use super::Command; pub struct InstallCommand { pub binary_path: Option, pub static_path: Option, - pub debug_binary_path: Option, - - #[clap(long)] - pub cmake_build: Option, #[clap(default_value = "false", long, short)] pub locked: bool, // pub additional_folders: Vec // todo @@ -50,9 +44,22 @@ impl Command for InstallCommand { println!("Using lock file"); } - let mut binary_path = self.binary_path; - let mut static_path = self.static_path; - let mut debug_binary_path = self.debug_binary_path; + let binary_pathbuf = self.binary_path.or_else(|| { + shared_package + .config + .info + .additional_data + .dynamic_lib_out + .clone() + }); + let static_pathbuf = self.static_path.or_else(|| { + shared_package + .config + .info + .additional_data + .static_lib_out + .clone() + }); let header_only = shared_package .config @@ -62,57 +69,23 @@ impl Command for InstallCommand { .unwrap_or(false); #[cfg(debug_assertions)] println!("Header only: {header_only}"); - - if !header_only { - if binary_path.is_none() && self.cmake_build.unwrap_or(true) { - binary_path = Some( - PathBuf::from(format!( - "./build/{}", - shared_package.config.info.get_so_name().file_name().unwrap().to_string_lossy() - )) - .canonicalize().context("Failed to retrieve release binary for publishing since it is not header only")?, - ); - } - if static_path.is_none() && self.cmake_build.unwrap_or(true) { - static_path = Some( - PathBuf::from(format!( - "./build/{}", - shared_package.config.info.get_static_name().file_name().unwrap().to_string_lossy() - )) - .canonicalize().context("Failed to retrieve release binary for publishing since it is not header only")?, - ); - } - - if debug_binary_path.is_none() && self.cmake_build.unwrap_or(true) { - debug_binary_path = Some( - PathBuf::from(format!( - "./build/debug/{}", - shared_package.config.info.get_so_name().file_name().unwrap().to_string_lossy() - )) - .canonicalize().context("Failed to retrieve debug binary for publishing since it is not header only")?, - ); - } - } - if let Some(p) = &debug_binary_path { - if !p.exists() { - println!("Could not find debug binary {p:?}, skipping") - } - } - - if let Some(p) = &binary_path { + if let Some(p) = &binary_pathbuf { if !p.exists() { println!("Could not find binary {p:?}, skipping") } } let mut file_repo = FileRepository::read()?; + + let binary_path = binary_pathbuf.as_deref(); + let static_binary_path = static_pathbuf.as_deref(); + file_repo.add_artifact_and_cache( shared_package, - PathBuf::from(".").canonicalize()?, + &PathBuf::from(".").canonicalize()?, binary_path, - debug_binary_path, - static_path, + static_binary_path, true, true, )?; diff --git a/src/commands/package/create.rs b/src/commands/package/create.rs index b9ae64de..156d1c18 100644 --- a/src/commands/package/create.rs +++ b/src/commands/package/create.rs @@ -4,7 +4,7 @@ use clap::Args; use owo_colors::OwoColorize; use qpm_package::models::{ extra::AdditionalPackageMetadata, - package::{PackageConfig, PackageMetadata, self}, + package::{self, PackageConfig, PackageMetadata}, }; use semver::Version; @@ -26,18 +26,9 @@ pub struct PackageOperationCreateArgs { /// Specify that this package is headers only and does not contain a .so or .a file #[clap(long = "headersOnly")] pub headers_only: Option, - /// Specify that this package is static linking - #[clap(long = "staticLinking")] - pub static_linking: Option, /// Specify the download link for a release .so or .a file #[clap(long = "soLink")] pub so_link: Option, - /// Specify the download link for a debug .so or .a files (usually from the obj folder) - #[clap(long = "debugSoLink")] - pub debug_so_link: Option, - /// Override the downloaded .so or .a filename with this name instead. - #[clap(long = "overrideSoName")] - pub override_so_name: Option, } impl Command for PackageOperationCreateArgs { @@ -54,10 +45,7 @@ impl Command for PackageOperationCreateArgs { let additional_data = AdditionalPackageMetadata { branch_name: self.branch_name, headers_only: self.headers_only, - static_linking: self.static_linking, so_link: self.so_link, - debug_so_link: self.debug_so_link, - override_so_name: self.override_so_name, ..Default::default() }; diff --git a/src/commands/package/edit_extra.rs b/src/commands/package/edit_extra.rs index a04ae409..eb01497c 100644 --- a/src/commands/package/edit_extra.rs +++ b/src/commands/package/edit_extra.rs @@ -93,26 +93,14 @@ impl Command for EditExtraArgs { package_edit_extra_headers_only(&mut package, headers_only.into()); any_changed = true; } - if let Some(static_linking) = self.static_linking { - package_edit_extra_static_linking(&mut package, static_linking.into()); - any_changed = true; - } if let Some(so_link) = self.so_link { package_edit_extra_so_link(&mut package, so_link); any_changed = true; } - if let Some(debug_so_link) = self.debug_so_link { - package_edit_extra_debug_so_link(&mut package, debug_so_link); - any_changed = true; - } if let Some(mod_link) = self.mod_link { package_edit_extra_mod_link(&mut package, mod_link); any_changed = true; } - if let Some(override_so_name) = self.override_so_name { - package_edit_extra_override_so_name(&mut package, override_so_name); - any_changed = true; - } if let Some(sub_folder) = self.sub_folder { package_edit_extra_sub_folder(&mut package, sub_folder); any_changed = true; @@ -145,11 +133,6 @@ pub fn package_edit_extra_headers_only(package: &mut PackageConfig, headers_only package.info.additional_data.headers_only = Some(headers_only); } -pub fn package_edit_extra_static_linking(package: &mut PackageConfig, static_linking: bool) { - println!("Setting static_linking: {static_linking:#?}"); - package.info.additional_data.static_linking = Some(static_linking); -} - pub fn package_edit_extra_so_link(package: &mut PackageConfig, so_link: String) { println!("Setting so_link: {so_link:#?}"); package.info.additional_data.so_link = Some(so_link); @@ -160,16 +143,6 @@ pub fn package_edit_extra_mod_link(package: &mut PackageConfig, mod_link: String package.info.additional_data.mod_link = Some(mod_link); } -pub fn package_edit_extra_debug_so_link(package: &mut PackageConfig, debug_so_link: String) { - println!("Setting debug_so_link: {debug_so_link:#?}"); - package.info.additional_data.debug_so_link = Some(debug_so_link); -} - -pub fn package_edit_extra_override_so_name(package: &mut PackageConfig, override_so_name: String) { - println!("Setting override_so_name: {override_so_name:#?}"); - package.info.additional_data.override_so_name = Some(override_so_name); -} - pub fn package_edit_extra_sub_folder(package: &mut PackageConfig, sub_folder: String) { println!("Setting sub_folder: {sub_folder:#?}"); package.info.additional_data.sub_folder = Some(sub_folder); diff --git a/src/commands/qmod/mod.rs b/src/commands/qmod/mod.rs index b4b825ec..5fc8754f 100644 --- a/src/commands/qmod/mod.rs +++ b/src/commands/qmod/mod.rs @@ -1,16 +1,10 @@ -use std::{ - collections::{HashMap, HashSet}, - path::PathBuf, -}; +use std::path::PathBuf; use clap::{Args, Subcommand}; use color_eyre::{eyre::ensure, Result}; -use itertools::Itertools; -use qpm_package::{ - extensions::package_metadata::PackageMetadataExtensions, - models::{dependency::SharedPackageConfig, package::PackageConfig}, -}; -use qpm_qmod::models::mod_json::{ModDependency, ModJson}; + +use qpm_package::models::{dependency::SharedPackageConfig, package::PackageConfig}; +use qpm_qmod::models::mod_json::ModJson; use semver::{Version, VersionReq}; use crate::models::{ @@ -153,10 +147,23 @@ fn execute_qmod_build_operation(build_parameters: BuildQmodOperationArgs) -> Res .headers_only .unwrap_or(false); let binary = (!is_header_only).then(|| { - shared_package + let dynamic_lib = shared_package .config .info - .get_so_name() + .additional_data + .dynamic_lib_out + .as_ref(); + + let static_lib = shared_package + .config + .info + .additional_data + .static_lib_out + .as_ref(); + + dynamic_lib + .or(static_lib) + .expect("No static or binary lib out path defined") .file_name() .unwrap() .to_str() diff --git a/src/models/package.rs b/src/models/package.rs index a82ced42..5f71ae84 100644 --- a/src/models/package.rs +++ b/src/models/package.rs @@ -1,24 +1,23 @@ -use std::{collections::HashSet, fs::File, io::BufReader, path::Path}; +use std::{fs::File, io::BufReader, path::Path}; use color_eyre::{ - eyre::{bail, Context}, + eyre::{anyhow, bail, Context}, Result, }; use itertools::Itertools; -use qpm_package::{ - extensions::package_metadata::PackageMetadataExtensions, - models::{ - dependency::{Dependency, SharedDependency, SharedPackageConfig}, - extra::CompileOptions, - package::PackageConfig, - }, +use qpm_package::models::{ + dependency::{Dependency, SharedDependency, SharedPackageConfig}, + extra::DependencyLibType, + package::PackageConfig, }; use qpm_qmod::models::mod_json::{ModDependency, ModJson}; use semver::VersionReq; -use crate::{repository::Repository, resolver::dependency::resolve, utils::json}; +use crate::{ + repository::Repository, resolver::dependency::resolve, terminal::colors::QPMColor, utils::json, +}; -use super::toolchain; +use super::{package_dependeny::PackageDependencyExtensions, toolchain}; pub const PACKAGE_FILE_NAME: &str = "qpm.json"; pub const SHARED_PACKAGE_FILE_NAME: &str = "qpm.shared.json"; @@ -37,6 +36,9 @@ pub trait PackageConfigExtensions { fn matches_version(&self, req: &VersionReq) -> bool; fn validate(&self) -> color_eyre::Result<()>; + + fn get_static_lib_out(&self) -> Result<&Path>; + fn get_dynamic_lib_out(&self) -> Result<&Path>; } pub trait SharedPackageConfigExtensions: Sized { fn resolve_from_package( @@ -99,8 +101,56 @@ impl PackageConfigExtensions for PackageConfig { ); } + let headers_only = self + .info + .additional_data + .headers_only + .unwrap_or(false); + let dynamic_lib_out = &self.info.additional_data.dynamic_lib_out; + let static_lib_out = &self.info.additional_data.static_lib_out; + + if !headers_only && (dynamic_lib_out.is_none() || static_lib_out.is_none()) { + bail!( + "{} nor {} are defined!", + "qpm.shared.json::config::info::additionalData::dynamicLibOut".file_path_color(), + "qpm.shared.json::config::info::additionalData::staticLibOut".file_path_color() + ); + } + Ok(()) } + + fn get_static_lib_out(&self) -> Result<&Path> { + let path = self + .info + .additional_data + .static_lib_out + .as_ref() + .ok_or_else(|| { + anyhow!( + "{} qpm.shared.json::info::additionalData::staticLibOut not defined", + self.info.id.dependency_id_color() + ) + })?; + + Ok(path) + } + + fn get_dynamic_lib_out(&self) -> Result<&Path> { + let path = self + .info + .additional_data + .dynamic_lib_out + .as_ref() + .ok_or_else(|| { + anyhow!( + "{} qpm.shared.json::info::additionalData::dynamicLibOut not defined", + self.info.id.dependency_id_color() + ) + })?; + + Ok(path) + } } impl PackageConfigExtensions for SharedPackageConfig { fn read>(dir: P) -> Result { @@ -137,6 +187,14 @@ impl PackageConfigExtensions for SharedPackageConfig { fn validate(&self) -> color_eyre::Result<()> { self.config.validate() } + + fn get_static_lib_out(&self) -> Result<&Path> { + self.config.get_static_lib_out() + } + + fn get_dynamic_lib_out(&self) -> Result<&Path> { + self.config.get_dynamic_lib_out() + } } impl SharedPackageConfigExtensions for SharedPackageConfig { @@ -146,24 +204,47 @@ impl SharedPackageConfigExtensions for SharedPackageConfig { ) -> Result<(Self, Vec)> { let resolved_deps = resolve(&config, repository)?.collect_vec(); + let restored_dependencies = resolved_deps + .iter() + .map(|shared_dep_config| { + let declared_dep = config + .dependencies + .iter() + .find(|declared_dep| declared_dep.id == shared_dep_config.config.info.id); + + (shared_dep_config, declared_dep) + }) + .map(|(shared_dep_config, declared_dep)| { + let restored_lib_type = match declared_dep { + // infer the lib type + // if explicitly set, will use that + Some(declared_dep) => { + declared_dep.infer_lib_type(&shared_dep_config.config.info.additional_data) + } + + // if not declared directly, just restore as header only + None => DependencyLibType::HeaderOnly, + }; + SharedDependency { + dependency: Dependency { + id: shared_dep_config.config.info.id.clone(), + version_range: VersionReq::parse(&format!( + "={}", + shared_dep_config.config.info.version + )) + .expect("Unable to parse version"), + additional_data: shared_dep_config.config.info.additional_data.clone(), + }, + version: shared_dep_config.config.info.version.clone(), + restored_lib_type, + } + }) + .collect(); + Ok(( SharedPackageConfig { config, - restored_dependencies: resolved_deps - .iter() - .map(|d| SharedDependency { - dependency: Dependency { - id: d.config.info.id.clone(), - version_range: VersionReq::parse(&format!( - "={}", - d.config.info.version - )) - .expect("Unable to parse version"), - additional_data: d.config.info.additional_data.clone(), - }, - version: d.config.info.version.clone(), - }) - .collect(), + restored_dependencies, }, resolved_deps, )) @@ -179,95 +260,60 @@ impl SharedPackageConfigExtensions for SharedPackageConfig { let local_deps = &self.config.dependencies; // Only bundle mods that are not specifically excluded in qpm.json or if they're not header-only - let restored_deps: Vec<_> = self + let required_deps: Vec<_> = self .restored_dependencies .iter() - .filter(|dep| { + .filter(|shared_dep| { + // find the actual dependency for the include qmod value let local_dep_opt = local_deps .iter() - .find(|local_dep| local_dep.id == dep.dependency.id); + .find(|local_dep| local_dep.id == shared_dep.dependency.id); - if let Some(local_dep) = local_dep_opt { - // if force included/excluded, return early - if let Some(force_included) = local_dep.additional_data.include_qmod { - return force_included; - } - } + // if set, we will include qmod + let include_qmod = + local_dep_opt.and_then(|local_dep| local_dep.additional_data.include_qmod); - // or if header only is false - dep.dependency.additional_data.mod_link.is_some() - || !dep.dependency.additional_data.headers_only.unwrap_or(false) - }) - .collect(); + // don't include static deps or header only + shared_dep.restored_lib_type == DependencyLibType::Shared && - // List of dependencies we are directly referencing in qpm.json - let direct_dependencies: HashSet = self - .config - .dependencies - .iter() - .map(|f| f.id.clone()) + // it's marked to be included, defaults to including ( same as dependencies with qmods ) + include_qmod.unwrap_or(true) + }) .collect(); // downloadable mods links n stuff // mods that are header-only but provide qmods can be added as deps - // Must be directly referenced in qpm.json - let mods: Vec = local_deps + let mod_dependencies: Vec = required_deps .iter() // Removes any dependency without a qmod link - .filter_map(|dep| { - let shared_dep = restored_deps.iter().find(|d| d.dependency.id == dep.id)?; - if shared_dep.dependency.additional_data.mod_link.is_some() { - return Some((shared_dep, dep)); - } - - None - }) - .map(|(shared_dep, dep)| ModDependency { - version_range: dep.version_range.clone(), - id: dep.id.clone(), + .filter(|&shared_dep| shared_dep.dependency.additional_data.mod_link.is_some()) + .map(|shared_dep| ModDependency { + version_range: shared_dep.dependency.version_range.clone(), + id: shared_dep.dependency.id.clone(), mod_link: shared_dep.dependency.additional_data.mod_link.clone(), }) .collect(); // The rest of the mods to handle are not qmods, they are .so or .a mods // actual direct lib deps - let libs: Vec = self - .restored_dependencies + let libs: Vec = required_deps .iter() - // We could just query the bmbf core mods list on GH? - // https://github.com/BMBF/resources/blob/master/com.beatgames.beatsaber/core-mods.json - // but really the only lib that never is copied over is the modloader, the rest is either a downloaded qmod or just a copied lib - // even core mods should technically be added via download - .filter(|lib| { - // find the actual dependency for the include qmod value - let local_dep_opt = local_deps - .iter() - .find(|local_dep| local_dep.id == lib.dependency.id); - - // if set, use it later - - let include_qmod = local_dep_opt - .and_then(|local_dep| local_dep.additional_data.include_qmod.as_ref()); - - // Must be directly referenced in qpm.json - direct_dependencies.contains(&lib.dependency.id) && - - // keep if header only is false, or if not defined - !lib.dependency.additional_data.headers_only.unwrap_or(false) && - - // Modloader should never be included - lib.dependency.id != "modloader" && - - // don't include static deps - !lib.dependency.additional_data.static_linking.unwrap_or(false) && - - // it's marked to be included, defaults to including ( same as dependencies with qmods ) - include_qmod.copied().unwrap_or(true) && - - // Only keep libs that aren't downloadable - !mods.iter().any(|dep| lib.dependency.id == dep.id) + // look for mods with no qmods + .filter(|dep| dep.dependency.additional_data.mod_link.is_none()) + .map(|dep| { + dep.dependency + .additional_data + .dynamic_lib_out + .as_ref() + .unwrap_or_else(|| { + panic!( + "Dependency {} does not define dynamic lib out", + dep.dependency.id.dependency_id_color() + ) + }) }) - .map(|dep| dep.get_so_name().to_str().unwrap().to_string()) + // get file name of dep + .map(|path| path.file_name().unwrap().to_str().unwrap().to_string()) .collect(); ModJson { @@ -280,19 +326,14 @@ impl SharedPackageConfigExtensions for SharedPackageConfig { description: None, cover_image: None, is_library: None, - dependencies: mods, - // TODO: Change - late_mod_files: vec![self.config.info.get_so_name().to_str().unwrap().to_string()], + dependencies: mod_dependencies, library_files: libs, ..Default::default() } } + /// check if shared json is valid for publishing fn verify(&self) -> color_eyre::Result<()> { - if self.config.info.additional_data.static_linking.is_some() { - bail!("Using deprecated feature static_linking! Please remove!"); - } - Ok(()) } diff --git a/src/models/package_dependeny.rs b/src/models/package_dependeny.rs index 5c679eb6..179fb851 100644 --- a/src/models/package_dependeny.rs +++ b/src/models/package_dependeny.rs @@ -1,26 +1,29 @@ +use std::path::Path; + +use color_eyre::eyre::{anyhow, Result}; use qpm_package::models::{ - dependency::{Dependency, SharedDependency}, - extra::DependencyLibType, - package::{PackageConfig, PackageDependency}, + dependency::Dependency, + extra::{AdditionalPackageMetadata, DependencyLibType}, + package::PackageDependency, }; +use crate::terminal::colors::QPMColor; + pub trait PackageDependencyExtensions { - fn infer_lib_type(&self, package: &PackageConfig) -> DependencyLibType; + fn infer_lib_type(&self, additional_data: &AdditionalPackageMetadata) -> DependencyLibType; - fn use_as_header_only(&self, package: &PackageConfig) -> bool; - fn use_as_static(&self, package: &PackageConfig) -> bool; - fn use_as_shared(&self, package: &PackageConfig) -> bool; + fn usable_as_header_only(&self, additional_data: &AdditionalPackageMetadata) -> bool; + fn usable_as_static(&self, additional_data: &AdditionalPackageMetadata) -> bool; + fn usable_as_shared(&self, additional_data: &AdditionalPackageMetadata) -> bool; } impl PackageDependencyExtensions for PackageDependency { - fn infer_lib_type(&self, package: &PackageConfig) -> DependencyLibType { + fn infer_lib_type(&self, additional_data: &AdditionalPackageMetadata) -> DependencyLibType { let data = self.additional_data.clone(); - let inferred = if package.info.additional_data.static_linking.is_some() - || package.info.additional_data.static_link.is_some() - { + let inferred = if additional_data.static_link.is_some() { DependencyLibType::Static - } else if package.info.additional_data.headers_only == Some(true) { + } else if additional_data.headers_only == Some(true) { DependencyLibType::HeaderOnly } else { DependencyLibType::Shared @@ -29,15 +32,52 @@ impl PackageDependencyExtensions for PackageDependency { data.lib_type.unwrap_or(inferred) } - fn use_as_header_only(&self, package: &PackageConfig) -> bool { - self.infer_lib_type(package) == DependencyLibType::HeaderOnly + fn usable_as_header_only(&self, additional_data: &AdditionalPackageMetadata) -> bool { + self.infer_lib_type(additional_data) == DependencyLibType::HeaderOnly + } + + fn usable_as_static(&self, additional_data: &AdditionalPackageMetadata) -> bool { + self.infer_lib_type(additional_data) == DependencyLibType::Static } - fn use_as_static(&self, package: &PackageConfig) -> bool { - self.infer_lib_type(package) == DependencyLibType::Static + fn usable_as_shared(&self, additional_data: &AdditionalPackageMetadata) -> bool { + self.infer_lib_type(additional_data) == DependencyLibType::Shared } +} + +pub trait DependencyExtensions { + fn get_static_lib_out(&self) -> Result<&Path>; + fn get_dynamic_lib_out(&self) -> Result<&Path>; +} + +impl DependencyExtensions for Dependency { + fn get_static_lib_out(&self) -> Result<&Path> { + let path = self + .additional_data + .static_lib_out + .as_ref() + .ok_or_else(|| { + anyhow!( + "{} qpm.shared.json::info::additionalData::staticLibOut not defined", + self.id.dependency_id_color() + ) + })?; + + Ok(path) + } + + fn get_dynamic_lib_out(&self) -> Result<&Path> { + let path = self + .additional_data + .dynamic_lib_out + .as_ref() + .ok_or_else(|| { + anyhow!( + "{} qpm.shared.json::info::additionalData::dynamicLibOut not defined", + self.id.dependency_id_color() + ) + })?; - fn use_as_shared(&self, package: &PackageConfig) -> bool { - self.infer_lib_type(package) == DependencyLibType::Shared + Ok(path) } } diff --git a/src/repository/local.rs b/src/repository/local.rs index a7bc5a5b..107886a5 100644 --- a/src/repository/local.rs +++ b/src/repository/local.rs @@ -13,23 +13,21 @@ use std::{ path::{Path, PathBuf}, }; -use qpm_package::{ - extensions::package_metadata::PackageMetadataExtensions, - models::{ - backend::PackageVersion, dependency::SharedPackageConfig, extra::DependencyLibType, - package::PackageConfig, - }, +use qpm_package::models::{ + backend::PackageVersion, + dependency::{SharedDependency, SharedPackageConfig}, + extra::DependencyLibType, + package::PackageConfig, }; use crate::{ - models::{ - config::get_combine_config, package::PackageConfigExtensions, - package_dependeny::PackageDependencyExtensions, - }, + models::{config::get_combine_config, package::PackageConfigExtensions}, + terminal::colors::QPMColor, utils::{fs::copy_things, json}, }; use super::Repository; +use crate::models::package_dependeny::DependencyExtensions; // TODO: Somehow make a global singleton of sorts/cached instance to share across places // like resolver @@ -87,10 +85,9 @@ impl FileRepository { pub fn add_artifact_and_cache( &mut self, package: SharedPackageConfig, - project_folder: PathBuf, - binary_path: Option, - debug_binary_path: Option, - static_binary_path: Option, + project_folder: &Path, + binary_path: Option<&Path>, + static_binary_path: Option<&Path>, copy: bool, overwrite_existing: bool, ) -> Result<()> { @@ -99,7 +96,6 @@ impl FileRepository { &package, project_folder, binary_path, - debug_binary_path, static_binary_path, false, )?; @@ -110,25 +106,24 @@ impl FileRepository { } fn copy_to_cache( - package: &SharedPackageConfig, - project_folder: PathBuf, - binary_path: Option, - debug_binary_path: Option, - static_binary_path: Option, + shared_package: &SharedPackageConfig, + project_folder: &Path, + binary_path: Option<&Path>, + static_binary_path: Option<&Path>, validate: bool, ) -> Result<()> { println!( "Adding cache for local dependency {} {}", - package.config.info.id.bright_red(), - package.config.info.version.bright_green() + shared_package.config.info.id.bright_red(), + shared_package.config.info.version.bright_green() ); let config = get_combine_config(); let cache_path = config .cache .as_ref() .unwrap() - .join(&package.config.info.id) - .join(package.config.info.version.to_string()); + .join(&shared_package.config.info.id) + .join(shared_package.config.info.version.to_string()); let tmp_path = cache_path.join("tmp"); let src_path = cache_path.join("src"); @@ -139,38 +134,26 @@ impl FileRepository { fs::create_dir_all(&src_path).context("Failed to create lib path")?; - if binary_path.is_some() || debug_binary_path.is_some() || static_binary_path.is_some() { - let lib_path = cache_path.join("lib"); - let so_path = lib_path.join(package.config.info.get_so_name()); - let static_path = lib_path.join(package.config.info.get_static_name()); - let debug_so_path = lib_path.join(format!( - "debug_{}", - package - .config - .info - .get_so_name() - .file_name() - .unwrap() - .to_string_lossy() - )); - - if let Some(binary_path_unwrapped) = &binary_path { - copy_things(binary_path_unwrapped, &so_path)?; - } + let lib_path = cache_path.join("lib"); - if let Some(debug_binary_path_unwrapped) = &debug_binary_path { - copy_things(debug_binary_path_unwrapped, &debug_so_path)?; - } - if let Some(static_binary_path_unwrapped) = &static_binary_path { - copy_things(static_binary_path_unwrapped, &static_path)?; - } + if let Some(binary_path_unwrapped) = &binary_path { + let dynamic_out_name = shared_package.get_dynamic_lib_out()?.file_name().unwrap(); + let so_path = lib_path.join(dynamic_out_name); + + copy_things(binary_path_unwrapped, &so_path)?; } - let original_shared_path = project_folder.join(&package.config.shared_dir); + if let Some(static_binary_path_unwrapped) = &static_binary_path { + let static_out_name = shared_package.get_static_lib_out()?.file_name().unwrap(); + let static_out_path = lib_path.join(static_out_name); + copy_things(static_binary_path_unwrapped, &static_out_path)?; + } + + let original_shared_path = project_folder.join(&shared_package.config.shared_dir); copy_things( &original_shared_path, - &src_path.join(&package.config.shared_dir), + &src_path.join(&shared_package.config.shared_dir), )?; copy_things(&project_folder.join("qpm.json"), &src_path.join("qpm.json"))?; copy_things( @@ -188,17 +171,22 @@ impl FileRepository { let downloaded_package = SharedPackageConfig::read(package_path)?; // check if downloaded config is the same version as expected, if not, panic - if downloaded_package.config.info.version != package.config.info.version { + if downloaded_package.config.info.version != shared_package.config.info.version { bail!( "Downloaded package ({}) version ({}) does not match expected version ({})!", - package.config.info.id.bright_red(), + shared_package.config.info.id.bright_red(), downloaded_package .config .info .version .to_string() .bright_green(), - package.config.info.version.to_string().bright_green(), + shared_package + .config + .info + .version + .to_string() + .bright_green(), ) } } @@ -246,11 +234,11 @@ impl FileRepository { } pub fn copy_from_cache( - package: &PackageConfig, + shared_package: &SharedPackageConfig, restored_deps: &[SharedPackageConfig], workspace_dir: &Path, ) -> Result<()> { - let files = Self::collect_deps(package, restored_deps, workspace_dir)?; + let files = Self::collect_deps(shared_package, restored_deps, workspace_dir)?; let config = get_combine_config(); let symlink = config.symlink.unwrap_or(true); @@ -307,15 +295,20 @@ impl FileRepository { } pub fn collect_deps( - package: &PackageConfig, + shared_package: &SharedPackageConfig, restored_deps: &[SharedPackageConfig], workspace_dir: &Path, ) -> Result> { - // let package = shared_package.config; + let package = &shared_package.config; let restored_dependencies_map: HashMap<&String, &SharedPackageConfig> = restored_deps .iter() .map(|p| (&p.config.info.id, p)) .collect(); + let locked_dependencies_map: HashMap<&String, &SharedDependency> = shared_package + .restored_dependencies + .iter() + .map(|p| (&p.dependency.id, p)) + .collect(); let user_config = get_combine_config(); let base_path = user_config.cache.as_ref().unwrap(); @@ -338,160 +331,136 @@ impl FileRepository { let extern_dir = workspace_dir.join(&package.dependencies_dir); - // delete if needed - if extern_dir.exists() { - fs::remove_dir_all(&extern_dir) - .with_context(|| format!("Unable to delete {extern_dir:?}"))?; - } - let extern_binaries = extern_dir.join("libs"); let extern_headers = extern_dir.join("includes"); - let mut paths = HashMap::::new(); - - // direct deps (binaries) - for referenced_dep in &package.dependencies { - let shared_dep = restored_dependencies_map.get(&referenced_dep.id).unwrap(); - let dep_cache_path = base_path - .join(&referenced_dep.id) - .join(shared_dep.config.info.version.to_string()); - let libs_path = dep_cache_path.join("lib"); - - let lib_type_opt = referenced_dep.infer_lib_type(&shared_dep.config); - - // skip header only deps - if shared_dep - .config - .info - .additional_data - .headers_only - .unwrap_or(false) - // if dependency is requested as header only - || lib_type_opt == DependencyLibType::HeaderOnly - { - if referenced_dep - .additional_data - .lib_type - .as_ref() - .is_some_and(|t| *t != DependencyLibType::HeaderOnly) - { - eprintln!( - "Header only library {} is requested as {:?}", - shared_dep.config.info.id, lib_type_opt - ); - } - continue; - } - // Not header only - let data = &shared_dep.config.info.additional_data; - - let name = match lib_type_opt { - // if has so link and is not using static_link - // use so name - DependencyLibType::Shared - if (data.debug_so_link.is_some() || data.so_link.is_some()) => - { - match data.debug_so_link.is_none() { - true => shared_dep.config.info.get_so_name(), - false => format!( - "debug_{}", - shared_dep - .config - .info - .get_so_name() - .file_name() - .unwrap() - .to_string_lossy() + let headers = locked_dependencies_map.iter().map( + |(dep_id, shared_dep)| -> Result<(PathBuf, PathBuf)> { + let shared_dep_config = + restored_dependencies_map.get(dep_id).unwrap_or_else(|| { + panic!( + "No shared config in resolved_deps for dependency {}:{}", + dep_id.dependency_id_color(), + shared_dep.version.dependency_version_color() ) - .into(), - } - } - // if dependency is static and has static_linking - DependencyLibType::Static - if data.static_linking.unwrap_or(false) && data.so_link.is_some() => - { - shared_dep.config.info.get_so_name().with_extension("a") - } - DependencyLibType::Static if data.static_link.is_some() => { - shared_dep.config.info.get_static_name() + }); + + let dep_cache_path = base_path + .join(dep_id) + .join(shared_dep_config.config.info.version.to_string()); + + let src_path = dep_cache_path.join("src"); + + if !src_path.exists() { + bail!( + "Missing src for dependency {}:{}", + dep_id, + shared_dep_config.config.info.version.to_string() + ); } - _ => bail!( - "Attempting to use dependency as {lib_type_opt:?} but failed. Info: {data:?}" - ), - }; - let src_binary = libs_path.join(&name); + let exposed_headers = src_path.join(&shared_dep_config.config.shared_dir); + let project_deps_headers_target = extern_headers.join(dep_id); - if !src_binary.exists() { - bail!( - "Missing binary {} for {}:{}", - name.file_name().unwrap().to_string_lossy(), - referenced_dep.id, - shared_dep.config.info.version + let path = ( + exposed_headers, + project_deps_headers_target.join(&shared_dep_config.config.shared_dir), ); - } - paths.insert( - src_binary, - extern_binaries.join(name.file_name().unwrap().to_str()), - ); - } + Ok(path) + }, + ); - // Get headers of all dependencies restored - for (restored_id, restored_dep) in &restored_dependencies_map { - let dep_cache_path = base_path - .join(restored_id) - .join(restored_dep.config.info.version.to_string()); - let src_path = dep_cache_path.join("src"); + let binaries = locked_dependencies_map + .iter() + .filter(|(_dep_id, shared_dep)| shared_dep.restored_lib_type != DependencyLibType::HeaderOnly) + .map(|(dep_id, shared_dep)| -> Result<(PathBuf, PathBuf)> { + let data = &shared_dep.dependency.additional_data; + + let dep_cache_path = base_path + .join(dep_id) + .join(shared_dep.version.to_string()); + let libs_path = dep_cache_path.join("lib"); + + let src_path = dep_cache_path.join("src"); + + if !src_path.exists() { + bail!( + "Missing src for dependency {}:{}", + dep_id, + shared_dep.version.to_string() + ); + } - if !src_path.exists() { - bail!( - "Missing src for dependency {}:{}", - restored_id, - restored_dep.config.info.version.to_string() - ); - } + let dependency_lib_type = shared_dep.restored_lib_type.clone(); + let name = match dependency_lib_type { + // if has so link and is not using static_link + // use so name + DependencyLibType::Shared if data.so_link.is_some() => { + shared_dep.dependency.get_dynamic_lib_out()? + } + DependencyLibType::Static if data.static_link.is_some() => { + shared_dep.dependency.get_static_lib_out()? + } + _ => bail!("Attempting to use dependency as {dependency_lib_type:?} but failed. Info: {data:?}"), + }; - let exposed_headers = src_path.join(&restored_dep.config.shared_dir); - let project_deps_headers_target = extern_headers.join(restored_id); + let src_binary = libs_path.join(name); - paths.insert( - exposed_headers, - project_deps_headers_target.join(&restored_dep.config.shared_dir), - ); - } + if !src_binary.exists() { + bail!( + "Missing binary {} for {}:{}", + name.file_name().unwrap().to_string_lossy(), + dep_id, + shared_dep.version + ); + } + let dst_binary = + extern_binaries.join(name.file_name().unwrap().to_str().unwrap()); + + let path = (src_binary, dst_binary); + Ok(path) + }); // extra files - // while this is looped twice, generally I'd assume the compiler to properly - // optimize this and it's better readability - for referenced_dependency in &package.dependencies { - let shared_dep = restored_dependencies_map - .get(&referenced_dependency.id) - .unwrap(); - - let dep_cache_path = base_path - .join(&referenced_dependency.id) - .join(shared_dep.config.info.version.to_string()); - let src_path = dep_cache_path.join("src"); - - let extern_headers_dep = extern_headers.join(&referenced_dependency.id); - - if let Some(extras) = &referenced_dependency.additional_data.extra_files { - for extra in extras { - let extra_src = src_path.join(extra); - - if !extra_src.exists() { - bail!( - "Missing extra {extra} for dependency {}:{}", - referenced_dependency.id, - shared_dep.config.info.version.to_string() - ); + let extra_files = package + .dependencies + .iter() + .map(|referenced_dependency| { + let shared_dep = restored_dependencies_map + .get(&referenced_dependency.id) + .unwrap(); + + let dep_cache_path = base_path + .join(&referenced_dependency.id) + .join(shared_dep.config.info.version.to_string()); + let src_path = dep_cache_path.join("src"); + + let mut paths: Vec<(PathBuf, PathBuf)> = vec![]; + + let extern_headers_dep = extern_headers.join(&referenced_dependency.id); + if let Some(extras) = &referenced_dependency.additional_data.extra_files { + for extra in extras { + let extra_src = src_path.join(extra); + + if !extra_src.exists() { + bail!( + "Missing extra {extra} for dependency {}:{}", + referenced_dependency.id, + shared_dep.config.info.version.to_string() + ); + } + + paths.push((extra_src, extern_headers_dep.join(extra))); } - - paths.insert(extra_src, extern_headers_dep.join(extra)); } - } - } + + Ok(paths) + }) + .flatten_ok(); + + let mut paths: HashMap = + headers.chain(binaries).chain(extra_files).try_collect()?; paths.retain(|src, _| src.exists()); diff --git a/src/repository/qpackages.rs b/src/repository/qpackages.rs index dd5f0e97..45ffc03a 100644 --- a/src/repository/qpackages.rs +++ b/src/repository/qpackages.rs @@ -1,5 +1,5 @@ use color_eyre::{ - eyre::{bail, Context}, + eyre::{anyhow, bail, Context}, Result, }; use itertools::Itertools; @@ -17,14 +17,12 @@ use zip::ZipArchive; use serde::Deserialize; -use qpm_package::{models::{ +use qpm_package::models::{ backend::PackageVersion, dependency::SharedPackageConfig, package::PackageConfig, -}, extensions::package_metadata::PackageMetadataExtensions}; +}; use crate::{ - models::{ - config::get_combine_config, package::PackageConfigExtensions, - }, + models::{config::get_combine_config, package::PackageConfigExtensions}, network::agent::{download_file_report, get_agent}, terminal::colors::QPMColor, utils::git, @@ -137,10 +135,6 @@ impl QPMRepository { return Ok(()); } - let so_path = lib_path.join(config.info.get_so_name()); - let static_path = lib_path.join(config.info.get_static_name()); - let debug_so_path = lib_path.join(format!("debug_{}", config.info.get_so_name().file_name().unwrap().to_string_lossy())); - // Downloads the repo / zip file into src folder w/ subfolder taken into account if !src_path.exists() { // if the tmp path exists, but src doesn't, that's a failed cache, delete it and try again! @@ -248,46 +242,62 @@ impl QPMRepository { if !lib_path.exists() { fs::create_dir_all(&lib_path).context("Failed to create lib path")?; // libs didn't exist or the release object didn't exist, we need to download from packageconfig.info.additional_data.so_link and packageconfig.info.additional_data.debug_so_link - let download_binary = |path: &Path, url_opt: Option<&String>| -> Result<_> { - if !path.exists() || File::open(path).is_err() { - if let Some(url) = url_opt { - println!( - "Downloading {} from {} to {}", - path.file_name() - .unwrap() - .to_string_lossy() - .download_file_name_color(), - url_opt.unwrap().version_id_color(), - path.as_os_str() - .to_string_lossy() - .alternate_dependency_version_color() - ); - // so_link existed, download - if url.contains("github.com") { - // github url! - git::get_release(url, path)?; - } else { - let bytes = download_file_report(url, |_, _| {})?; - - let mut file = File::create(path)?; - - file.write_all(&bytes) - .context("Failed to write out downloaded bytes")?; - } - } + let download_binary = |path: &Path, url_opt: Option<&String>| -> Result<()> { + if path.exists() { + return Ok(()); } + + let Some(url) = url_opt else { + return Err(anyhow!( + "No url defined for download to {}", + path.display().file_path_color() + )); + }; + + println!( + "Downloading {} from {} to {}", + path.file_name() + .unwrap() + .to_string_lossy() + .download_file_name_color(), + url_opt.unwrap().version_id_color(), + path.as_os_str() + .to_string_lossy() + .alternate_dependency_version_color() + ); + // so_link existed, download + if url.contains("github.com") { + // github url! + git::get_release(url, path)?; + } else { + let bytes = download_file_report(url, |_, _| {})?; + + let mut file = File::create(path)?; + + file.write_all(&bytes) + .context("Failed to write out downloaded bytes")?; + } + Ok(()) }; - download_binary(&static_path, config.info.additional_data.static_link.as_ref())?; - download_binary(&so_path, config.info.additional_data.so_link.as_ref())?; - download_binary( - &debug_so_path, - config.info.additional_data.debug_so_link.as_ref(), - )?; + // dynamic + if let Some(dynamic_lib_out) = &config.info.additional_data.dynamic_lib_out { + let so_path = lib_path.join(dynamic_lib_out.file_name().unwrap().to_str().unwrap()); + download_binary(&so_path, config.info.additional_data.so_link.as_ref())?; + } + + // static + if let Some(static_lib_out) = &config.info.additional_data.static_lib_out { + let static_path = + lib_path.join(static_lib_out.file_name().unwrap().to_str().unwrap()); + download_binary( + &static_path, + config.info.additional_data.static_link.as_ref(), + )?; + } } if config.info.additional_data.so_link.is_none() - && config.info.additional_data.debug_so_link.is_none() && config.info.additional_data.static_link.is_none() && !config.info.additional_data.headers_only.unwrap_or(false) { diff --git a/src/resolver/dependency.rs b/src/resolver/dependency.rs index 6efacbfc..8be19d37 100644 --- a/src/resolver/dependency.rs +++ b/src/resolver/dependency.rs @@ -1,9 +1,10 @@ -use std::{borrow::Borrow, error::Error, path::Path, vec::IntoIter}; +use std::{borrow::Borrow, error::Error, fs, path::Path, vec::IntoIter}; use crate::{ + models::package::SharedPackageConfigExtensions, repository::{local::FileRepository, Repository}, terminal::colors::QPMColor, - utils::cmake::write_cmake, models::package::SharedPackageConfigExtensions, + utils::cmake::write_cmake, }; use color_eyre::{ eyre::{bail, Context}, @@ -161,7 +162,18 @@ pub fn restore>( repository.write_repo()?; println!("Copying now"); - FileRepository::copy_from_cache(&shared_package.config, resolved_deps, workspace.as_ref())?; + + let extern_dir = workspace + .as_ref() + .join(&shared_package.config.dependencies_dir); + + // delete if needed + if extern_dir.exists() { + fs::remove_dir_all(&extern_dir) + .with_context(|| format!("Unable to delete {extern_dir:?}"))?; + } + + FileRepository::copy_from_cache(shared_package, resolved_deps, workspace.as_ref())?; write_cmake(shared_package, repository)?; shared_package.try_write_toolchain(repository)?; diff --git a/src/tests/mocks/repo.rs b/src/tests/mocks/repo.rs index bb205b9f..b9348a3e 100644 --- a/src/tests/mocks/repo.rs +++ b/src/tests/mocks/repo.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use qpm_package::models::extra::DependencyLibType; use qpm_package::models::{ dependency::{Dependency, SharedDependency, SharedPackageConfig}, extra::AdditionalPackageMetadata, @@ -65,6 +66,7 @@ pub fn build_artifact_and_depend( restored_dependencies: vec![SharedDependency { dependency: dep, version: shared_dep.config.info.version.clone(), + restored_lib_type: DependencyLibType::HeaderOnly, }], } } @@ -106,6 +108,7 @@ pub fn build_artifact_and_depends( additional_data: shared_config.config.info.additional_data.clone(), }, version: shared_config.config.info.version.clone(), + restored_lib_type: DependencyLibType::HeaderOnly, }) .collect(), } diff --git a/src/utils/cmake.rs b/src/utils/cmake.rs index e11f962e..5c03edb7 100644 --- a/src/utils/cmake.rs +++ b/src/utils/cmake.rs @@ -5,7 +5,7 @@ use std::{ }; use color_eyre::{eyre::Context, Result}; -use qpm_package::{models::dependency::SharedPackageConfig, extensions::package_metadata::PackageMetadataExtensions}; +use qpm_package::models::dependency::SharedPackageConfig; use crate::repository::Repository; use std::fmt::Write as OtherWrite; @@ -262,11 +262,7 @@ pub fn make_defines_string(dep: &SharedPackageConfig) -> Result { )?; result.push_str("# derived from override .so name or just id_version\n"); - writeln!( - result, - "set(COMPILE_ID \"{}\")", - dep.config.info.get_module_id() - )?; + writeln!(result, "set(COMPILE_ID \"{}\")", dep.config.info.id)?; result.push_str( "# derived from whichever codegen package is installed, will default to just codegen\n", diff --git a/src/utils/fs.rs b/src/utils/fs.rs index 2bca2679..8b9389d2 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -1,9 +1,9 @@ -use std::{fs, path::PathBuf}; +use std::{fs, path::Path}; use color_eyre::Result; use fs_extra::{dir::copy as copy_directory, file::copy as copy_file}; -pub fn copy_things(a: &PathBuf, b: &PathBuf) -> Result<()> { +pub fn copy_things(a: &Path, b: &Path) -> Result<()> { if a.is_dir() { fs::create_dir_all(b)?; } else { From 5570a1891a67950938d20b89ed56bf47dbdb7ec7 Mon Sep 17 00:00:00 2001 From: FernTheDev <15272073+Fernthedev@users.noreply.github.com> Date: Mon, 1 Jan 2024 00:37:39 -0400 Subject: [PATCH 3/6] Add dynamic and static out paths to toolchain --- src/models/toolchain.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/models/toolchain.rs b/src/models/toolchain.rs index 02fe0fee..e7745ba9 100644 --- a/src/models/toolchain.rs +++ b/src/models/toolchain.rs @@ -1,10 +1,8 @@ use std::{fs::File, path::PathBuf}; use color_eyre::eyre::Result; -use qpm_package::models::{ - dependency::SharedPackageConfig, extra::CompileOptions, package::PackageConfig, -}; -use serde::{Serialize, Deserialize}; +use qpm_package::models::{dependency::SharedPackageConfig, extra::CompileOptions}; +use serde::{Deserialize, Serialize}; use crate::repository::Repository; @@ -15,7 +13,7 @@ pub struct ToolchainData { pub extern_dir: PathBuf, pub binary_out: Option, - pub debug_binary_out: Option, + pub static_binary_out: Option, } pub fn write_toolchain_file( @@ -88,12 +86,26 @@ pub fn write_toolchain_file( } }); + let extern_dir = shared_config.config.dependencies_dir.clone(); + + let static_binary_out = shared_config + .config + .info + .additional_data + .static_lib_out + .clone(); + let binary_out = shared_config + .config + .info + .additional_data + .dynamic_lib_out + .clone(); + let toolchain = ToolchainData { compile_options, - extern_dir: shared_config.config.dependencies_dir.clone(), - // TODO: - binary_out: None, - debug_binary_out: None, + extern_dir, + binary_out, + static_binary_out, }; let file = File::create(toolchain_path)?; serde_json::to_writer_pretty(file, &toolchain)?; From 922245508b8da54d0219d4d9b62f1c1c2c0c2b3b Mon Sep 17 00:00:00 2001 From: FernTheDev <15272073+Fernthedev@users.noreply.github.com> Date: Mon, 1 Jan 2024 12:15:14 -0400 Subject: [PATCH 4/6] Fix missing condition --- src/models/package.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/package.rs b/src/models/package.rs index 5f71ae84..910f5b4f 100644 --- a/src/models/package.rs +++ b/src/models/package.rs @@ -109,7 +109,7 @@ impl PackageConfigExtensions for PackageConfig { let dynamic_lib_out = &self.info.additional_data.dynamic_lib_out; let static_lib_out = &self.info.additional_data.static_lib_out; - if !headers_only && (dynamic_lib_out.is_none() || static_lib_out.is_none()) { + if !headers_only && dynamic_lib_out.is_none() && static_lib_out.is_none() { bail!( "{} nor {} are defined!", "qpm.shared.json::config::info::additionalData::dynamicLibOut".file_path_color(), From fce146787158833107d3ce7cac3bb6d1eb4977e2 Mon Sep 17 00:00:00 2001 From: FernTheDev <15272073+Fernthedev@users.noreply.github.com> Date: Mon, 1 Jan 2024 12:31:14 -0400 Subject: [PATCH 5/6] Remove link checks for local installs --- src/repository/local.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/repository/local.rs b/src/repository/local.rs index 107886a5..fe3227a6 100644 --- a/src/repository/local.rs +++ b/src/repository/local.rs @@ -396,10 +396,10 @@ impl FileRepository { let name = match dependency_lib_type { // if has so link and is not using static_link // use so name - DependencyLibType::Shared if data.so_link.is_some() => { + DependencyLibType::Shared => { shared_dep.dependency.get_dynamic_lib_out()? } - DependencyLibType::Static if data.static_link.is_some() => { + DependencyLibType::Static => { shared_dep.dependency.get_static_lib_out()? } _ => bail!("Attempting to use dependency as {dependency_lib_type:?} but failed. Info: {data:?}"), From 0ee163894c8613ff9efd82400771ecd28cc1b326 Mon Sep 17 00:00:00 2001 From: FernTheDev <15272073+Fernthedev@users.noreply.github.com> Date: Mon, 1 Jan 2024 12:35:46 -0400 Subject: [PATCH 6/6] Fix collect deps wrong path --- src/repository/local.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/repository/local.rs b/src/repository/local.rs index fe3227a6..6f77f6d2 100644 --- a/src/repository/local.rs +++ b/src/repository/local.rs @@ -397,26 +397,26 @@ impl FileRepository { // if has so link and is not using static_link // use so name DependencyLibType::Shared => { - shared_dep.dependency.get_dynamic_lib_out()? + shared_dep.dependency.get_dynamic_lib_out()?.file_name().unwrap().to_str().unwrap() } DependencyLibType::Static => { - shared_dep.dependency.get_static_lib_out()? + shared_dep.dependency.get_static_lib_out()?.file_name().unwrap().to_str().unwrap() } _ => bail!("Attempting to use dependency as {dependency_lib_type:?} but failed. Info: {data:?}"), }; let src_binary = libs_path.join(name); + let dst_binary = + extern_binaries.join(name); if !src_binary.exists() { bail!( "Missing binary {} for {}:{}", - name.file_name().unwrap().to_string_lossy(), + name, dep_id, shared_dep.version ); } - let dst_binary = - extern_binaries.join(name.file_name().unwrap().to_str().unwrap()); let path = (src_binary, dst_binary); Ok(path)