Skip to content

Commit 99938fc

Browse files
committed
Resolve artifact ambiguities using shortest match
This changes the behavior of `select_platform()` to resolve ambiguities using a two-step process. Previously, we would simply sort the resultant triplets and return the last one (so as to provide asemi- arbitrary stability, and also to prefer higher version numbers over lower version numbers in tags). However, with the proliferation of tags (and especially the new `sanitize=memory` tags) we need a way to exclude these "extra" tags when our `HostPlatform()` does not have them. This new matching algorithm excludes candidates from matching with the platform if there are other candidates with fewer total tags. This results in a "simplest match first" behavior, which better represents the intent of tags in the first place.
1 parent d1a56f5 commit 99938fc

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

base/binaryplatforms.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,12 +1067,20 @@ function select_platform(download_info::Dict, platform::AbstractPlatform = HostP
10671067
return nothing
10681068
end
10691069

1070-
# At this point, we may have multiple possibilities. E.g. if, in the future,
1071-
# Julia can be built without a direct dependency on libgfortran, we may match
1072-
# multiple tarballs that vary only within their libgfortran ABI. To narrow it
1073-
# down, we just sort by triplet, then pick the last one. This has the effect
1074-
# of generally choosing the latest release (e.g. a `libgfortran5` tarball
1075-
# rather than a `libgfortran3` tarball)
1070+
# At this point, we may have multiple possibilities. We now engage a multi-
1071+
# stage selection algorithm, where we first choose simpler matches over more
1072+
# complex matches. We define a simpler match as one that has fewer tags
1073+
# overall. As these candidate matches have already been filtered to match
1074+
# the given platform, the only other tags that exist are ones that are in
1075+
# addition to the tags declared by the platform. Hence, selecting the
1076+
# minimum in number of tags is equivalent to selecting the closest match.
1077+
min_tag_count = minimum(length(tags(p)) for p in ps)
1078+
filter!(p -> length(tags(p)) == min_tag_count, ps)
1079+
1080+
# Now we _still_ may continue to have multiple matches, so we now simply sort
1081+
# the candidate matches by their triplets and take the last one, so as to
1082+
# generally choose the latest release (e.g. a `libgfortran5` tarball over a
1083+
# `libgfortran3` tarball).
10761084
p = last(sort(ps, by = p -> triplet(p)))
10771085
return download_info[p]
10781086
end

test/binaryplatforms.jl

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,9 @@ end
315315
P("x86_64", "linux"; libgfortran_version=v"5") => "linux8",
316316

317317
# Ambiguity test
318-
P("aarch64", "linux"; libgfortran_version=v"3") => "linux4",
318+
P("aarch64", "linux"; libgfortran_version=v"3") => "linux3",
319319
P("aarch64", "linux"; libgfortran_version=v"3", libstdcxx_version=v"3.4.18") => "linux5",
320+
P("aarch64", "linux"; libgfortran_version=v"3", libstdcxx_version=v"3.4.18", foo="bar") => "linux9",
320321

321322
# OS test
322323
P("x86_64", "macos"; libgfortran_version=v"3") => "mac4",
@@ -327,8 +328,10 @@ end
327328
@test select_platform(platforms, P("x86_64", "linux"; libgfortran_version=v"4")) == "linux7"
328329

329330
# Ambiguity test
330-
@test select_platform(platforms, P("aarch64", "linux")) == "linux5"
331-
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"3")) == "linux5"
331+
@test select_platform(platforms, P("aarch64", "linux")) == "linux3"
332+
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"3")) == "linux3"
333+
# This one may be surprising, but we still match `linux3`, and since linux3 is shorter, we choose it.
334+
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"3", libstdcxx_version=v"3.4.18")) === "linux3"
332335
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"4")) === nothing
333336

334337
@test select_platform(platforms, P("x86_64", "macos")) == "mac4"
@@ -339,6 +342,14 @@ end
339342

340343
# Sorry, Alex. ;)
341344
@test select_platform(platforms, P("x86_64", "freebsd")) === nothing
345+
346+
# The new "prefer shortest matching" algorithm is meant to be used to resolve ambiguities such as the following:
347+
platforms = Dict(
348+
# Typical binning test
349+
P("x86_64", "linux") => "good",
350+
P("x86_64", "linux"; sanitize="memory") => "bad",
351+
)
352+
@test select_platform(platforms, P("x86_64", "linux")) == "good"
342353
end
343354

344355
@testset "Custom comparators" begin

0 commit comments

Comments
 (0)