Skip to content

Commit

Permalink
versioninfo: refactor and use the same code for serialization (#2994)
Browse files Browse the repository at this point in the history
* versioninfo: refactor and use the same code for serialization

* serialization_version: fetch version on first use
  • Loading branch information
benlorenz authored Nov 5, 2023
1 parent 0f7269b commit 6fd21c5
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 69 deletions.
6 changes: 3 additions & 3 deletions src/Oscar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ end

const PROJECT_TOML = Pkg.TOML.parsefile(joinpath(@__DIR__, "..", "Project.toml"))
const VERSION_NUMBER = VersionNumber(PROJECT_TOML["version"])
const PROJECT_UUID = UUID(PROJECT_TOML["uuid"])

const is_dev = (function()
uuid = PROJECT_TOML["uuid"]
deps = Pkg.dependencies()
if Base.haskey(deps, uuid)
if deps[uuid].is_tracking_path
if Base.haskey(deps, PROJECT_UUID)
if deps[PROJECT_UUID].is_tracking_path
return true
end
end
Expand Down
16 changes: 9 additions & 7 deletions src/Serialization/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@
# the only parameter needed for such types is their parent.

using JSON
using UUIDs

include("serializers.jl")

Expand Down Expand Up @@ -163,10 +162,14 @@ function version_number(dict::Dict)
return VersionNumber(dict[:major], dict[:minor], dict[:patch])
end

function serialization_version_info()
const oscar_serialization_version = Ref{Dict{Symbol, Any}}()

function get_oscar_serialization_version()
if isassigned(oscar_serialization_version)
return oscar_serialization_version[]
end
if is_dev
path = Oscar.oscardir
commit_hash = readchomp(`git -C $path log -n 1 --pretty=format:"%H"`)
commit_hash = get(_get_oscar_git_info(), :commit, "unknown")
version_info = "$VERSION_NUMBER-$commit_hash"
result = Dict{Symbol, Any}(
:Oscar => ["https://github.com/oscar-system/Oscar.jl", version_info]
Expand All @@ -176,9 +179,8 @@ function serialization_version_info()
:Oscar => ["https://github.com/oscar-system/Oscar.jl", VERSION_NUMBER]
)
end
return result
return oscar_serialization_version[] = result
end
const oscar_serialization_version = serialization_version_info()

################################################################################
# (De|En)coding types
Expand Down Expand Up @@ -482,7 +484,7 @@ function save(io::IO, obj::T; metadata::Union{MetaData, Nothing}=nothing,
s = state(serializer_open(io, serializer_type))
save_data_dict(s) do
# write out the namespace first
save_header(s, oscar_serialization_version, :_ns)
save_header(s, get_oscar_serialization_version(), :_ns)

save_typed_object(s, obj)

Expand Down
2 changes: 1 addition & 1 deletion src/Serialization/upgrades/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ function upgrade(dict::Dict{Symbol, Any}, dict_version::VersionNumber)
upgraded_dict = upgrade_script(s, upgraded_dict)
end
end
upgraded_dict[:_ns] = oscar_serialization_version
upgraded_dict[:_ns] = get_oscar_serialization_version()
return upgraded_dict
end
1 change: 1 addition & 0 deletions src/imports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Pkg
using Random
using RandomExtensions
using UUIDs

# our packages
import AbstractAlgebra
Expand Down
141 changes: 83 additions & 58 deletions src/utils/versioninfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,77 @@
# In a bare repo HEAD will not point to the correct commit so we use the git
# tree-hash that Pkg.jl provides and manually map this to a corresponding
# commit.
function _lookup_commit_from_cache(url::AbstractString, tree::AbstractString)
if Sys.which("git") !== nothing
try
path = Pkg.Types.add_repo_cache_path(url)
if isdir(path)
commit = readchomp(`sh -c "git -C $path log --oneline --all --pretty='tree %T;%H' | grep \"^tree $tree\" | cut -d\; -f2 | head -n1"`)
return readchomp(`git -C $path show -s --format=", %h -- %ci" $commit`)
end
catch
function _lookup_commit_from_cache!(info::Dict, url::AbstractString, tree::AbstractString)
if Sys.which("git") !== nothing
try
path = Pkg.Types.add_repo_cache_path(url)
if isdir(path)
commit = readchomp(`sh -c "git -C $path log --oneline --all --pretty='tree %T;%H' | grep \"^tree $tree\" | cut -d\; -f2 | head -n1"`)
c = readchomp(`git -C $path show -s --format="%H#%ci" $commit`)
(info[:commit], info[:date]) = split(c, "#")
end
end
return ""
catch
end
end
end

function _lookup_git_branch(dir::AbstractString; commit=false)
info = ""
if Sys.which("git") !== nothing &&
isdir(joinpath(dir,".git"))
try
ref = readchomp(`git -C $dir rev-parse --abbrev-ref HEAD`)
info = " - #$(ref)"
if commit
c = readchomp(`git -C $dir show -s --format="%h -- %ci" HEAD`)
info = "$info, $c"
end
catch
end
end
return info
function _lookup_git_branch!(info::Dict, dir::AbstractString)
# the .git entry might be a file instead of a dir when using git worktrees
if Sys.which("git") !== nothing &&
ispath(joinpath(dir, ".git"))
try
ref = readchomp(`git -C $dir rev-parse --abbrev-ref HEAD`)
info[:branch] = ref
c = readchomp(`git -C $dir show -s --format="%H#%ci" HEAD`)
(info[:commit], info[:date]) = split(c, "#")
catch
end
end
end

function _get_git_info(dep::Union{Pkg.API.PackageInfo,AbstractString})
info = Dict{Symbol,String}()
if dep isa Pkg.API.PackageInfo && dep.is_tracking_repo
_lookup_commit_from_cache!(info, dep.git_source, dep.tree_hash)
# this might be a branch, tag, or commit hash
info[:branch] = dep.git_revision
elseif dep isa Pkg.API.PackageInfo && dep.is_tracking_path
_lookup_git_branch!(info, dep.source)
elseif dep isa AbstractString
_lookup_git_branch!(info, dep)
end
return info
end

function _get_oscar_git_info()
# Oscar is either one of the dependencies or the active project.
# For the active project we try to use the Oscar path as git directory.
oscarinfo = get(Pkg.dependencies(), PROJECT_UUID, Oscar.oscardir)
return _get_git_info(oscarinfo)
end

function _deps_git_info(dep::Pkg.API.PackageInfo; commit=false)
if dep.is_tracking_repo
info = commit ? _lookup_commit_from_cache(dep.git_source, dep.tree_hash) : ""
return " - #$(dep.git_revision)$info"
elseif dep.is_tracking_path
return _lookup_git_branch(dep.source; commit=commit)
end
return ""
function _format_git_info(info::Dict; branch=true, commit=false)
val = String[]
if branch && haskey(info, :branch)
push!(val, "#$(info[:branch])")
end
if commit && haskey(info, :commit)
push!(val, "$(info[:commit][1:10]) -- $(info[:date])")
end
return length(val) > 0 ? " - $(join(val, ", "))" : ""
end

function _print_dependency_versions(io::IO, deps::AbstractArray{<:AbstractString}; padding=" ", suffix="", branch=false, commit=false)
width = maximum(length.(deps))+length(suffix)+2
deps = filter(d->d.name in deps, collect(values(Pkg.dependencies())))
deps = sort!(deps; by=x->x.name)
for dep in deps
print(io, "$(padding)$(rpad(dep.name*suffix, width, ' ')) v$(dep.version)")
println(io, branch ? _deps_git_info(dep; commit=commit) : "")
end
width = maximum(length.(deps))+length(suffix)+2
deps = filter(d->d.name in deps, collect(values(Pkg.dependencies())))
deps = sort!(deps; by=x->x.name)
for dep in deps
print(io, "$(padding)$(rpad(dep.name*suffix, width, ' ')) v$(dep.version)")
if branch || commit
print(io, _format_git_info(_get_git_info(dep); branch=branch, commit=commit))
end
println(io)
end
end

@doc raw"""
Expand All @@ -67,22 +89,25 @@ Print the versions of all Oscar-related dependencies.
- `full::Bool=false` : include all of the above
"""
function versioninfo(io::IO=stdout; branch=false, jll=false, julia=false, commit=false, full=false)
if full
branch = jll = julia = commit = true
end
print(io, "OSCAR version $(VERSION_NUMBER)")
println(io, branch ? _lookup_git_branch(Oscar.oscardir; commit=commit) : "")
println(io, " combining:")
_print_dependency_versions(io, cornerstones; suffix=".jl", branch=branch, commit=commit)
if jll
println(io, " building on:")
_print_dependency_versions(io, jll_deps; branch=branch, commit=commit)
println(io, "See `]st -m` for a full list of dependencies.")
end
if julia
println(io, "")
Main.InteractiveUtils.versioninfo(io)
println(io, Base.TAGGED_RELEASE_BANNER)
end
if full
branch = jll = julia = commit = true
end
print(io, "OSCAR version $(VERSION_NUMBER)")
if branch || commit
print(io, _format_git_info(_get_oscar_git_info(); branch=branch, commit=commit))
end
println(io)
println(io, " combining:")
_print_dependency_versions(io, cornerstones; suffix=".jl", branch=branch, commit=commit)
if jll
println(io, " building on:")
_print_dependency_versions(io, jll_deps; branch=branch, commit=commit)
println(io, "See `]st -m` for a full list of dependencies.")
end
if julia
println(io, "")
Main.InteractiveUtils.versioninfo(io)
println(io, Base.TAGGED_RELEASE_BANNER)
end
end

0 comments on commit 6fd21c5

Please sign in to comment.