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/), 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). 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 ## [0.5.0-rc.1] - 2024-10-06
### Changed ### Changed
- Rewrite the entire project in a more maintainable way by @daimond113 - Rewrite the entire project in a more maintainable way by @daimond113

View file

@ -118,6 +118,7 @@ impl AddCommand {
pesde::source::workspace::specifier::WorkspaceDependencySpecifier { pesde::source::workspace::specifier::WorkspaceDependencySpecifier {
name: name.clone(), name: name.clone(),
version_type: version.unwrap_or_default(), 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")? .context("missing default index in workspace package manifest")?
.to_string(), .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 indicatif::MultiProgress;
use pesde::{ use pesde::{
lockfile::{DependencyGraph, DownloadedGraph, Lockfile}, lockfile::{DependencyGraph, DownloadedGraph, Lockfile},
manifest::target::TargetKind,
names::{PackageName, PackageNames}, names::{PackageName, PackageNames},
source::{version_id::VersionId, workspace::specifier::VersionType, PackageSources}, source::{version_id::VersionId, workspace::specifier::VersionType, PackageSources},
Project, Project,
@ -268,7 +269,7 @@ pub fn shift_project_dir(project: &Project, pkg_dir: PathBuf) -> Project {
pub fn run_on_workspace_members( pub fn run_on_workspace_members(
project: &Project, project: &Project,
f: impl Fn(Project) -> anyhow::Result<()>, f: impl Fn(Project) -> anyhow::Result<()>,
) -> anyhow::Result<BTreeMap<PackageName, RelativePathBuf>> { ) -> anyhow::Result<BTreeMap<PackageName, BTreeMap<TargetKind, RelativePathBuf>>> {
Ok(match project.workspace_dir() { Ok(match project.workspace_dir() {
Some(_) => { Some(_) => {
// this might seem counterintuitive, but remember that the workspace // this might seem counterintuitive, but remember that the workspace
@ -282,18 +283,24 @@ pub fn run_on_workspace_members(
.map(|(path, manifest)| { .map(|(path, manifest)| {
( (
manifest.name, manifest.name,
manifest.target.kind(),
RelativePathBuf::from_path(path.strip_prefix(project.package_dir()).unwrap()) RelativePathBuf::from_path(path.strip_prefix(project.package_dir()).unwrap())
.unwrap(), .unwrap(),
) )
}) })
.map(|(name, path)| { .map(|(name, target, path)| {
f(shift_project_dir( f(shift_project_dir(
project, project,
path.to_path(project.package_dir()), path.to_path(project.package_dir()),
)) ))
.map(|_| (name, path)) .map(|_| (name, target, path))
}) })
.collect::<Result<_, _>>() .collect::<Result<Vec<_>, _>>()
.context("failed to install workspace member's dependencies")?, .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 /// The workspace members
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub workspace: BTreeMap<PackageName, RelativePathBuf>, pub workspace: BTreeMap<PackageName, BTreeMap<TargetKind, RelativePathBuf>>,
/// The graph of dependencies /// The graph of dependencies
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]

View file

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

View file

@ -226,12 +226,16 @@ impl PackageSource for GitPackageSource {
} }
}; };
let target = specifier.target.unwrap_or(manifest.target.kind());
let path = lockfile let path = lockfile
.workspace .workspace
.get(&specifier.name) .get(&specifier.name)
.and_then(|targets| targets.get(&target))
.ok_or_else(|| { .ok_or_else(|| {
errors::ResolveError::NoPathForWorkspaceMember( errors::ResolveError::NoPathForWorkspaceMember(
specifier.name.to_string(), specifier.name.to_string(),
target,
Box::new(self.repo_url.clone()), 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 /// Errors that can occur when interacting with the Git package source
pub mod errors { pub mod errors {
use crate::manifest::target::TargetKind;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use thiserror::Error; use thiserror::Error;
@ -594,8 +599,8 @@ pub mod errors {
NoLockfile(Box<gix::Url>), NoLockfile(Box<gix::Url>),
/// No path for a workspace member was found in the lockfile /// No path for a workspace member was found in the lockfile
#[error("no path found for workspace member {0} in lockfile for repository {1}")] #[error("no path found for workspace member {0} {1} in lockfile for repository {2}")]
NoPathForWorkspaceMember(String, Box<gix::Url>), NoPathForWorkspaceMember(String, TargetKind, Box<gix::Url>),
} }
/// Errors that can occur when downloading a package from a Git package source /// 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::{Deserialize, Serialize};
use serde_with::{DeserializeFromStr, SerializeDisplay}; use serde_with::{DeserializeFromStr, SerializeDisplay};
use std::{fmt::Display, str::FromStr}; use std::{fmt::Display, str::FromStr};
@ -12,6 +12,8 @@ pub struct WorkspaceDependencySpecifier {
/// The version type to use when publishing the package /// The version type to use when publishing the package
#[serde(default, rename = "version")] #[serde(default, rename = "version")]
pub version_type: VersionType, pub version_type: VersionType,
/// The target of the workspace package
pub target: Option<TargetKind>,
} }
impl DependencySpecifier for WorkspaceDependencySpecifier {} impl DependencySpecifier for WorkspaceDependencySpecifier {}