diff --git a/src/Oscar.jl b/src/Oscar.jl index b8ed02708a5a..1f983f0c7c87 100644 --- a/src/Oscar.jl +++ b/src/Oscar.jl @@ -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 diff --git a/src/Serialization/main.jl b/src/Serialization/main.jl index 63bdbdc4edf7..95dde799d91c 100644 --- a/src/Serialization/main.jl +++ b/src/Serialization/main.jl @@ -127,7 +127,6 @@ # the only parameter needed for such types is their parent. using JSON -using UUIDs include("serializers.jl") @@ -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] @@ -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 @@ -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) diff --git a/src/Serialization/upgrades/main.jl b/src/Serialization/upgrades/main.jl index 6525c4015c61..541f6e4b61c8 100644 --- a/src/Serialization/upgrades/main.jl +++ b/src/Serialization/upgrades/main.jl @@ -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 diff --git a/src/imports.jl b/src/imports.jl index ffde3fd5702f..3c52c0ff3907 100644 --- a/src/imports.jl +++ b/src/imports.jl @@ -2,6 +2,7 @@ using Pkg using Random using RandomExtensions +using UUIDs # our packages import AbstractAlgebra diff --git a/src/utils/versioninfo.jl b/src/utils/versioninfo.jl index eeb71af21ed5..df8494bcc608 100644 --- a/src/utils/versioninfo.jl +++ b/src/utils/versioninfo.jl @@ -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""" @@ -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