From 9e85cd970ad5ba8f59e4294e74dc1fe40d6f232c Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Tue, 7 Jan 2025 23:11:42 +0100 Subject: [PATCH 1/6] add `GAP.Packages.versioninfo()` --- src/packages.jl | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/packages.jl b/src/packages.jl index 7b803ceb..ff581a76 100644 --- a/src/packages.jl +++ b/src/packages.jl @@ -3,6 +3,7 @@ module Packages import Downloads import Pidfile +#import Pkg import ...GAP: disable_error_handler, Globals, GapObj, replace_global!, RNamObj, sysinfo, Wrappers const DEFAULT_PKGDIR = Ref{String}() @@ -525,4 +526,51 @@ function locate_package(name::String) return String(Wrappers.ELM_REC(loaded, lname)[1]) end +""" + versioninfo(io::IO=stdout) + +Print the versions of GAP, and all currently loaded GAP packages. +""" +function versioninfo(io::IO=stdout) + println(io, "GAP version ", String(Globals.GAPInfo.Version)) + println(io, "GAP packages:") + dict = Dict{Symbol, Any}(Globals.GAPInfo.PackagesLoaded) + default_artifacts_path = realpath(joinpath(DEPOT_PATH[1], "artifacts")) + #deps = collect(values(Pkg.dependencies())) + marks = String[] + names = String[] + paths = String[] + versions = String[] + jllversions = String[] + for key in sort(collect(keys(dict))) + name = String(key) + push!(names, name) + vals = dict[key] + origpath = realpath(vals[1]) + path = replace(origpath, default_artifacts_path => "ARTIFACTS") + push!(marks, path == origpath ? "*" : "") + if startswith(path, "ARTIFACTS") + pos = findall("/", path) + if length(pos) > 1 && pos[2][1]-pos[1][1] > 10 + path = path[1:(pos[1][1]+7)] * "..." * path[pos[2][1]:end] + end + end + push!(paths, path) + push!(versions, vals[2]) + # jllpos = findfirst(x -> x.name == "GAP_pkg_$(name)_jll", deps) + # jllversion = jllpos == nothing ? "" : repr(deps[jllpos].version) + # push!(jllversions, replace(jllversion, "\"" => "")) + end + namewidth = maximum(length.(names)) + 2 + verswidth = maximum(length.(versions)) + 2 + #jllverswidth = maximum(length.(jllversions)) + 2 + for i in 1:length(names) + println(io, rpad(marks[i], 2, ' '), + rpad(names[i], namewidth, ' '), + rpad(versions[i], verswidth, ' '), + # rpad(jllversions[i], jllverswidth, ' '), + paths[i]) + end +end + end From e9743bd2c625560953496a134e36e131fb79398e Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 8 Jan 2025 09:22:52 +0100 Subject: [PATCH 2/6] include the new docstring --- docs/src/packages.md | 1 + src/packages.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/packages.md b/docs/src/packages.md index a28dce61..7146627b 100644 --- a/docs/src/packages.md +++ b/docs/src/packages.md @@ -9,6 +9,7 @@ The following functions allow one to load/install/update/remove/locate GAP packages. ```@docs +GAP.Packages.versioninfo GAP.Packages.load GAP.Packages.install GAP.Packages.update diff --git a/src/packages.jl b/src/packages.jl index ff581a76..52828d25 100644 --- a/src/packages.jl +++ b/src/packages.jl @@ -529,7 +529,7 @@ end """ versioninfo(io::IO=stdout) -Print the versions of GAP, and all currently loaded GAP packages. +Print the version and installation paths of all currently loaded GAP packages. """ function versioninfo(io::IO=stdout) println(io, "GAP version ", String(Globals.GAPInfo.Version)) From 9acc841c1701fd8934b2ed49b55dcd0a9621a949 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 8 Jan 2025 15:26:46 +0100 Subject: [PATCH 3/6] next iteration - change `GAP.Packages.versioninfo`: do not show the GAP version, show GAP packages (versions and paths) and jll packages in separate lists, similar to Oscar's `versioninfo`, - do not show `*` in the beginning of the lines for those packages whose paths are nonstandard, - add `GAP.versioninfo` that shows also the GAP (and GAP_jll) version, - introduce keyword arguments for including jll and GAP information, - document `GAP.versioninfo` not `GAP.Packages.versioninfo`. --- docs/src/internal.md | 1 + docs/src/packages.md | 1 - src/GAP.jl | 25 ++++++++++++++++++-- src/packages.jl | 54 +++++++++++++++++++++++++++----------------- 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/docs/src/internal.md b/docs/src/internal.md index 24b525ae..f3b95c19 100644 --- a/docs/src/internal.md +++ b/docs/src/internal.md @@ -6,6 +6,7 @@ DocTestSetup = :(using GAP) # Internal ```@docs +GAP.versioninfo GAP.get_symbols_in_module GAP.GAP GAP.RecDict diff --git a/docs/src/packages.md b/docs/src/packages.md index 7146627b..a28dce61 100644 --- a/docs/src/packages.md +++ b/docs/src/packages.md @@ -9,7 +9,6 @@ The following functions allow one to load/install/update/remove/locate GAP packages. ```@docs -GAP.Packages.versioninfo GAP.Packages.load GAP.Packages.install GAP.Packages.update diff --git a/src/GAP.jl b/src/GAP.jl index 4d65e5e0..92045615 100644 --- a/src/GAP.jl +++ b/src/GAP.jl @@ -1,9 +1,11 @@ """ GAP.jl is the Julia interface to the GAP-System. - For the package manual see https://oscar-system.github.io/GAP.jl/. + For the package manual see + [https://oscar-system.github.io/GAP.jl/](https://oscar-system.github.io/GAP.jl/). - For more information about GAP see https://www.gap-system.org/. + For more information about GAP see + [https://www.gap-system.org/](https://www.gap-system.org/). """ module GAP @@ -318,6 +320,25 @@ function randseed!(seed::Union{Integer,Nothing}=nothing) nothing end +import Pkg + +""" + versioninfo(io::IO = stdout; jll::Bool = false) + +Print the version numbers of GAP.jl and GAP, +and version numbers and installation paths of all currently loaded GAP packages. +Note that these paths can be nonstandard because Julia's package manager +does not control which available version of a GAP package gets loaded. + +If `jll` is `true` then also the underlying binary packages (jll), +if available, are included in the output. +""" +function versioninfo(io::IO = stdout; jll::Bool = false, padding::String = "") + deps = filter(d -> d.name == "GAP", collect(values(Pkg.dependencies()))) + println(io, "GAP.jl version ", deps[1].version) + GAP.Packages.versioninfo(io, GAP = true, jll = jll, padding = padding) +end + include("lowlevel.jl") include("ccalls.jl") include("globals.jl") diff --git a/src/packages.jl b/src/packages.jl index 52828d25..42756844 100644 --- a/src/packages.jl +++ b/src/packages.jl @@ -3,7 +3,7 @@ module Packages import Downloads import Pidfile -#import Pkg +import Pkg import ...GAP: disable_error_handler, Globals, GapObj, replace_global!, RNamObj, sysinfo, Wrappers const DEFAULT_PKGDIR = Ref{String}() @@ -526,29 +526,20 @@ function locate_package(name::String) return String(Wrappers.ELM_REC(loaded, lname)[1]) end -""" - versioninfo(io::IO=stdout) - -Print the version and installation paths of all currently loaded GAP packages. -""" -function versioninfo(io::IO=stdout) - println(io, "GAP version ", String(Globals.GAPInfo.Version)) - println(io, "GAP packages:") +# `GAP.Packages.versioninfo` is called by `GAP.versioninfo`. +function versioninfo(io::IO = stdout; GAP::Bool = false, jll::Bool = false, padding::String = "") + GAP && println(io, padding, "GAP version ", String(Globals.GAPInfo.Version)) + println(io, padding, "GAP packages:") dict = Dict{Symbol, Any}(Globals.GAPInfo.PackagesLoaded) default_artifacts_path = realpath(joinpath(DEPOT_PATH[1], "artifacts")) - #deps = collect(values(Pkg.dependencies())) - marks = String[] names = String[] paths = String[] versions = String[] - jllversions = String[] for key in sort(collect(keys(dict))) name = String(key) push!(names, name) vals = dict[key] - origpath = realpath(vals[1]) - path = replace(origpath, default_artifacts_path => "ARTIFACTS") - push!(marks, path == origpath ? "*" : "") + path = replace(realpath(vals[1]), default_artifacts_path => "ARTIFACTS") if startswith(path, "ARTIFACTS") pos = findall("/", path) if length(pos) > 1 && pos[2][1]-pos[1][1] > 10 @@ -557,20 +548,41 @@ function versioninfo(io::IO=stdout) end push!(paths, path) push!(versions, vals[2]) - # jllpos = findfirst(x -> x.name == "GAP_pkg_$(name)_jll", deps) - # jllversion = jllpos == nothing ? "" : repr(deps[jllpos].version) - # push!(jllversions, replace(jllversion, "\"" => "")) end namewidth = maximum(length.(names)) + 2 verswidth = maximum(length.(versions)) + 2 - #jllverswidth = maximum(length.(jllversions)) + 2 for i in 1:length(names) - println(io, rpad(marks[i], 2, ' '), + println(io, padding, " ", rpad(names[i], namewidth, ' '), rpad(versions[i], verswidth, ' '), - # rpad(jllversions[i], jllverswidth, ' '), paths[i]) end + if jll + deps = collect(values(Pkg.dependencies())) + jllnames = String[] + jlldeps = [] + if GAP + jllname = "GAP_jll" + jllpos = findfirst(x -> x.name == jllname, deps) + push!(jllnames, jllname) + push!(jlldeps, deps[jllpos]) + end + for name in names + jllname = "GAP_pkg_$(name)_jll" + jllpos = findfirst(x -> x.name == jllname, deps) + if jllpos != nothing + push!(jllnames, jllname) + push!(jlldeps, deps[jllpos]) + end + end + jllnamewidth = maximum(length.(jllnames)) + 2 + println(io, padding, "building on:") + for i in 1:length(jllnames) + println(io, padding, " ", + rpad(jllnames[i], jllnamewidth, ' '), + jlldeps[i].version) + end + end end end From 9329baa9263ddc279ec810816b8f8c88a3deeb70 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 8 Jan 2025 16:10:03 +0100 Subject: [PATCH 4/6] do not try to find GAP.jl in `Pkg.dependencies()` --- src/GAP.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/GAP.jl b/src/GAP.jl index 92045615..2bca367d 100644 --- a/src/GAP.jl +++ b/src/GAP.jl @@ -320,8 +320,6 @@ function randseed!(seed::Union{Integer,Nothing}=nothing) nothing end -import Pkg - """ versioninfo(io::IO = stdout; jll::Bool = false) @@ -334,8 +332,9 @@ If `jll` is `true` then also the underlying binary packages (jll), if available, are included in the output. """ function versioninfo(io::IO = stdout; jll::Bool = false, padding::String = "") - deps = filter(d -> d.name == "GAP", collect(values(Pkg.dependencies()))) - println(io, "GAP.jl version ", deps[1].version) + # We cannot use `Pkg.dependencies()` because (depending on the project) + # GAP is perhaps not contained. + println(io, "GAP.jl version ", Compat.pkgversion(@__MODULE__)) GAP.Packages.versioninfo(io, GAP = true, jll = jll, padding = padding) end From 2cbfbc5341e8d18077bb0ecdfd53104c3c6a491b Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 8 Jan 2025 16:48:42 +0100 Subject: [PATCH 5/6] one more iteration - show the jll version for all installed packages not only for the loaded ones, since the jlls are loaded - add `full` argument for `GAP.versioninfo`, like in Oscar - add a test --- src/GAP.jl | 10 +++++++--- src/packages.jl | 28 +++++++++++----------------- test/basics.jl | 7 +++++++ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/GAP.jl b/src/GAP.jl index 2bca367d..a09fb859 100644 --- a/src/GAP.jl +++ b/src/GAP.jl @@ -329,13 +329,17 @@ Note that these paths can be nonstandard because Julia's package manager does not control which available version of a GAP package gets loaded. If `jll` is `true` then also the underlying binary packages (jll), -if available, are included in the output. +if available, of all installed (not necessarily loaded) packages +are included in the output. """ -function versioninfo(io::IO = stdout; jll::Bool = false, padding::String = "") +function versioninfo(io::IO = stdout; jll::Bool = false, full::Bool = false, padding::String = "") + if full + jll = true + end # We cannot use `Pkg.dependencies()` because (depending on the project) # GAP is perhaps not contained. println(io, "GAP.jl version ", Compat.pkgversion(@__MODULE__)) - GAP.Packages.versioninfo(io, GAP = true, jll = jll, padding = padding) + GAP.Packages.versioninfo(io; GAP = true, full = full, jll = jll, padding = padding) end include("lowlevel.jl") diff --git a/src/packages.jl b/src/packages.jl index 42756844..6937a2fe 100644 --- a/src/packages.jl +++ b/src/packages.jl @@ -527,7 +527,10 @@ function locate_package(name::String) end # `GAP.Packages.versioninfo` is called by `GAP.versioninfo`. -function versioninfo(io::IO = stdout; GAP::Bool = false, jll::Bool = false, padding::String = "") +function versioninfo(io::IO = stdout; GAP::Bool = false, jll::Bool = false, full::Bool = false, padding::String = "") + if full + GAP = jll = true + end GAP && println(io, padding, "GAP version ", String(Globals.GAPInfo.Version)) println(io, padding, "GAP packages:") dict = Dict{Symbol, Any}(Globals.GAPInfo.PackagesLoaded) @@ -559,28 +562,19 @@ function versioninfo(io::IO = stdout; GAP::Bool = false, jll::Bool = false, padd end if jll deps = collect(values(Pkg.dependencies())) - jllnames = String[] - jlldeps = [] + jlldeps = filter(x -> startswith(x.name, "GAP_pkg_"), deps) + sort!(jlldeps, by = x -> x.name) if GAP jllname = "GAP_jll" jllpos = findfirst(x -> x.name == jllname, deps) - push!(jllnames, jllname) - push!(jlldeps, deps[jllpos]) - end - for name in names - jllname = "GAP_pkg_$(name)_jll" - jllpos = findfirst(x -> x.name == jllname, deps) - if jllpos != nothing - push!(jllnames, jllname) - push!(jlldeps, deps[jllpos]) - end + pushfirst!(jlldeps, deps[jllpos]) end - jllnamewidth = maximum(length.(jllnames)) + 2 + jllnamewidth = maximum([length(d.name) for d in jlldeps]) + 2 println(io, padding, "building on:") - for i in 1:length(jllnames) + for d in jlldeps println(io, padding, " ", - rpad(jllnames[i], jllnamewidth, ' '), - jlldeps[i].version) + rpad(d.name, jllnamewidth, ' '), + d.version) end end end diff --git a/test/basics.jl b/test/basics.jl index e966b9b2..b6ceace3 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -175,3 +175,10 @@ end print(io, GAP.AbstractAlgebra.Lowercase(), GapObj([1, 2, 3])) @test String(take!(io)) == "GAP: [ 1, 2, 3 ]" end + +@testset "versioninfo" begin + io = IOBuffer() + GAP.versioninfo(io, jll = true) + str = String(take!(io)) + @test startswith(str, "GAP.jl version") +end From 1e743714ff4a215aca5ac42c67e54de038064d41 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 8 Jan 2025 17:10:23 +0100 Subject: [PATCH 6/6] address more comments --- CHANGES.md | 1 + Project.toml | 2 +- src/GAP.jl | 4 ++-- test/basics.jl | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 341750ad..4301657e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,7 @@ - simpcomp - singular - zeromqinterface +- Add `GAP.versioninfo()` - Optimize conversion of GAP strings to Julia strings, symbols or `Vector{UInt8}` ## Version 0.12.3 (released 2025-01-01) diff --git a/Project.toml b/Project.toml index 21094639..56d515ee 100644 --- a/Project.toml +++ b/Project.toml @@ -58,7 +58,7 @@ nauty_jll = "55c6dc9b-343a-50ca-8ff2-b71adb3733d5" AbstractAlgebra = "0.41.11, 0.42.1, 0.43, 0.44" Artifacts = "1.6" BinaryWrappers = "0.1.3" -Compat = "4.4.0" +Compat = "4.11" Downloads = "1.4.3" GAP_jll = "~400.1400.000" GAP_lib_jll = "~400.1400.000" diff --git a/src/GAP.jl b/src/GAP.jl index a09fb859..c8b2d464 100644 --- a/src/GAP.jl +++ b/src/GAP.jl @@ -321,14 +321,14 @@ function randseed!(seed::Union{Integer,Nothing}=nothing) end """ - versioninfo(io::IO = stdout; jll::Bool = false) + versioninfo(io::IO = stdout; jll::Bool = false, full::Bool = false) Print the version numbers of GAP.jl and GAP, and version numbers and installation paths of all currently loaded GAP packages. Note that these paths can be nonstandard because Julia's package manager does not control which available version of a GAP package gets loaded. -If `jll` is `true` then also the underlying binary packages (jll), +If `jll` or `full` is `true` then also the underlying binary packages (jll), if available, of all installed (not necessarily loaded) packages are included in the output. """ diff --git a/test/basics.jl b/test/basics.jl index b6ceace3..cc6a756f 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -178,7 +178,7 @@ end @testset "versioninfo" begin io = IOBuffer() - GAP.versioninfo(io, jll = true) + GAP.versioninfo(io; full = true) str = String(take!(io)) @test startswith(str, "GAP.jl version") end