diff --git a/gap/OscarInterface/PackageInfo.g b/gap/OscarInterface/PackageInfo.g index a8d260166e0f..7dd69bbdf5e8 100644 --- a/gap/OscarInterface/PackageInfo.g +++ b/gap/OscarInterface/PackageInfo.g @@ -75,7 +75,10 @@ PackageDoc := rec( Dependencies := rec( GAP := ">= 4.12", - NeededOtherPackages := [ ["JuliaInterface", ">=0.9"] ], + NeededOtherPackages := [ + ["JuliaInterface", ">=0.9"], + ["Polycyclic", ">=2.16"], + ], SuggestedOtherPackages := [ ], ExternalConditions := [ ], ), diff --git a/src/Oscar.jl b/src/Oscar.jl index 87285f9abdf5..677cc5ed1335 100644 --- a/src/Oscar.jl +++ b/src/Oscar.jl @@ -50,7 +50,7 @@ function _print_banner(;is_dev = Oscar.is_dev) else version_string = "Version " * version_string end - + if displaysize(stdout)[2] >= 80 println( raw""" ___ ____ ____ _ ____ @@ -86,20 +86,25 @@ function __init__() # make Oscar module accessible from GAP (it may not be available as # `Julia.Oscar` if Oscar is loaded indirectly as a package dependency) GAP.Globals.BindGlobal(GapObj("Oscar"), Oscar) - GAP.Globals.SetPackagePath(GAP.Obj("OscarInterface"), GAP.Obj(joinpath(@__DIR__, "..", "gap", "OscarInterface"))) - GAP.Globals.LoadPackage(GAP.Obj("OscarInterface"), false) - withenv("TERMINFO_DIRS" => joinpath(GAP.GAP_jll.Readline_jll.Ncurses_jll.find_artifact_dir(), "share", "terminfo")) do - GAP.Packages.load("browse"; install=true) # needed for all_character_table_names doctest - end + + # Up to now, hopefully the GAP packages listed below have not been loaded. # We want newer versions of some GAP packages than the distributed ones. # (But we do not complain if the installation fails.) + for (url, branch) in [ + ("https://github.com/danielrademacher/recog.git", ""), + ] + GAP_Packages_install(url, interactive = false, branch = branch) + end for (pkg, version) in [ - ("recog", "1.4.2"), ("repsn", "3.1.1"), ] GAP.Packages.install(pkg, version, interactive = false, quiet = true) end - # We need some GAP packages. + + withenv("TERMINFO_DIRS" => joinpath(GAP.GAP_jll.Readline_jll.Ncurses_jll.find_artifact_dir(), "share", "terminfo")) do + GAP.Packages.load("browse"; install=true) # needed for all_character_table_names doctest + end + # We need some GAP packages (currently with unspecified versions). for pkg in [ "atlasrep", "ctbllib", # character tables @@ -123,6 +128,13 @@ function __init__() ] GAP.Packages.load(pkg) end + # Load the OscarInterface package in the end. + # It needs some other GAP packages, + # and is not needed by packages that can be loaded before Oscar. + GAP.Globals.SetPackagePath(GAP.Obj("OscarInterface"), GAP.Obj(joinpath(@__DIR__, "..", "gap", "OscarInterface"))) + GAP.Globals.LoadPackage(GAP.Obj("OscarInterface"), false) + # Switch off GAP's info messages, + # also those that are triggered from GAP packages. __GAP_info_messages_off() __init_group_libraries() diff --git a/src/utils/install.jl b/src/utils/install.jl new file mode 100644 index 000000000000..779eda10d2a9 --- /dev/null +++ b/src/utils/install.jl @@ -0,0 +1,58 @@ +# Install a GAP package via the URL of a GIT repository. +# If the package was already installed then update the installation, +# otherwise clone the repository. +# (The code is a modified copy of GAP's `InstallPackageFromGit`.) +function GAP_Packages_install(url::String; interactive::Bool = false, branch::String = "") + # point PackageManager to GAP.jl's pkg dir + GAP.Globals.PKGMAN_CustomPackageDir = GapObj(GAP.Packages.DEFAULT_PKGDIR[]) + # avoid info messages from PackageManager + GAP.Globals.SetInfoLevel(GAP.Globals.InfoPackageManager, 0) + + url = GapObj(url) + name = GAP.Globals.PKGMAN_NameOfGitRepo(url) + name === GAP.Globals.fail && return false + dir = GAP.Globals.Filename(GAP.Globals.Directory(GAP.Globals.PKGMAN_PackageDir()), name) + + # check for existing repository + allinfo = GAP.Globals.PackageInfo(name) + info = GAP.Globals.Filtered(allinfo, + x -> GAP.Globals.StartsWith(x.InstallationPath, GAP.Globals.PKGMAN_PackageDir())) + dirs = GAP.Globals.List(info, i -> i.InstallationPath) + repo = GAP.Globals.Filename(GAP.Globals.List(dirs, GAP.Globals.Directory), GapObj(".git")); + if repo !== GAP.Globals.fail + # the package is already installed, update it + return GAP.Globals.UpdatePackage(name, interactive) + end + + ! GAP.Globals.PKGMAN_IsValidTargetDir(dir) && return false + if branch == "" + exec = GAP.Globals.PKGMAN_Exec(GapObj("."), GapObj("git"), GapObj("clone"), url, dir) + else + exec = GAP.Globals.PKGMAN_Exec(GapObj("."), GapObj("git"), GapObj("clone"), url, dir, GapObj("-b"), GapObj(branch)) + end + + (exec === GAP.Globals.fail || exec.code != 0) && return false + GAP.Globals.PKGMAN_RefreshPackageInfo() + + # check for PackageInfo.g + info = GAP.Globals.Filename(GAP.Globals.Directory(dir), GapObj("PackageInfo.g")); + if ! GAP.Globals.IsReadableFile(info) + if GAP.Globals.ValueOption("debug") != true + GAP.Globals.PKGMAN_RemoveDir(dir) + end + return false + end + + # install dependencies + if GAP.Globals.PKGMAN_InstallDependencies(dir) != true + if GAP.Globals.ValueOption("debug") != true + GAP.Globals.PKGMAN_RemoveDir(dir) + end + return false + end + + # compile, make doc, and check +#TODO: build the documentation once PackageManager sets the right current directory, +# return GAP.Globals.PKGMAN_CheckPackage(dir) + return true +end diff --git a/src/utils/utils.jl b/src/utils/utils.jl index 942aa935bb9c..9712ca98b950 100644 --- a/src/utils/utils.jl +++ b/src/utils/utils.jl @@ -12,3 +12,4 @@ include("docs.jl") include("tests.jl") include("rand.jl") include("parallel.jl") +include("install.jl")