For those who wanted to know the details of how I generated the pull requests, here it is. It’s largely copy/pasted from MassInstallActions with as few changes as I had to make to get this to work. As the name MassInstallActions suggests, that package only handles pull request dealing with GitHub Actions. Ideally we’d refactor that package to support more general kinds of changes, but for now I just hacked the following up:
using GitHub, HTTP, Pkg
include("convertpc.jl")
const default_body = read("commitmsg.md", String)
function with_temp_dir(f::Function)
original_directory = pwd()
tmp_dir = mktempdir()
atexit(() -> rm(tmp_dir; force = true, recursive = true))
cd(tmp_dir)
result = f(tmp_dir)
cd(original_directory)
rm(tmp_dir; force = true, recursive = true)
return result
end
function git(f)
return f("git")
end
function migrate(repo::GitHub.Repo;
auth::GitHub.Authorization,
pr_branch_name::AbstractString = "teh/precompiletools",
pr_title::AbstractString = "Migrate from SnoopPrecompile to PrecompileTools",
pr_body::AbstractString = default_body,
commit_message::AbstractString = "Migrate from SnoopPrecompile to PrecompileTools",
pkg_url_type::Symbol = :html)
fk = GitHub.create_fork(repo; auth)
if pkg_url_type === :html
pkg_url_with_auth = fk.html_url.uri
elseif pkg_url_type === :ssh
pkg_url_with_auth = fk.ssh_url.uri
else
throw(ArgumentError("`pkg_url_type = $(pkg_url_type)` not supported"))
end
sleep(5)
with_temp_dir() do tmp_dir
git() do git
cd(tmp_dir) do
run(`$(git) clone $(pkg_url_with_auth) REPO`)
cd("REPO")
run(`$(git) checkout -B $(pr_branch_name)`)
if convert2pct(joinpath(tmp_dir, "REPO"))
run(`$(git) add -A`)
run(`$(git) commit -m $(commit_message)`)
# try
run(`$(git) push --force origin $(pr_branch_name)`)
# catch
# # try again?
# run(`$(git) push --force origin $(pr_branch_name)`)
# end
sleep(5)
params = Dict{String, String}()
params["title"] = pr_title
params["head"] = "timholy:" * pr_branch_name
params["base"] = repo.default_branch
params["body"] = pr_body
GitHub.create_pull_request(repo; params, auth)
@info "Pull request submitted for $(repo.name)"
end
end
end
end
return nothing
end
regs = Pkg.Registry.reachable_registries()
reg = only(filter(r -> r.name == "General", regs))
regpath = splitext(reg.path)[1]
toml = Pkg.TOML.parsefile(joinpath(regpath, "Registry.toml"))
pkgurls = String[]
for (uuid, data) in toml["packages"]
pkgpath = data["path"]
depfile = joinpath(regpath, pkgpath, "Deps.toml")
if isfile(depfile)
deps = read(depfile, String)
if occursin("SnoopPrecompile", deps)
pkgfile = joinpath(regpath, pkgpath, "Package.toml")
pkginfo = Pkg.TOML.parsefile(pkgfile)
url = splitext(pkginfo["repo"])[1]
push!(pkgurls, url)
end
end
end
sort!(pkgurls; by=name->splitpath(name)[end])
unique!(pkgurls)
# A chance to fix errors/edit the list. This was needed because the
# script didn't initially run to completion and I had to remove the ones already tackled
error("edit `pkgurls` to narrow the list of packages, then run the block below")
while !isempty(pkgurls)
url = pkgurls[end]
println(url)
repo = GitHub.repo(joinpath(splitpath(url)[3:end]...); auth)
migrate(repo; auth, pkg_url_type=:ssh)
pop!(pkgurls) # worked, delete from queue
println("\n\n")
end
convertpc.jl
is the script I posted in the OP, and commitmsg.md
was the message many of you received with the pull requests. auth
is a GitHub authentication token that you have to set up externally.