PkgTemplates.jl/src/plugins/git.jl
Chris de Graaf d53fb0b119
More docs!
2019-09-26 00:32:06 +07:00

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