feat: support multitarget workspace members

This commit is contained in:
daimond113 2024-10-06 23:49:59 +02:00
parent fc123ee537
commit 962482962b
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
8 changed files with 33 additions and 12 deletions

View file

@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Add support for multiple targets under the same package name in workspace members by @daimond113
## [0.5.0-rc.1] - 2024-10-06
### Changed
- Rewrite the entire project in a more maintainable way by @daimond113

View file

@ -118,6 +118,7 @@ impl AddCommand {
pesde::source::workspace::specifier::WorkspaceDependencySpecifier {
name: name.clone(),
version_type: version.unwrap_or_default(),
target: self.target,
},
),
),

View file

@ -347,7 +347,7 @@ impl PublishCommand {
.context("missing default index in workspace package manifest")?
.to_string(),
),
target: Some(manifest.target.kind()),
target: Some(spec.target.unwrap_or(manifest.target.kind())),
});
}
}

View file

@ -4,6 +4,7 @@ use gix::bstr::BStr;
use indicatif::MultiProgress;
use pesde::{
lockfile::{DependencyGraph, DownloadedGraph, Lockfile},
manifest::target::TargetKind,
names::{PackageName, PackageNames},
source::{version_id::VersionId, workspace::specifier::VersionType, PackageSources},
Project,
@ -268,7 +269,7 @@ pub fn shift_project_dir(project: &Project, pkg_dir: PathBuf) -> Project {
pub fn run_on_workspace_members(
project: &Project,
f: impl Fn(Project) -> anyhow::Result<()>,
) -> anyhow::Result<BTreeMap<PackageName, RelativePathBuf>> {
) -> anyhow::Result<BTreeMap<PackageName, BTreeMap<TargetKind, RelativePathBuf>>> {
Ok(match project.workspace_dir() {
Some(_) => {
// this might seem counterintuitive, but remember that the workspace
@ -282,18 +283,24 @@ pub fn run_on_workspace_members(
.map(|(path, manifest)| {
(
manifest.name,
manifest.target.kind(),
RelativePathBuf::from_path(path.strip_prefix(project.package_dir()).unwrap())
.unwrap(),
)
})
.map(|(name, path)| {
.map(|(name, target, path)| {
f(shift_project_dir(
project,
path.to_path(project.package_dir()),
))
.map(|_| (name, path))
.map(|_| (name, target, path))
})
.collect::<Result<_, _>>()
.context("failed to install workspace member's dependencies")?,
.collect::<Result<Vec<_>, _>>()
.context("failed to install workspace member's dependencies")?
.into_iter()
.fold(BTreeMap::new(), |mut map, (name, target, path)| {
map.entry(name).or_default().insert(target, path);
map
}),
})
}

View file

@ -129,7 +129,7 @@ pub struct Lockfile {
/// The workspace members
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub workspace: BTreeMap<PackageName, RelativePathBuf>,
pub workspace: BTreeMap<PackageName, BTreeMap<TargetKind, RelativePathBuf>>,
/// The graph of dependencies
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]

View file

@ -85,8 +85,10 @@ fn run() -> anyhow::Result<()> {
break 'scripts;
}
let exe_name = exe.with_extension("");
let exe_name = exe_name.file_name().unwrap();
let exe_name = exe.file_name().unwrap().to_string_lossy();
let exe_name = exe_name
.strip_suffix(std::env::consts::EXE_SUFFIX)
.unwrap_or(&exe_name);
if exe_name == env!("CARGO_BIN_NAME") {
break 'scripts;

View file

@ -226,12 +226,16 @@ impl PackageSource for GitPackageSource {
}
};
let target = specifier.target.unwrap_or(manifest.target.kind());
let path = lockfile
.workspace
.get(&specifier.name)
.and_then(|targets| targets.get(&target))
.ok_or_else(|| {
errors::ResolveError::NoPathForWorkspaceMember(
specifier.name.to_string(),
target,
Box::new(self.repo_url.clone()),
)
})?
@ -505,6 +509,7 @@ impl PackageSource for GitPackageSource {
/// Errors that can occur when interacting with the Git package source
pub mod errors {
use crate::manifest::target::TargetKind;
use relative_path::RelativePathBuf;
use thiserror::Error;
@ -594,8 +599,8 @@ pub mod errors {
NoLockfile(Box<gix::Url>),
/// No path for a workspace member was found in the lockfile
#[error("no path found for workspace member {0} in lockfile for repository {1}")]
NoPathForWorkspaceMember(String, Box<gix::Url>),
#[error("no path found for workspace member {0} {1} in lockfile for repository {2}")]
NoPathForWorkspaceMember(String, TargetKind, Box<gix::Url>),
}
/// Errors that can occur when downloading a package from a Git package source

View file

@ -1,4 +1,4 @@
use crate::{names::PackageName, source::DependencySpecifier};
use crate::{manifest::target::TargetKind, names::PackageName, source::DependencySpecifier};
use serde::{Deserialize, Serialize};
use serde_with::{DeserializeFromStr, SerializeDisplay};
use std::{fmt::Display, str::FromStr};
@ -12,6 +12,8 @@ pub struct WorkspaceDependencySpecifier {
/// The version type to use when publishing the package
#[serde(default, rename = "version")]
pub version_type: VersionType,
/// The target of the workspace package
pub target: Option<TargetKind>,
}
impl DependencySpecifier for WorkspaceDependencySpecifier {}