Skip to content

Commit

Permalink
fix: Fix multi-range version detection. (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj authored Nov 22, 2023
1 parent 2b2a2b8 commit 0b3ab02
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#### 🐞 Fixes

- Fixed an issue where `proto list-global` would panic when canonicalizing paths.
- Fixed multi-version ranges (`||`) not resolving locally installed versions correctly.

## 0.23.2

Expand Down
34 changes: 17 additions & 17 deletions crates/core/src/version_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,12 @@ impl<'tool> VersionResolver<'tool> {
}
}

pub fn match_highest_version<'l, I>(req: &'l VersionReq, versions: I) -> Option<VersionSpec>
where
I: IntoIterator<Item = &'l Version>,
{
pub fn match_highest_version(req: &VersionReq, versions: &[&Version]) -> Option<VersionSpec> {
let mut highest_match: Option<Version> = None;

for version in versions {
if req.matches(version)
&& (highest_match.is_none() || highest_match.as_ref().is_some_and(|v| version > v))
&& (highest_match.is_none() || highest_match.as_ref().is_some_and(|v| *version > v))
{
highest_match = Some((*version).clone());
}
Expand All @@ -79,7 +76,7 @@ where
}

// Filter out aliases because they cannot be matched against
fn extract_installed_versions(installed: &HashSet<VersionSpec>) -> HashSet<&Version> {
fn extract_installed_versions(installed: &HashSet<VersionSpec>) -> Vec<&Version> {
installed
.iter()
.filter_map(|item| match item {
Expand All @@ -95,15 +92,16 @@ pub fn resolve_version(
aliases: &BTreeMap<String, UnresolvedVersionSpec>,
manifest: Option<&ToolManifest>,
) -> miette::Result<VersionSpec> {
let remote_versions = versions.iter().collect::<Vec<_>>();
let installed_versions = if let Some(manifest) = manifest {
extract_installed_versions(&manifest.installed_versions)
} else {
HashSet::new()
vec![]
};

match &candidate {
UnresolvedVersionSpec::Canary => {
return Ok(VersionSpec::Alias("canary".into()));
return Ok(VersionSpec::Canary);
}
UnresolvedVersionSpec::Alias(alias) => {
let mut alias_value = None;
Expand All @@ -123,34 +121,36 @@ pub fn resolve_version(
UnresolvedVersionSpec::Req(req) => {
// Check locally installed versions first
if !installed_versions.is_empty() {
if let Some(version) = match_highest_version(req, installed_versions) {
if let Some(version) = match_highest_version(req, &installed_versions) {
return Ok(version);
}
}

// Otherwise we'll need to download from remote
if let Some(version) = match_highest_version(req, versions) {
if let Some(version) = match_highest_version(req, &remote_versions) {
return Ok(version);
}
}
UnresolvedVersionSpec::ReqAny(reqs) => {
for req in reqs {
// Check locally installed versions first
if !installed_versions.is_empty() {
if let Some(version) = match_highest_version(req, installed_versions.clone()) {
// Check locally installed versions first
if !installed_versions.is_empty() {
for req in reqs {
if let Some(version) = match_highest_version(req, &installed_versions) {
return Ok(version);
}
}
}

// Otherwise we'll need to download from remote
if let Some(version) = match_highest_version(req, versions) {
// Otherwise we'll need to download from remote
for req in reqs {
if let Some(version) = match_highest_version(req, &remote_versions) {
return Ok(version);
}
}
}
UnresolvedVersionSpec::Version(ver) => {
// Check locally installed versions first
if installed_versions.contains(ver) {
if installed_versions.contains(&ver) {
return Ok(VersionSpec::Version(ver.to_owned()));
}

Expand Down

0 comments on commit 0b3ab02

Please sign in to comment.