From f505aa7dccccc3917ec97cce1f01c8ccaa149605 Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 7 Jun 2022 15:57:29 -0400 Subject: [PATCH 1/5] add pkgversion(m::Module) --- base/exports.jl | 1 + base/loading.jl | 36 ++++++++++++++++++++++++++--- doc/src/base/base.md | 1 + test/loading.jl | 7 ++++++ test/project/deps/Foo1/Project.toml | 3 +++ 5 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 test/project/deps/Foo1/Project.toml diff --git a/base/exports.jl b/base/exports.jl index 6c1cdcc8b7d77..304d48d24bdcd 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -790,6 +790,7 @@ export parentmodule, pathof, pkgdir, + pkgversion, names, which, @isdefined, diff --git a/base/loading.jl b/base/loading.jl index f2cf385e33643..254bee3e10d95 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -437,6 +437,27 @@ function pkgdir(m::Module, paths::String...) return joinpath(dirname(dirname(path)), paths...) end +""" + pkgversion(m::Module) + +Return the version of the package that imported module `m`, +or `nothing` if `m` was not imported from a package or a +package without a version field set. + +!!! compat "Julia 1.9" + This function was introduced in Julia 1.9. +""" +function pkgversion(m::Module) + _pkgdir = pkgdir(m) + _pkgdir === nothing && return nothing + project_file = locate_project_file(_pkgdir) + if project_file isa String + return get_project_version(project_file) + else + return nothing + end +end + ## generic project & manifest API ## const project_names = ("JuliaProject.toml", "Project.toml") @@ -1209,16 +1230,25 @@ function set_pkgorigin_version_path(pkg, path) if path !== nothing project_file = locate_project_file(joinpath(dirname(path), "..")) if project_file isa String - d = parsed_toml(project_file) - v = get(d, "version", nothing) + v = get_project_version(project_file) if v !== nothing - pkgorigin.version = VersionNumber(v::AbstractString) + pkgorigin.version = v end end end pkgorigin.path = path end +function get_project_version(project_file::String) + d = parsed_toml(project_file) + v = get(d, "version", nothing) + if isnothing(v) + return nothing + else + return VersionNumber(v::AbstractString) + end +end + # Returns `nothing` or the name of the newly-created cachefile function _require(pkg::PkgId) # handle recursive calls to require diff --git a/doc/src/base/base.md b/doc/src/base/base.md index 65334e7c4b677..38d9d788eee35 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -418,6 +418,7 @@ Base.nameof(::Module) Base.parentmodule Base.pathof(::Module) Base.pkgdir(::Module) +Base.pkgversion(::Module) Base.moduleroot __module__ __source__ diff --git a/test/loading.jl b/test/loading.jl index 39e4790eee9d3..dd9aa66da196f 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -359,6 +359,13 @@ module NotPkgModule; end @test pkgdir(NotPkgModule, "src") === nothing end + @testset "pkgversion" begin + @test pkgversion(Foo) == v"1.2.3" + @test pkgversion(Foo.SubFoo1) == v"1.2.3" + @test pkgversion(Foo.SubFoo2) == v"1.2.3" + @test pkgversion(NotPkgModule) === nothing + end + end ## systematic generation of test environments ## diff --git a/test/project/deps/Foo1/Project.toml b/test/project/deps/Foo1/Project.toml new file mode 100644 index 0000000000000..b15bdfc656a64 --- /dev/null +++ b/test/project/deps/Foo1/Project.toml @@ -0,0 +1,3 @@ +name = "Foo" +uuid = "1a6589dc-c33c-4d54-9a54-f7fc4b3ff616" +version = "1.2.3" From 76225f1f62b67b5e01473c9a1585905f7883bef4 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 8 Jun 2022 10:58:19 -0400 Subject: [PATCH 2/5] use the cached version from pkgorigins --- base/loading.jl | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index 254bee3e10d95..c86a713e0619d 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -444,18 +444,17 @@ Return the version of the package that imported module `m`, or `nothing` if `m` was not imported from a package or a package without a version field set. +The version is read from the package's Project.toml at package +load time. + !!! compat "Julia 1.9" This function was introduced in Julia 1.9. """ function pkgversion(m::Module) - _pkgdir = pkgdir(m) - _pkgdir === nothing && return nothing - project_file = locate_project_file(_pkgdir) - if project_file isa String - return get_project_version(project_file) - else - return nothing - end + rootmodule = moduleroot(m) + pkg = PkgId(rootmodule) + pkgorigin = get!(PkgOrigin, pkgorigins, pkg) + return pkgorigin.version end ## generic project & manifest API ## @@ -1230,25 +1229,16 @@ function set_pkgorigin_version_path(pkg, path) if path !== nothing project_file = locate_project_file(joinpath(dirname(path), "..")) if project_file isa String - v = get_project_version(project_file) + d = parsed_toml(project_file) + v = get(d, "version", nothing) if v !== nothing - pkgorigin.version = v + pkgorigin.version = VersionNumber(v::AbstractString) end end end pkgorigin.path = path end -function get_project_version(project_file::String) - d = parsed_toml(project_file) - v = get(d, "version", nothing) - if isnothing(v) - return nothing - else - return VersionNumber(v::AbstractString) - end -end - # Returns `nothing` or the name of the newly-created cachefile function _require(pkg::PkgId) # handle recursive calls to require From 963ea1e60c33a7d523afbc086fe69b3d1bf121fc Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 8 Jun 2022 11:00:02 -0400 Subject: [PATCH 3/5] docstring wording --- base/loading.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index c86a713e0619d..ae23f537737ee 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -441,11 +441,11 @@ end pkgversion(m::Module) Return the version of the package that imported module `m`, -or `nothing` if `m` was not imported from a package or a -package without a version field set. +or `nothing` if `m` was not imported from a package, or imported +from a package without a version field set. -The version is read from the package's Project.toml at package -load time. +The version is read from the package's Project.toml during package +load. !!! compat "Julia 1.9" This function was introduced in Julia 1.9. From a26908658db229f530968ac8cd963c4cceaebff5 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 8 Jun 2022 11:05:21 -0400 Subject: [PATCH 4/5] suggested code fix --- base/loading.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index ae23f537737ee..88ba1050d2b02 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -453,8 +453,8 @@ load. function pkgversion(m::Module) rootmodule = moduleroot(m) pkg = PkgId(rootmodule) - pkgorigin = get!(PkgOrigin, pkgorigins, pkg) - return pkgorigin.version + pkgorigin = get(pkgorigins, pkg, nothing) + return pkgorigin === nothing ? nothing : pkgorigin.version end ## generic project & manifest API ## From 371a5eede5ab02ef0a0d13b7ad9b1d56d6f455cd Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 8 Jun 2022 12:25:25 -0400 Subject: [PATCH 5/5] add to NEWS --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 3bc140e77843c..ac9e84c88b934 100644 --- a/NEWS.md +++ b/NEWS.md @@ -67,6 +67,8 @@ New library functions * `Iterators.flatmap` was added ([#44792]). * New helper `Splat(f)` which acts like `x -> f(x...)`, with pretty printing for inspecting which function `f` was originally wrapped. ([#42717]) +* New `pkgversion(m::Module)` function to get the version of the package that loaded + a given module, similar to `pkgdir(m::Module)`. ([#45607]) Library changes ---------------