feat: allow full version reqs in workspace spec version field

This commit is contained in:
daimond113 2024-10-13 14:13:21 +02:00
parent e6773144db
commit 15df417472
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
5 changed files with 63 additions and 10 deletions

View file

@ -6,6 +6,9 @@ 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
- Support full version requirements in workspace version field by @daimond113
### Fixed
- Correct `pesde.toml` inclusion message in `publish` command by @daimond113
- Allow writes to files when `link` is false in PackageFS::write_to by @daimond113

View file

@ -117,7 +117,7 @@ impl AddCommand {
DependencySpecifiers::Workspace(
pesde::source::workspace::specifier::WorkspaceDependencySpecifier {
name: name.clone(),
version_type: version.unwrap_or_default(),
version: version.clone().unwrap_or_default(),
target: self.target,
},
),
@ -220,7 +220,7 @@ impl AddCommand {
println!(
"added workspace {}@{} to {}",
spec.name, spec.version_type, dependency_key
spec.name, spec.version, dependency_key
);
}
}

View file

@ -17,7 +17,10 @@ use pesde::{
pesde::{specifier::PesdeDependencySpecifier, PesdePackageSource},
specifiers::DependencySpecifiers,
traits::PackageSource,
workspace::{specifier::VersionType, WorkspacePackageSource},
workspace::{
specifier::{VersionType, VersionTypeOrReq},
WorkspacePackageSource,
},
IGNORED_DIRS, IGNORED_FILES,
},
Project, DEFAULT_INDEX_NAME, MANIFEST_FILE_NAME,
@ -344,8 +347,11 @@ impl PublishCommand {
*specifier = DependencySpecifiers::Pesde(PesdeDependencySpecifier {
name: spec.name.clone(),
version: match spec.version_type {
VersionType::Wildcard => VersionReq::STAR,
version: match spec.version.clone() {
VersionTypeOrReq::VersionType(VersionType::Wildcard) => {
VersionReq::STAR
}
VersionTypeOrReq::Req(r) => r,
v => VersionReq::parse(&format!("{v}{}", manifest.version))
.context(format!("failed to parse version for {v}"))?,
},

View file

@ -6,7 +6,7 @@ use pesde::{
lockfile::{DependencyGraph, DownloadedGraph, Lockfile},
manifest::target::TargetKind,
names::{PackageName, PackageNames},
source::{version_id::VersionId, workspace::specifier::VersionType, PackageSources},
source::{version_id::VersionId, workspace::specifier::VersionTypeOrReq, PackageSources},
Project,
};
use relative_path::RelativePathBuf;
@ -152,7 +152,7 @@ impl VersionedPackageName {
enum AnyPackageIdentifier<V: FromStr = VersionId, N: FromStr = PackageNames> {
PackageName(VersionedPackageName<V, N>),
Url((gix::Url, String)),
Workspace(VersionedPackageName<VersionType, PackageName>),
Workspace(VersionedPackageName<VersionTypeOrReq, PackageName>),
}
impl<V: FromStr<Err = E>, E: Into<anyhow::Error>, N: FromStr<Err = F>, F: Into<anyhow::Error>>

View file

@ -11,7 +11,7 @@ pub struct WorkspaceDependencySpecifier {
pub name: PackageName,
/// The version type to use when publishing the package
#[serde(default, rename = "version")]
pub version_type: VersionType,
pub version: VersionTypeOrReq,
/// The target of the workspace package
pub target: Option<TargetKind>,
}
@ -19,7 +19,7 @@ impl DependencySpecifier for WorkspaceDependencySpecifier {}
impl Display for WorkspaceDependencySpecifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "workspace:{}{}", self.version_type, self.name)
write!(f, "workspace:{}{}", self.version, self.name)
}
}
@ -66,6 +66,42 @@ impl FromStr for VersionType {
}
}
/// Either a version type or a version requirement
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
pub enum VersionTypeOrReq {
/// A version type
VersionType(VersionType),
/// A version requirement
Req(semver::VersionReq),
}
impl Default for VersionTypeOrReq {
fn default() -> Self {
VersionTypeOrReq::VersionType(VersionType::Caret)
}
}
impl Display for VersionTypeOrReq {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
VersionTypeOrReq::VersionType(t) => write!(f, "{t}"),
VersionTypeOrReq::Req(r) => write!(f, "{r}"),
}
}
}
impl FromStr for VersionTypeOrReq {
type Err = errors::VersionTypeOrReqFromStr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map(VersionTypeOrReq::VersionType).or_else(|_| {
s.parse()
.map(VersionTypeOrReq::Req)
.map_err(errors::VersionTypeOrReqFromStr::InvalidVersionReq)
})
}
}
/// Errors that can occur when using a version type
pub mod errors {
use thiserror::Error;
@ -74,7 +110,15 @@ pub mod errors {
#[derive(Debug, Error)]
pub enum VersionTypeFromStr {
/// The version type is invalid
#[error("invalid version type: {0}")]
#[error("invalid version type {0}")]
InvalidVersionType(String),
}
/// Errors that can occur when parsing a version type or requirement
#[derive(Debug, Error)]
pub enum VersionTypeOrReqFromStr {
/// The version requirement is invalid
#[error("invalid version requirement {0}")]
InvalidVersionReq(#[from] semver::Error),
}
}