91 lines
3.1 KiB
Julia
91 lines
3.1 KiB
Julia
"""
|
|
Git(; ignore=String[], ssh=false, manifest=false, gpgsign=false)
|
|
|
|
Creates a Git repository and a `.gitignore` file.
|
|
|
|
## Keyword Arguments
|
|
- `ignore::Vector{<:AbstractString}`: Patterns to add to the `.gitignore`.
|
|
See also: [`gitignore`](@ref).
|
|
- `manifest::Bool`: Whether or not to commit `Manifest.toml`.
|
|
- `ssh::Bool`: Whether or not to use SSH for the remote.
|
|
If left unset, HTTPS is used.
|
|
- `gpgsign::Bool`: Whether or not to sign commits with your GPG key.
|
|
This option requires that the Git CLI is installed.
|
|
"""
|
|
@with_kw_noshow struct Git <: Plugin
|
|
ignore::Vector{String} = []
|
|
ssh::Bool = false
|
|
manifest::Bool = false
|
|
gpgsign::Bool = false
|
|
end
|
|
|
|
# Try to make sure that no files are created after we commit.
|
|
priority(::Git, ::typeof(posthook)) = 5
|
|
|
|
Base.:(==)(a::Git, b::Git) = all(map(n -> getfield(a, n) == getfield(b, n), fieldnames(Git)))
|
|
|
|
function gitignore(p::Git)
|
|
ignore = copy(p.ignore)
|
|
p.manifest || push!(ignore, "Manifest.toml")
|
|
return ignore
|
|
end
|
|
|
|
# Set up the Git repository.
|
|
function prehook(p::Git, t::Template, pkg_dir::AbstractString)
|
|
if p.gpgsign && try run(pipeline(`git --version`; stdout=devnull)); false catch; true end
|
|
throw(ArgumentError("Git: gpgsign is set but the Git CLI is not installed"))
|
|
end
|
|
LibGit2.with(LibGit2.init(pkg_dir)) do repo
|
|
commit(p, repo, pkg_dir, "Initial commit")
|
|
pkg = basename(pkg_dir)
|
|
url = if p.ssh
|
|
"git@$(t.host):$(t.user)/$pkg.jl.git"
|
|
else
|
|
"https://$(t.host)/$(t.user)/$pkg.jl"
|
|
end
|
|
LibGit2.with(GitRemote(repo, "origin", url)) do remote
|
|
# TODO: `git pull` still requires some Git branch config.
|
|
LibGit2.add_push!(repo, remote, "refs/heads/master")
|
|
end
|
|
end
|
|
end
|
|
|
|
# Create the .gitignore.
|
|
function hook(p::Git, t::Template, pkg_dir::AbstractString)
|
|
ignore = mapreduce(gitignore, append!, t.plugins)
|
|
# Only ignore manifests at the repo root.
|
|
p.manifest || "Manifest.toml" in ignore || push!(ignore, "/Manifest.toml")
|
|
unique!(sort!(ignore))
|
|
gen_file(joinpath(pkg_dir, ".gitignore"), join(ignore, "\n"))
|
|
end
|
|
|
|
# Commit the files.
|
|
function posthook(p::Git, ::Template, pkg_dir::AbstractString)
|
|
# Ensure that the manifest exists if it's going to be committed.
|
|
manifest = joinpath(pkg_dir, "Manifest.toml")
|
|
if p.manifest && !isfile(manifest)
|
|
touch(manifest)
|
|
with_project(Pkg.update, pkg_dir)
|
|
end
|
|
|
|
LibGit2.with(GitRepo(pkg_dir)) do repo
|
|
LibGit2.add!(repo, ".")
|
|
msg = "Files generated by PkgTemplates"
|
|
# TODO: Newer versions of Julia will not have Pkg.installed.
|
|
installed = Pkg.installed()
|
|
if haskey(installed, "PkgTemplates")
|
|
ver = string(installed["PkgTemplates"])
|
|
msg *= "\n\nPkgTemplates version: $ver"
|
|
end
|
|
commit(p, repo, pkg_dir, msg)
|
|
end
|
|
end
|
|
|
|
function commit(p::Git, repo::GitRepo, pkg_dir::AbstractString, msg::AbstractString)
|
|
if p.gpgsign
|
|
run(pipeline(`git -C $pkg_dir commit -S --allow-empty -m $msg`; stdout=devnull))
|
|
else
|
|
LibGit2.commit(repo, msg)
|
|
end
|
|
end
|