Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions crates/mono-project/src/project/version/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ pub trait VersionExt {
/// Returns the next version after applying the given increment.
fn bump(&self, increment: Increment) -> Version;

/// Returns the highest possible increment for the version.
/// Returns the minimum increment for the version.
fn min_bump(&self) -> Option<Increment>;

/// Returns the maximum increment for the version.
fn max_bump(&self) -> Increment;

/// Parses a version from a string, allowing for an optional `v` prefix.
Expand Down Expand Up @@ -113,15 +116,21 @@ impl VersionExt for Version {
version
}

/// Returns the highest possible increment for the version.
///
/// This method returns the highest possible increment for this version,
/// taking into account special handling for `0.0.z` and `0.y.z` ranges.
/// Returns the minimum increment for the version.
fn min_bump(&self) -> Option<Increment> {
if let (0, 0) = (self.major, self.minor) {
Some(Increment::Patch)
} else {
None
}
}

/// Returns the maximum increment for the version.
fn max_bump(&self) -> Increment {
match (self.major, self.minor) {
(0, 0) => Increment::Patch,
(0, _) => Increment::Minor,
_ => Increment::Major,
(_, _) => Increment::Major,
}
}
}
17 changes: 15 additions & 2 deletions crates/mono-project/src/project/workspace/dependents/suggestion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@

//! Version increment suggestion.

use std::cmp;
use std::collections::BTreeSet;

use crate::project::manifest::Manifest;
use crate::project::version::Increment;
use crate::project::version::{Increment, VersionExt};
use crate::project::{Project, Result};

use super::Dependents;
Expand Down Expand Up @@ -66,6 +67,7 @@ where
/// # Errors
///
/// This method passes through errors returned by the given function.
#[allow(clippy::missing_panics_doc)]
pub fn bump<F>(&self, increments: &mut [Option<Increment>], f: F) -> Result
where
F: Fn(Suggestion<'_, T>) -> Result<Option<Increment>>,
Expand All @@ -82,6 +84,17 @@ where
// chosen by the caller are correctly propagated to dependents
let incoming = self.graph.topology().incoming();
for node in self.graph.traverse(sources) {
let project = self.graph[node];

// Obtain the current package version, and clamp the increment to
// the minimum and maximum viable increments for the given version.
// This ensures that we never suggest an increment lower or higher
// than what the version requires or allows.
let version = project.manifest.version().expect("invariant");
increments[node] = increments[node]
.map(|increment| cmp::min(increment, version.max_bump()))
.or(version.min_bump());

// Obtain the unique version increments of all dependencies, and
// collect them into a set for selection through the caller
let mut options = BTreeSet::from_iter([increments[node]]);
Expand All @@ -94,7 +107,7 @@ where
// Collect the suggested version increments, and invoke the given
// function, remembering the returned version increment
increments[node] = f(Suggestion {
project: self.graph[node],
project,
increments: &options.into_iter().collect::<Vec<_>>(),
})?;
}
Expand Down