using Pkg using Pkg.TOML using LibGit2 const base = ["Base64", "CRC32c", "Dates", "DelimitedFiles", "Distributed", "FileWatching", "Future", "InteractiveUtils", "Libdl", "LibGit2", "LinearAlgebra", "Logging", "Markdown", "Mmap", "Pkg", "Printf", "Profile", "Random", "REPL", "Serialization", "SHA", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "SuiteSparse", "Test", "Unicode", "UUIDs"] const disabled = ["WinRPM", "Homebrew", "CMake", "Docile", "Color", "HTTPClient", "ICU", "Calendar", "LegacyStrings", "Nulls"] registrypath = expanduser("~/.julia-old/registries/General/") registry = joinpath(registrypath, "Registry.toml") const register = TOML.parse(join(readlines(registry), "\n")) jlpkgname(info) = "julia-$(lowercase(info.name))" function getrev(path) versions = TOML.parse(join(readlines(path), "\n")) versionv = findmax(map(x -> VersionNumber(x), keys(versions) |> collect)) (rev = versions[string(versionv[1])]["git-tree-sha1"], ver = versionv[1]) end function getpackagebyuuid(uuid) uuid in keys(register["packages"]) || return nothing path = register["packages"][uuid]["path"] getpath(x) = joinpath(registrypath, joinpath(path, x)) package = TOML.parse(join(readlines(getpath("Package.toml")), "\n")) deppath = getpath("Deps.toml") isfile(deppath) || return nothing deps = TOML.parse(join(readlines(deppath), "\n")) (name = package["name"], uuid = package["uuid"], repo = package["repo"], deps = deps, vers = getrev(getpath("Versions.toml"))) end function getpackage(wanted) uuid = findfirst(p -> lowercase(p["name"]) == lowercase(wanted), register["packages"]) uuid == nothing && return nothing return getpackagebyuuid(uuid) end function getdeps!(deps, vers, recursive, out) flat(arr::Array) = mapreduce(x -> isa(x, Array) ? flat(x) : x, append!, arr, init=[]) v = map(p -> VersionNumber.(split(p, '-')), keys(deps) |> collect) valid = findall(x -> length(x) == 1 || (x[2] == v"0" && x[1] <= vers) || x[1] <= vers <= x[2], v) f = flat(map(x -> values(x), values(collect(values(deps))[valid]))) push!.(Ref(out), f) # if recursive # push! # end nothing end function have(info) file = "/home/nixo/git/guix/gnu/packages/julia-xyz.scm" return "(name \"" * jlpkgname(info) * "\")" in strip.(readlines(file)) end function gethash(info) wd = mktempdir() if info.name in base || info.name in disabled || have(info) return "" end println(stderr, "Cloning $(info.name) in $wd") repo = LibGit2.clone(info.repo, wd) hash = cd(wd) do out = Pipe() try LibGit2.checkout!(repo, string(LibGit2.GitHash(LibGit2.peel(LibGit2.GitCommit, LibGit2.GitTag(repo, "v" * string(info.vers.ver)))))) catch e try LibGit2.checkout!(repo, string(LibGit2.GitHash(LibGit2.peel(LibGit2.GitCommit, LibGit2.GitCommit(repo, "v" * string(info.vers.ver)))))) catch e # FIXME: if this happens, return the commit too and use it in the package println(stderr, "Failed to checkout $(e), continuing") end end run(pipeline(`guix hash -rx .`, stdout=out)) readline(out) end rm(wd, recursive = true) hash end function makepackage(info; done = []) if info === nothing @warn "Could not find package (have you cloned the registry?)" return elseif info in done return "" end push!(done, info) deps = String[] getdeps!(info.deps, info.vers.ver, true, deps) # TODO: remove deps that are in base deps = filter(x -> x !== nothing, getpackagebyuuid.(deps)) deplist = join(map(name -> "(\"$name\" ,$name)", jlpkgname.(deps)), '\n') packagedeps = join(makepackage.(deps, done = done), "") hash = gethash(info) hash == "" && return "" """ $packagedeps (define-public $(jlpkgname(info)) (package (name "$(jlpkgname(info))") (version "$(info.vers.ver)") (source (origin (method git-fetch) (uri (git-reference (url "$(info.repo)") (commit (string-append "v" version)))) (file-name "$(info.name)") (sha256 (base32 "$hash")))) (propagated-inputs `($(deplist))) (build-system julia-build-system) (home-page "$(info.repo)") (synopsis "") (description "") (license license:expat))) """ end println.(makepackage.(getpackage.(ARGS)))