Merge pull request #33 from invenia/cdg/optional-git

Make Git stuff optional
This commit is contained in:
Chris de Graaf 2018-11-12 18:54:19 -06:00 committed by GitHub
commit 62702da431
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 61 deletions

View File

@ -47,7 +47,7 @@ t = Template(;
],
)
generate("MyPkg2", t)
run(`git -C $(joinpath(t.dir, "MyPkg2")) ls-tree -r --name-only HEAD`);
run(`git -C $(joinpath(t.dir, "MyPkg2")) ls-files`);
```
If that looks like a lot of work, you can also create templates interactively

View File

@ -71,7 +71,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
@ -127,7 +127,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@ -174,7 +174,7 @@ Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
@ -232,7 +232,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
@ -283,7 +283,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
@ -345,7 +345,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
@ -386,7 +386,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
@ -438,7 +438,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is

View File

@ -2,11 +2,12 @@
generate(pkg::AbstractString, t::Template) -> Nothing
generate(t::Template, pkg::AbstractString) -> Nothing
Generate a package named `pkg` from `t`.
Generate a package named `pkg` from `t`. If `git` is `false`, no Git repository is created.
"""
function generate(
pkg::AbstractString,
t::Template;
git::Bool=true,
gitconfig::Union{GitConfig, Nothing}=nothing,
)
pkg = splitjl(pkg)
@ -17,35 +18,37 @@ function generate(
# Create the directory with some boilerplate inside.
Pkg.generate(pkg_dir)
# Initialize the repo.
repo = LibGit2.init(pkg_dir)
@info "Initialized git repo at $pkg_dir"
if git
# Initialize the repo.
repo = LibGit2.init(pkg_dir)
@info "Initialized Git repo at $pkg_dir"
if gitconfig !== nothing
# Configure the repo.
repoconfig = GitConfig(repo)
for c in LibGit2.GitConfigIter(gitconfig)
LibGit2.set!(repoconfig, unsafe_string(c.name), unsafe_string(c.value))
if gitconfig !== nothing
# Configure the repo.
repoconfig = GitConfig(repo)
for c in LibGit2.GitConfigIter(gitconfig)
LibGit2.set!(repoconfig, unsafe_string(c.name), unsafe_string(c.value))
end
end
end
# Commit and set the remote.
LibGit2.commit(repo, "Initial commit")
rmt = if t.ssh
"git@$(t.host):$(t.user)/$pkg.jl.git"
else
"https://$(t.host)/$(t.user)/$pkg.jl"
end
# We need to set the remote in a strange way, see #8.
close(LibGit2.GitRemote(repo, "origin", rmt))
@info "Set remote origin to $rmt"
# Create the gh-pages branch if necessary.
if haskey(t.plugins, GitHubPages)
LibGit2.branch!(repo, "gh-pages")
# Commit and set the remote.
LibGit2.commit(repo, "Initial commit")
@info "Created empty gh-pages branch"
LibGit2.branch!(repo, "master")
rmt = if t.ssh
"git@$(t.host):$(t.user)/$pkg.jl.git"
else
"https://$(t.host)/$(t.user)/$pkg.jl"
end
# We need to set the remote in a strange way, see #8.
close(LibGit2.GitRemote(repo, "origin", rmt))
@info "Set remote origin to $rmt"
# Create the gh-pages branch if necessary.
if haskey(t.plugins, GitHubPages)
LibGit2.branch!(repo, "gh-pages")
LibGit2.commit(repo, "Initial commit")
@info "Created empty gh-pages branch"
LibGit2.branch!(repo, "master")
end
end
# Generate the files.
@ -54,21 +57,26 @@ function generate(
gen_tests(pkg_dir, t),
gen_require(pkg_dir, t),
gen_readme(pkg_dir, t),
gen_gitignore(pkg_dir, t),
gen_license(pkg_dir, t),
vcat(map(p -> gen_plugin(p, t, pkg), values(t.plugins))...),
)
LibGit2.add!(repo, files...)
LibGit2.commit(repo, "Files generated by PkgTemplates")
@info "Committed $(length(files)) files/directories: $(join(files, ", "))"
if git
append!(files, gen_gitignore(pkg_dir, t))
LibGit2.add!(repo, files...)
LibGit2.commit(repo, "Files generated by PkgTemplates")
@info "Committed $(length(files)) files/directories: $(join(files, ", "))"
if length(collect(LibGit2.GitBranchIter(repo))) > 1
@info "Remember to push all created branches to your remote: git push --all"
end
end
# Add the new package to the current environment.
Pkg.develop(PackageSpec(path=pkg_dir))
if length(collect(LibGit2.GitBranchIter(repo))) > 1
@info "Remember to push all created branches to your remote: git push --all"
end
@info "New package is at $pkg_dir"
catch e
rm(pkg_dir; recursive=true)
rethrow(e)
@ -78,13 +86,14 @@ end
function generate(
t::Template,
pkg::AbstractString;
git::Bool=true,
gitconfig::Union{GitConfig, Nothing}=nothing,
)
generate(pkg, t; gitconfig=gitconfig)
generate(pkg, t; git=git, gitconfig=gitconfig)
end
"""
generate_interactive(pkg::AbstractString; fast::Bool=false) -> Template
generate_interactive(pkg::AbstractString; fast::Bool=false, git::Bool=true) -> Template
Interactively create a template, and then generate a package with it. Arguments and
keywords are used in the same way as in [`generate`](@ref) and
@ -93,10 +102,11 @@ keywords are used in the same way as in [`generate`](@ref) and
function generate_interactive(
pkg::AbstractString;
fast::Bool=false,
git::Bool=true,
gitconfig::Union{GitConfig, Nothing}=nothing,
)
t = interactive_template(; fast=fast)
generate(pkg, t; gitconfig=gitconfig)
t = interactive_template(; git=git, fast=fast)
generate(pkg, t; git=git, gitconfig=gitconfig)
return t
end

View File

@ -47,11 +47,12 @@ create a template, you can use [`interactive_template`](@ref) instead.
ssh::Bool=false,
manifest::Bool=false,
plugins::Vector{<:Plugin}=Plugin[],
git::Bool=true,
)
# Check for required Git options for package generation
# (you can't commit to a repository without them).
isempty(LibGit2.getconfig("user.name", "")) && missingopt("user.name")
isempty(LibGit2.getconfig("user.email", "")) && missingopt("user.email")
git && isempty(LibGit2.getconfig("user.name", "")) && missingopt("user.name")
git && isempty(LibGit2.getconfig("user.email", "")) && missingopt("user.email")
# If no username was set, look for one in the global git config.
# Note: This is one of a few GitHub specifics (maybe we could use the host value).
@ -126,7 +127,7 @@ end
Interactively create a [`Template`](@ref). If `fast` is set, defaults will be assumed for
all values except username and plugins.
"""
function interactive_template(; fast::Bool=false)
function interactive_template(; git::Bool=true, fast::Bool=false)
@info "Default values are shown in [brackets]"
# Getting the leaf types in a separate thread eliminates an awkward wait after
# "Select plugins" is printed.
@ -144,8 +145,8 @@ function interactive_template(; fast::Bool=false)
throw(ArgumentError("Username is required"))
end
kwargs[:host] = if fast
"https://github.com"
kwargs[:host] = if fast || !git
"https://github.com" # If Git isn't enabled, this value never gets used.
else
default_host = "github.com"
print("Code hosting service [$default_host]: ")
@ -196,7 +197,7 @@ function interactive_template(; fast::Bool=false)
isempty(julia_version) ? default_julia_version : VersionNumber(julia_version)
end
kwargs[:ssh] = if fast
kwargs[:ssh] = if fast || !git
false
else
print("Set remote to SSH? [no]: ")
@ -218,7 +219,7 @@ function interactive_template(; fast::Bool=false)
selected = collect(request(menu))
kwargs[:plugins] = Vector{Plugin}(map(interactive, getindex(plugin_types, selected)))
return Template(; kwargs...)
return Template(; git=git, kwargs...)
end
leaves(T::Type)::Vector{DataType} = isconcretetype(T) ? [T] : vcat(leaves.(subtypes(T))...)

View File

@ -43,6 +43,13 @@
@test !t.manifest
@test isempty(t.plugins)
println()
# Host and SSH aren't prompted for when git is disabled.
write(stdin.buffer, "$me\n\n\r\n\n\nd")
t = interactive_template(; git=false)
@test t.host == "github.com"
@test !t.ssh
println()
end
@testset "Package generation" begin

View File

@ -27,14 +27,14 @@ const test_file = tempname()
const default_dir = Pkg.devdir()
const gitconfig = GitConfig(joinpath(@__DIR__, "gitconfig"))
const template_text = """
PKGNAME: {{PKGNAME}}
VERSION: {{VERSION}}}
{{#DOCUMENTER}}Documenter{{/DOCUMENTER}}
{{#CODECOV}}Codecov{{/CODECOV}}
{{#COVERALLS}}Coveralls{{/COVERALLS}}
{{#AFTER}}After{{/AFTER}}
{{#OTHER}}Other{{/OTHER}}
"""
PKGNAME: {{PKGNAME}}
VERSION: {{VERSION}}}
{{#DOCUMENTER}}Documenter{{/DOCUMENTER}}
{{#CODECOV}}Codecov{{/CODECOV}}
{{#COVERALLS}}Coveralls{{/COVERALLS}}
{{#AFTER}}After{{/AFTER}}
{{#OTHER}}Other{{/OTHER}}
"""
write(test_file, template_text)
@testset "Template creation" begin
@ -331,6 +331,19 @@ end
rm(temp_dir; recursive=true)
end
@testset "Git-less template creation" begin
if isempty(LibGit2.getconfig("user.name", ""))
@test_logs Template(; user=me, git=false)
end
end
@testset "Git-less package generation" begin
t = Template(; user=me)
generate(test_pkg, t; git=false)
@test !ispath(joinpath(t.dir, ".git"))
@test !isfile(joinpath(t.dir, ".gitignore"))
end
@testset "Version floor" begin
@test version_floor(v"1.0.0") == "1.0"
@test version_floor(v"1.0.1") == "1.0"