Skip to content

Commit d94f8a1

Browse files
Error if the stdlib version requested mismatches current version (#4335)
1 parent a8e394b commit d94f8a1

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/Operations.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,37 @@ function get_compat_workspace(env, name)
524524
return compat
525525
end
526526

527+
function check_stdlib_version_compat!(pkg::PackageSpec, julia_version)
528+
julia_version === nothing && return
529+
pkg.version === nothing && return
530+
@assert pkg.uuid !== nothing
531+
532+
if !(is_stdlib(pkg.uuid, julia_version) && !(pkg.uuid in Types.UPGRADABLE_STDLIBS_UUIDS))
533+
return
534+
end
535+
536+
current_stdlib_version = Types.stdlib_version(pkg.uuid, julia_version)
537+
current_stdlib_version === nothing && return
538+
539+
# Check if the requested version conflicts with current stdlib version
540+
version_conflicts = if pkg.version isa VersionNumber
541+
pkg.version != current_stdlib_version
542+
elseif pkg.version isa VersionSpec
543+
!(current_stdlib_version in pkg.version)
544+
else
545+
error("Unexpected version spec type for stdlib `$(pkg.name)`: $(typeof(pkg.version))")
546+
end
547+
548+
return if version_conflicts
549+
throw(
550+
Resolve.ResolverError(
551+
"""Cannot add stdlib `$(pkg.name)` with version specification `$(pkg.version)`.
552+
The current Julia version v$(julia_version) uses `$(pkg.name)` v$(current_stdlib_version)."""
553+
)
554+
)
555+
end
556+
end
557+
527558
# Resolve a set of versions given package version specs
528559
# looks at uuid, version, repo/path,
529560
# sets version to a VersionNumber
@@ -579,6 +610,9 @@ function resolve_versions!(
579610
)
580611
)
581612
end
613+
614+
check_stdlib_version_compat!(pkg, julia_version)
615+
582616
# Work around not clobbering 0.x.y+ for checked out old type of packages
583617
if !(pkg.version isa VersionNumber)
584618
pkg.version = v

test/api.jl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,4 +448,67 @@ end
448448
end
449449
end
450450

451+
@testset "Stdlib version validation" begin
452+
isolate() do
453+
Pkg.activate(temp = true)
454+
455+
# Test that adding a stdlib with wrong version fails
456+
pkg_uuid = Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f") # Pkg stdlib UUID
457+
current_pkg_version = Pkg.Types.stdlib_version(pkg_uuid, VERSION)
458+
459+
# Create a fake wrong version that's different from current
460+
wrong_version = VersionNumber(current_pkg_version.major, current_pkg_version.minor + 1, 0)
461+
462+
# Test that adding Pkg with wrong version throws an error
463+
@test_throws r"Cannot add stdlib `Pkg` with version " Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = wrong_version))
464+
465+
# Test that adding Pkg with correct version works (should be a no-op)
466+
@test_nowarn Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = current_pkg_version))
467+
468+
Pkg.activate(temp = true)
469+
# Test that upgradable stdlibs (downgradable too) are not affected by version validation
470+
# DelimitedFiles is an upgradable stdlib
471+
delim_files_uuid = Base.UUID("8bb1440f-4735-579b-a4ab-409b98df4dab")
472+
# Should be able to add DelimitedFiles with any version without error
473+
old_version = v"1.9.0" # julia 1.13.0 is on v1.9.1
474+
@test Pkg.Types.stdlib_version(delim_files_uuid, VERSION) != old_version
475+
# We expect this might fail for resolver reasons, but NOT for stdlib version validation
476+
Pkg.add(Pkg.PackageSpec(name = "DelimitedFiles", uuid = delim_files_uuid, version = old_version))
477+
@test Pkg.dependencies()[delim_files_uuid].version == old_version
478+
479+
Pkg.activate(temp = true)
480+
# Test VersionSpec validation (like REPL "Package@version" syntax)
481+
# Test that adding Pkg with wrong version via VersionSpec throws an error
482+
wrong_version_spec = Pkg.Versions.VersionSpec(wrong_version)
483+
@test_throws r"Cannot add stdlib `Pkg` with version " Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = wrong_version_spec))
484+
485+
Pkg.activate(temp = true)
486+
# Test that adding Pkg with correct version via VersionSpec works
487+
correct_version_spec = Pkg.Versions.VersionSpec(current_pkg_version)
488+
@test_nowarn Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = correct_version_spec))
489+
490+
Pkg.activate(temp = true)
491+
# Test that VersionSpec with ranges that include current version work
492+
# This should work as the current version is within the range
493+
version_range_spec = Pkg.Versions.VersionSpec("*") # Allow any version
494+
@test_nowarn Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = version_range_spec))
495+
496+
Pkg.activate(temp = true)
497+
# Test String version validation (like REPL "Package@version" syntax)
498+
# Test that adding Pkg with wrong version via String throws an error
499+
wrong_version_string = string(wrong_version)
500+
@test_throws r"Cannot add stdlib `Pkg` with version " Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = wrong_version_string))
501+
502+
Pkg.activate(temp = true)
503+
# Test that adding Pkg with correct version via String works
504+
correct_version_string = string(current_pkg_version)
505+
@test_nowarn Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = correct_version_string))
506+
507+
Pkg.activate(temp = true)
508+
# Test stdlib not in manifest scenario (fresh environment)
509+
# This tests the first update_package_add method with ::Nothing entry
510+
@test_throws r"Cannot add stdlib `Pkg` with version " Pkg.add(Pkg.PackageSpec(name = "Pkg", uuid = pkg_uuid, version = wrong_version))
511+
end
512+
end
513+
451514
end # module APITests

0 commit comments

Comments
 (0)