Remove some not-very-useful features

Removed keywords to Template: years, requirements, and gitconfig.
This commit is contained in:
Chris de Graaf 2018-09-26 14:55:33 -05:00
parent b0a9844792
commit e2c615faf8
10 changed files with 109 additions and 288 deletions

View File

@ -1,5 +1,5 @@
""" """
generate(pkg_name::AbstractString, t::Template; ssh::Bool=false) -> Nothing generate(pkg_name::AbstractString, t::Template) -> Nothing
Generate a package named `pkg_name` from `t`. Generate a package named `pkg_name` from `t`.
""" """
@ -14,17 +14,10 @@ function generate(pkg_name::AbstractString, t::Template)
# Create the directory with some boilerplate inside. # Create the directory with some boilerplate inside.
Pkg.generate(pkg_dir) Pkg.generate(pkg_dir)
# Initialize the repo and configure it. # Initialize the repo.
repo = LibGit2.init(pkg_dir) repo = LibGit2.init(pkg_dir)
@info "Initialized git repo at $pkg_dir" @info "Initialized git repo at $pkg_dir"
LibGit2.with(LibGit2.GitConfig, repo) do cfg
for (key, val) in t.gitconfig
LibGit2.set!(cfg, key, val)
end
end
isempty(t.gitconfig) || @info "Applied git configuration"
LibGit2.commit(repo, "Initial commit") LibGit2.commit(repo, "Initial commit")
@info "Made empty initial commit"
rmt = if t.ssh rmt = if t.ssh
"git@$(t.host):$(t.user)/$pkg_name.jl.git" "git@$(t.host):$(t.user)/$pkg_name.jl.git"
else else
@ -54,13 +47,11 @@ function generate(pkg_name::AbstractString, t::Template)
) )
LibGit2.add!(repo, files...) LibGit2.add!(repo, files...)
@info "Staged $(length(files)) files/directories: $(join(files, ", "))"
LibGit2.commit(repo, "Files generated by PkgTemplates") LibGit2.commit(repo, "Files generated by PkgTemplates")
@info "Committed files generated by PkgTemplates" @info "Staged and committed $(length(files)) files/directories: $(join(files, ", "))"
multiple_branches = length(collect(LibGit2.GitBranchIter(repo))) > 1
@info "Finished" @info "Finished"
if multiple_branches if length(collect(LibGit2.GitBranchIter(repo))) > 1
@info "Remember to push all created branches to your remote: git push --all" @info "Remember to push all created branches to your remote: git push --all"
end end
catch e catch e
@ -69,33 +60,31 @@ function generate(pkg_name::AbstractString, t::Template)
end end
end end
function generate(t::Template, pkg_name::AbstractString) generate(t::Template, pkg_name::AbstractString) = generate(pkg_name, t)
generate(pkg_name, t)
end
""" """
generate_interactive(pkg_name::AbstractString; fast::Bool=false) -> Nothing generate_interactive(pkg::AbstractString; fast::Bool=false) -> Nothing
Interactively create a template, and then generate a package with it. Arguments and 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 keywords are used in the same way as in [`generate`](@ref) and
[`interactive_template`](@ref). [`interactive_template`](@ref).
""" """
function generate_interactive(pkg_name::AbstractString; fast::Bool=false) function generate_interactive(pkg::AbstractString; fast::Bool=false)
generate(pkg_name, interactive_template(; fast=fast)) generate(pkg, interactive_template(; fast=fast))
end end
""" """
gen_tests(pkg_dir::AbstractString, template::Template) -> Vector{String} gen_tests(pkg_dir::AbstractString, t::Template) -> Vector{String}
Create the test entrypoint in `pkg_dir`. Create the test entrypoint in `pkg_dir`.
# Arguments # Arguments
* `pkg_dir::AbstractString`: The package directory in which the files will be generated * `pkg_dir::AbstractString`: The package directory in which the files will be generated
* `template::Template`: The template whose tests we are generating. * `t::Template`: The template whose tests we are generating.
Returns an array of generated file/directory names. Returns an array of generated file/directory names.
""" """
function gen_tests(pkg_dir::AbstractString, template::Template) function gen_tests(pkg_dir::AbstractString, t::Template)
proj = Base.current_project() proj = Base.current_project()
try try
Pkg.activate(pkg_dir) Pkg.activate(pkg_dir)
@ -123,54 +112,52 @@ function gen_tests(pkg_dir::AbstractString, template::Template)
end end
""" """
gen_require(pkg_dir::AbstractString, template::Template) -> Vector{String} gen_require(pkg_dir::AbstractString, t::Template) -> Vector{String}
Create the `REQUIRE` file in `pkg_dir`. Create the `REQUIRE` file in `pkg_dir`.
# Arguments # Arguments
* `pkg_dir::AbstractString`: The directory in which the files will be generated. * `pkg_dir::AbstractString`: The directory in which the files will be generated.
* `template::Template`: The template whose REQUIRE we are generating. * `t::Template`: The template whose REQUIRE we are generating.
Returns an array of generated file/directory names. Returns an array of generated file/directory names.
""" """
function gen_require(pkg_dir::AbstractString, template::Template) function gen_require(pkg_dir::AbstractString, t::Template)
text = "julia $(version_floor(template.julia_version))\n" text = "julia $(version_floor(t.julia_version))\n"
text *= join(template.requirements, "\n")
gen_file(joinpath(pkg_dir, "REQUIRE"), text) gen_file(joinpath(pkg_dir, "REQUIRE"), text)
return ["REQUIRE"] return ["REQUIRE"]
end end
""" """
gen_readme(pkg_dir::AbstractString, template::Template) -> Vector{String} gen_readme(pkg_dir::AbstractString, t::Template) -> Vector{String}
Create a README in `pkg_dir` with badges for each enabled plugin. Create a README in `pkg_dir` with badges for each enabled plugin.
# Arguments # Arguments
* `pkg_dir::AbstractString`: The directory in which the files will be generated. * `pkg_dir::AbstractString`: The directory in which the files will be generated.
* `template::Template`: The template whose README we are generating. * `t::Template`: The template whose README we are generating.
Returns an array of generated file/directory names. Returns an array of generated file/directory names.
""" """
function gen_readme(pkg_dir::AbstractString, template::Template) function gen_readme(pkg_dir::AbstractString, t::Template)
pkg = basename(pkg_dir) pkg = basename(pkg_dir)
text = "# $pkg\n" text = "# $pkg\n"
done = [] done = []
# Generate the ordered badges first, then add any remaining ones to the right. # Generate the ordered badges first, then add any remaining ones to the right.
for plugin_type in BADGE_ORDER for plugin_type in BADGE_ORDER
if haskey(template.plugins, plugin_type) if haskey(t.plugins, plugin_type)
text *= "\n" text *= "\n"
text *= join( text *= join(
badges(template.plugins[plugin_type], template.user, pkg), badges(t.plugins[plugin_type], t.user, pkg),
"\n", "\n",
) )
push!(done, plugin_type) push!(done, plugin_type)
end end
end end
for plugin_type in setdiff(keys(template.plugins), done) for plugin_type in setdiff(keys(t.plugins), done)
text *= "\n" text *= "\n"
text *= join( text *= join(
badges(template.plugins[plugin_type], template.user, pkg), badges(t.plugins[plugin_type], t.user, pkg),
"\n", "\n",
) )
end end
@ -180,20 +167,20 @@ function gen_readme(pkg_dir::AbstractString, template::Template)
end end
""" """
gen_gitignore(pkg_dir::AbstractString, template::Template) -> Vector{String} gen_gitignore(pkg_dir::AbstractString, t::Template) -> Vector{String}
Create a `.gitignore` in `pkg_dir`. Create a `.gitignore` in `pkg_dir`.
# Arguments # Arguments
* `pkg_dir::AbstractString`: The directory in which the files will be generated. * `pkg_dir::AbstractString`: The directory in which the files will be generated.
* `template::Template`: The template whose .gitignore we are generating. * `t::Template`: The template whose .gitignore we are generating.
Returns an array of generated file/directory names. Returns an array of generated file/directory names.
""" """
function gen_gitignore(pkg_dir::AbstractString, template::Template) function gen_gitignore(pkg_dir::AbstractString, t::Template)
pkg = basename(pkg_dir) pkg = basename(pkg_dir)
seen = [".DS_Store"] seen = [".DS_Store"]
patterns = vcat(map(p -> p.gitignore, values(template.plugins))...) patterns = vcat(map(p -> p.gitignore, values(t.plugins))...)
for pattern in patterns for pattern in patterns
if !in(pattern, seen) if !in(pattern, seen)
push!(seen, pattern) push!(seen, pattern)
@ -206,23 +193,23 @@ function gen_gitignore(pkg_dir::AbstractString, template::Template)
end end
""" """
gen_license(pkg_dir::AbstractString, template::Template) -> Vector{String} gen_license(pkg_dir::AbstractString, t::Template) -> Vector{String}
Create a license in `pkg_dir`. Create a license in `pkg_dir`.
# Arguments # Arguments
* `pkg_dir::AbstractString`: The directory in which the files will be generated. * `pkg_dir::AbstractString`: The directory in which the files will be generated.
* `template::Template`: The template whose LICENSE we are generating. * `t::Template`: The template whose LICENSE we are generating.
Returns an array of generated file/directory names. Returns an array of generated file/directory names.
""" """
function gen_license(pkg_dir::AbstractString, template::Template) function gen_license(pkg_dir::AbstractString, t::Template)
if isempty(template.license) if isempty(t.license)
return String[] return String[]
end end
text = "Copyright (c) $(template.years) $(template.authors)\n" text = "Copyright (c) $(Dates.year(Dates.now())) $(t.authors)\n"
text *= read_license(template.license) text *= read_license(t.license)
gen_file(joinpath(pkg_dir, "LICENSE"), text) gen_file(joinpath(pkg_dir, "LICENSE"), text)
return ["LICENSE"] return ["LICENSE"]

View File

@ -12,34 +12,24 @@ Records common information used to generate a package. If you don't wish to manu
create a template, you can use [`interactive_template`](@ref) instead. create a template, you can use [`interactive_template`](@ref) instead.
# Keyword Arguments # Keyword Arguments
* `user::AbstractString=""`: GitHub username. If left unset, it will try to take the * `user::AbstractString=""`: GitHub (or other code hosting service) username. If left
value of a supplied git config's "github.user" key, then the global git config's unset, it will take the the global git config's value. If that is not set, an
value. If neither is set, an `ArgumentError` is thrown. `ArgumentError` is thrown. **This is case-sensitive for some plugins, so take care to
**This is case-sensitive for some plugins, so take care to enter it correctly.** enter it correctly.**
* `host::AbstractString="github.com"`: URL to the code hosting service where your package * `host::AbstractString="github.com"`: URL to the code hosting service where your package
will reside. Note that while hosts other than GitHub won't cause errors, they are not will reside. Note that while hosts other than GitHub won't cause errors, they are not
officially supported and they will cause certain plugins will produce incorrect output. officially supported and they will cause certain plugins will produce incorrect output.
For example, [`AppVeyor`](@ref)'s badge image will point to a GitHub-specific URL,
regardless of the value of `host`.
* `license::AbstractString="MIT"`: Name of the package license. If an empty string is * `license::AbstractString="MIT"`: Name of the package license. If an empty string is
given, no license is created. [`available_licenses`](@ref) can be used to list all given, no license is created. [`available_licenses`](@ref) can be used to list all
available licenses, and [`show_license`](@ref) can be used to print out a particular available licenses, and [`show_license`](@ref) can be used to print out a particular
license's text. license's text.
* `authors::Union{AbstractString, Vector{<:AbstractString}}=""`: Names that appear on the * `authors::Union{AbstractString, Vector{<:AbstractString}}=""`: Names that appear on the
license. Supply a string for one author or an array for multiple. Similarly to `user`, license. Supply a string for one author or an array for multiple. Similarly to `user`,
it will try to take the value of a supplied git config's "user.name" key, then the global it will take the value of of the global git config's value if it is left unset.
git config's value, if it is left unset.
* `years::Union{Integer, AbstractString}=$(Dates.year(Dates.today()))`: Copyright years on
the license. Can be supplied by a number, or a string such as "2016 - 2017".
* `dir::AbstractString=$(dev_dir())`: Directory in which the package will go. Relative * `dir::AbstractString=$(dev_dir())`: Directory in which the package will go. Relative
paths are converted to absolute ones at template creation time. paths are converted to absolute ones at template creation time.
* `julia_version::VersionNumber=VERSION`: Minimum allowed Julia version. * `julia_version::VersionNumber=VERSION`: Minimum allowed Julia version.
* `ssh::Bool=false`: Whether or not to use SSH for the remote. * `ssh::Bool=false`: Whether or not to use SSH for the remote.
* `requirements::Vector{<:AbstractString}=String[]`: Package requirements. If there are
duplicate requirements with different versions, i.e. ["PkgTemplates", "PkgTemplates
0.1"], an `ArgumentError` is thrown. Each entry in this array will be copied into the
`REQUIRE` file of packages generated with this template.
* `gitconfig::Dict=Dict()`: Git configuration options.
* `plugins::Vector{<:Plugin}=Plugin[]`: A list of `Plugin`s that the package will include. * `plugins::Vector{<:Plugin}=Plugin[]`: A list of `Plugin`s that the package will include.
""" """
@auto_hash_equals struct Template @auto_hash_equals struct Template
@ -47,12 +37,9 @@ create a template, you can use [`interactive_template`](@ref) instead.
host::AbstractString host::AbstractString
license::AbstractString license::AbstractString
authors::AbstractString authors::AbstractString
years::AbstractString
dir::AbstractString dir::AbstractString
julia_version::VersionNumber julia_version::VersionNumber
ssh::Bool ssh::Bool
requirements::Vector{AbstractString}
gitconfig::Dict
plugins::Dict{DataType, Plugin} plugins::Dict{DataType, Plugin}
function Template(; function Template(;
@ -60,18 +47,24 @@ create a template, you can use [`interactive_template`](@ref) instead.
host::AbstractString="https://github.com", host::AbstractString="https://github.com",
license::AbstractString="MIT", license::AbstractString="MIT",
authors::Union{AbstractString, Vector{<:AbstractString}}="", authors::Union{AbstractString, Vector{<:AbstractString}}="",
years::Union{Integer, AbstractString}=Dates.year(Dates.today()),
dir::AbstractString=dev_dir(), dir::AbstractString=dev_dir(),
julia_version::VersionNumber=VERSION, julia_version::VersionNumber=VERSION,
ssh::Bool=false, ssh::Bool=false,
requirements::Vector{<:AbstractString}=String[],
gitconfig::Dict=Dict(),
plugins::Vector{<:Plugin}=Plugin[], plugins::Vector{<:Plugin}=Plugin[],
) )
# If no username was set, look for one in a supplied git config, # Check for required Git options for package generation
# and then in the global git config. # (you can't commit to a repository without them).
if isempty(LibGit2.getconfig("user.name", ""))
@warn "Git config option 'user.name' missing, package generation will fail"
end
if isempty(LibGit2.getconfig("user.email", ""))
@warn "Git config option 'user.email' missing, package generation will fail"
end
# If no username was set, look for one in the global git config.
# Note: This is one of a few GitHub specifics.
if isempty(user) if isempty(user)
user = get(gitconfig, "github.user", LibGit2.getconfig("github.user", "")) user = LibGit2.getconfig("github.user", "")
end end
if isempty(user) if isempty(user)
throw(ArgumentError("No GitHub username found, set one with user=username")) throw(ArgumentError("No GitHub username found, set one with user=username"))
@ -83,80 +76,43 @@ create a template, you can use [`interactive_template`](@ref) instead.
throw(ArgumentError("License '$license' is not available")) throw(ArgumentError("License '$license' is not available"))
end end
# If no author was set, look for one in the supplied git config, # If no author was set, look for one in the global git config.
# and then in the global git config.
if isempty(authors) if isempty(authors)
authors = get(gitconfig, "user.name", LibGit2.getconfig("user.name", "")) authors = LibGit2.getconfig("user.name", "")
elseif isa(authors, Vector) elseif isa(authors, Vector)
authors = join(authors, ", ") authors = join(authors, ", ")
end end
years = string(years)
dir = abspath(expanduser(dir)) dir = abspath(expanduser(dir))
requirements_dedup = collect(Set(requirements))
diff = length(requirements) - length(requirements_dedup)
names = map(t -> first(t), split.(requirements_dedup))
if length(names) > length(Set(names))
throw(ArgumentError(
"requirements contains duplicate packages with conflicting versions"
))
elseif diff > 0
@warn "Removed $(diff) duplicate$(diff == 1 ? "" : "s") from requirements"
end
plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins) plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins)
if (length(plugins) != length(plugin_dict)) if (length(plugins) != length(plugin_dict))
@warn "Plugin list contained duplicates, only the last of each type was kept" @warn "Plugin list contained duplicates, only the last of each type was kept"
end end
new( new(user, host, license, authors, dir, julia_version, ssh, plugin_dict)
user, host, license, authors, years, dir, julia_version, ssh,
requirements_dedup, gitconfig, plugin_dict,
)
end end
end end
function Base.show(io::IO, t::Template) function Base.show(io::IO, t::Template)
maybe_none(s::AbstractString) = isempty(string(s)) ? "None" : string(s) maybe(s::AbstractString) = isempty(string(s)) ? "None" : string(s)
spc = " " spc = " "
println(io, "Template:") println(io, "Template:")
println(io, "$spc→ User: $(maybe_none(t.user))") println(io, "$spc→ User: $(maybe(t.user))")
println(io, "$spc→ Host: $(maybe_none(t.host))") println(io, "$spc→ Host: $(maybe(t.host))")
print(io, "$spc→ License: ") print(io, "$spc→ License: ")
if isempty(t.license) if isempty(t.license)
println(io, "None") println(io, "None")
else else
println(io, "$(t.license) ($(t.authors) $(t.years))") println(io, "$(t.license) ($(t.authors) $(Dates.year(Dates.now())))")
end end
println(io, "$spc→ Package directory: $(replace(maybe_none(t.dir), homedir() => "~"))") println(io, "$spc→ Package directory: $(replace(maybe(t.dir), homedir() => "~"))")
println(io, "$spc→ Minimum Julia version: v$(version_floor(t.julia_version))") println(io, "$spc→ Minimum Julia version: v$(version_floor(t.julia_version))")
println(io, "$spc→ SSH remote: $(t.ssh ? "Yes" : "No")") println(io, "$spc→ SSH remote: $(t.ssh ? "Yes" : "No")")
n = length(t.requirements)
s = n == 1 ? "" : "s"
print(io, "$spc→ $n package requirement$s")
if isempty(t.requirements)
println(io)
else
println(io, ": $(join(t.requirements, ", "))")
end
print(io, "$spc→ Git configuration options:")
if isempty(t.gitconfig)
println(io, " None")
else
println(io)
for k in sort(collect(keys(t.gitconfig)); by=string)
println(io, "$(spc^2)$k = $(t.gitconfig[k])")
end
end
print(io, "$spc→ Plugins:") print(io, "$spc→ Plugins:")
if isempty(t.plugins) if isempty(t.plugins)
print(io, " None") print(io, " None")
@ -214,12 +170,11 @@ function interactive_template(; fast::Bool=false)
menu = RadioMenu(String["None", split(String(take!(io)), "\n")...]) menu = RadioMenu(String["None", split(String(take!(io)), "\n")...])
# If the user breaks out of the menu with Ctrl-c, the result is -1, the absolute # If the user breaks out of the menu with Ctrl-c, the result is -1, the absolute
# value of which correponds to no license. # value of which correponds to no license.
licenses[abs(request(menu))].first first(licenses[abs(request(menu))])
end end
# We don't need to ask for authors or copyright years if there is no license, # We don't need to ask for authors if there is no license,
# because the license is the only place that they matter. # because the license is the only place that they matter.
kwargs[:authors] = if fast || isempty(kwargs[:license]) kwargs[:authors] = if fast || isempty(kwargs[:license])
LibGit2.getconfig("user.name", "") LibGit2.getconfig("user.name", "")
else else
@ -230,15 +185,6 @@ function interactive_template(; fast::Bool=false)
isempty(authors) ? default_authors : authors isempty(authors) ? default_authors : authors
end end
kwargs[:years] = if fast || isempty(kwargs[:license])
Dates.year(Dates.today())
else
default_years = Dates.year(Dates.today())
print("Enter the copyright year(s) [$default_years]: ")
years = readline()
isempty(years) ? default_years : years
end
kwargs[:dir] = if fast kwargs[:dir] = if fast
dev_dir() dev_dir()
else else
@ -264,30 +210,6 @@ function interactive_template(; fast::Bool=false)
in(uppercase(readline()), ["Y", "YES", "T", "TRUE"]) in(uppercase(readline()), ["Y", "YES", "T", "TRUE"])
end end
kwargs[:requirements] = if fast
String[]
else
print("Enter any Julia package requirements, (separated by spaces) []: ")
String.(split(readline()))
end
kwargs[:gitconfig] = if fast
Dict()
else
gitconfig = Dict()
print("Enter any Git key-value pairs (one per line, separated by spaces) [None]: ")
while true
line = readline()
isempty(line) && break
tokens = split(line, " ", limit=2)
if haskey(gitconfig, tokens[1])
@warn "Duplicate key '$(tokens[1])': Replacing old value '$(tokens[2])'"
end
gitconfig[tokens[1]] = tokens[2]
end
gitconfig
end
println("Select plugins:") println("Select plugins:")
# Only include plugin types which have an `interactive` method. # Only include plugin types which have an `interactive` method.
plugin_types = filter(t -> hasmethod(interactive, (Type{t},)), fetch(plugin_types)) plugin_types = filter(t -> hasmethod(interactive, (Type{t},)), fetch(plugin_types))

View File

@ -7,18 +7,15 @@
# Therefore, we skip any interactive tests on OSX builds. # Therefore, we skip any interactive tests on OSX builds.
@testset "Interactive template creation" begin @testset "Interactive template creation" begin
write(stdin.buffer, "$me\n\n\r\n\n\n\n\nd") write(stdin.buffer, "$me\n\n\r\n\n\nd")
t = interactive_template() t = interactive_template()
@test t.user == me @test t.user == me
@test t.host == "github.com" @test t.host == "github.com"
@test isempty(t.license) @test isempty(t.license)
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
@test t.years == string(Dates.year(Dates.today()))
@test t.dir == default_dir @test t.dir == default_dir
@test t.julia_version == VERSION @test t.julia_version == VERSION
@test !t.ssh @test !t.ssh
@test isempty(t.requirements)
@test isempty(t.gitconfig)
@test isempty(t.plugins) @test isempty(t.plugins)
if isempty(LibGit2.getconfig("github.user", "")) if isempty(LibGit2.getconfig("github.user", ""))
@ -26,46 +23,35 @@
@test_throws ArgumentError t = interactive_template() @test_throws ArgumentError t = interactive_template()
end end
write(stdin.buffer, "$me\ngitlab.com\n$('\x1b')[B\r$me\n2016\n$test_file\n0.5\nyes\nX Y\nkey val val\nkey2 val2\n\n$('\x1b')[B\r$('\x1b')[B\rd\n\n") down = '\x1b' * "[B" # Down array key.
write(stdin.buffer, "$me\ngitlab.com\n$down\r$me\n$test_file\n0.5\nyes\n$down\r$down\rd\n\n")
t = interactive_template() t = interactive_template()
@test t.user == me @test t.user == me
@test t.host == "gitlab.com" @test t.host == "gitlab.com"
# Not sure if the order the licenses are displayed in is consistent. # Not sure if the order the licenses are displayed in is consistent.
@test !isempty(t.license) @test !isempty(t.license)
@test t.authors == me @test t.authors == me
@test t.years == "2016"
@test t.dir == abspath(test_file) @test t.dir == abspath(test_file)
@test t.julia_version == v"0.5.0" @test t.julia_version == v"0.5.0"
@test t.ssh @test t.ssh
@test Set(t.requirements) == Set(["X", "Y"])
@test t.gitconfig == Dict("key" => "val val", "key2" => "val2")
# Like above, not sure which plugins this will generate. # Like above, not sure which plugins this will generate.
@test length(t.plugins) == 2 @test length(t.plugins) == 2
# TODO: What is this supposed to warn about?
write(stdin.buffer, "$me\n\n\r\n\nA B\nA B\n\nd")
@test_logs (:warn, r".+") match_mode=:any interactive_template()
write(stdin.buffer, "$me\nd") write(stdin.buffer, "$me\nd")
t = interactive_template(; fast=true) t = interactive_template(; fast=true)
@test t.user == me @test t.user == me
@test t.host == "github.com" @test t.host == "github.com"
@test t.license == "MIT" @test t.license == "MIT"
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
# I guess this could technically break if it runs on New Year's Eve...
@test t.years == string(Dates.year(Dates.today()))
@test t.dir == default_dir @test t.dir == default_dir
@test t.julia_version == VERSION @test t.julia_version == VERSION
@test !t.ssh @test !t.ssh
@test isempty(t.requirements)
@test isempty(t.gitconfig)
@test isempty(t.plugins) @test isempty(t.plugins)
println() println()
end end
@testset "Interactive package generation" begin @testset "Interactive package generation" begin
cfg = join(("$k $v" for (k, v) in gitconfig), "\n") write(stdin.buffer, "$me\n\n\r\n\n\n\n\n\nd")
write(stdin.buffer, "$me\n\n\r\n\n\n\n$cfg\n\nd")
generate_interactive(test_pkg) generate_interactive(test_pkg)
@test isdir(joinpath(default_dir, test_pkg)) @test isdir(joinpath(default_dir, test_pkg))
rm(joinpath(default_dir, test_pkg); force=true, recursive=true) rm(joinpath(default_dir, test_pkg); force=true, recursive=true)

View File

@ -1,4 +1,3 @@
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -26,7 +25,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Badge generation" begin @testset "Badge generation" begin
p = AppVeyor() p = AppVeyor()
@test badges(p, user, test_pkg) == ["[![Build Status](https://ci.appveyor.com/api/projects/status/github/$user/$test_pkg.jl?svg=true)](https://ci.appveyor.com/project/$user/$test_pkg-jl)"] @test badges(p, me, test_pkg) == ["[![Build Status](https://ci.appveyor.com/api/projects/status/github/$me/$test_pkg.jl?svg=true)](https://ci.appveyor.com/project/$me/$test_pkg-jl)"]
end end
@testset "File generation" begin @testset "File generation" begin

View File

@ -1,4 +1,3 @@
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -26,7 +25,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Badge generation" begin @testset "Badge generation" begin
p = CodeCov() p = CodeCov()
@test badges(p, user, test_pkg) == ["[![CodeCov](https://codecov.io/gh/$user/$test_pkg.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/$user/$test_pkg.jl)"] @test badges(p, me, test_pkg) == ["[![CodeCov](https://codecov.io/gh/$me/$test_pkg.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/$me/$test_pkg.jl)"]
end end
@testset "File generation" begin @testset "File generation" begin

View File

@ -1,4 +1,3 @@
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -26,7 +25,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Badge generation" begin @testset "Badge generation" begin
p = Coveralls() p = Coveralls()
@test badges(p, user, test_pkg) == ["[![Coveralls](https://coveralls.io/repos/github/$user/$test_pkg.jl/badge.svg?branch=master)](https://coveralls.io/github/$user/$test_pkg.jl?branch=master)"] @test badges(p, me, test_pkg) == ["[![Coveralls](https://coveralls.io/repos/github/$me/$test_pkg.jl/badge.svg?branch=master)](https://coveralls.io/github/$me/$test_pkg.jl?branch=master)"]
end end
@testset "File generation" begin @testset "File generation" begin

View File

@ -1,4 +1,3 @@
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -15,9 +14,9 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Badge generation" begin @testset "Badge generation" begin
p = GitHubPages() p = GitHubPages()
@test badges(p, user, test_pkg) == [ @test badges(p, me, test_pkg) == [
"[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$user.github.io/$test_pkg.jl/stable)" "[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$me.github.io/$test_pkg.jl/stable)"
"[![Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://$user.github.io/$test_pkg.jl/latest)" "[![Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://$me.github.io/$test_pkg.jl/latest)"
] ]
end end
@ -54,6 +53,23 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@test occursin("deploydocs", make) @test occursin("deploydocs", make)
rm(joinpath(pkg_dir, "docs"); recursive=true) rm(joinpath(pkg_dir, "docs"); recursive=true)
end end
@testset "Package generation with GitHubPages plugin" begin
t = Template(; user=me, plugins=[GitHubPages()])
generate(test_pkg, t)
pkg_dir = joinpath(default_dir, test_pkg)
# Check that the gh-pages branch exists.
repo = LibGit2.GitRepo(pkg_dir)
branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo))
@test in("gh-pages", branches)
# Check that the generated docs root is just the copied README.
readme = read(joinpath(pkg_dir, "README.md"), String)
index = read(joinpath(pkg_dir, "docs", "src", "index.md"), String)
@test readme == index
rm(pkg_dir; recursive=true)
end
end end
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)

View File

@ -1,4 +1,3 @@
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -40,9 +39,9 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Badge generation" begin @testset "Badge generation" begin
p = GitLabCI() p = GitLabCI()
@test badges(p, user, test_pkg) == [ @test badges(p, me, test_pkg) == [
"[![Build Status](https://gitlab.com/$user/$test_pkg.jl/badges/master/build.svg)](https://gitlab.com/$user/$test_pkg.jl/pipelines)", "[![Build Status](https://gitlab.com/$me/$test_pkg.jl/badges/master/build.svg)](https://gitlab.com/$me/$test_pkg.jl/pipelines)",
"[![Coverage](https://gitlab.com/$user/$test_pkg.jl/badges/master/coverage.svg)](https://gitlab.com/$user/$test_pkg.jl/commits/master)", "[![Coverage](https://gitlab.com/$me/$test_pkg.jl/badges/master/coverage.svg)](https://gitlab.com/$me/$test_pkg.jl/commits/master)",
] ]
end end

View File

@ -1,4 +1,3 @@
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -26,7 +25,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Badge generation" begin @testset "Badge generation" begin
p = TravisCI() p = TravisCI()
@test badges(p, user, test_pkg) == ["[![Build Status](https://travis-ci.com/$user/$test_pkg.jl.svg?branch=master)](https://travis-ci.com/$user/$test_pkg.jl)"] @test badges(p, me, test_pkg) == ["[![Build Status](https://travis-ci.com/$me/$test_pkg.jl.svg?branch=master)](https://travis-ci.com/$me/$test_pkg.jl)"]
end end
@testset "File generation" begin @testset "File generation" begin

View File

@ -16,13 +16,8 @@ struct Baz <: Plugin end
# Various options to be passed into templates. # Various options to be passed into templates.
const me = "christopher-dG" const me = "christopher-dG"
const gitconfig = Dict(
"user.name" => "Tester McTestFace",
"user.email" => "email@web.site",
"github.user" => "TesterMcTestFace",
)
const test_pkg = "TestPkg" const test_pkg = "TestPkg"
const fake_path = string(hash("/this/file/does/not/exist"); base=2) const fake_path = "/dev/null/this/file/does/not/exist"
const test_file = tempname() const test_file = tempname()
const default_dir = PkgTemplates.dev_dir() const default_dir = PkgTemplates.dev_dir()
const template_text = """ const template_text = """
@ -41,11 +36,9 @@ write(test_file, template_text)
t = Template(; user=me) t = Template(; user=me)
@test t.user == me @test t.user == me
@test t.license == "MIT" @test t.license == "MIT"
@test t.years == string(Dates.year(Dates.today()))
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
@test t.dir == default_dir @test t.dir == default_dir
@test t.julia_version == VERSION @test t.julia_version == VERSION
@test isempty(t.gitconfig)
@test isempty(t.plugins) @test isempty(t.plugins)
# Checking non-default field assignments. # Checking non-default field assignments.
@ -56,14 +49,8 @@ write(test_file, template_text)
t = Template(; user=me, license="MPL") t = Template(; user=me, license="MPL")
@test t.license == "MPL" @test t.license == "MPL"
t = Template(; user=me, years=2014)
@test t.years == "2014"
t = Template(user=me, years="2014-2015")
@test t.years == "2014-2015"
t = Template(; user=me, authors="Some Guy") t = Template(; user=me, authors="Some Guy")
@test t.authors == "Some Guy" @test t.authors == "Some Guy"
# Vectors of authors should be comma-joined. # Vectors of authors should be comma-joined.
t = Template(; user=me, authors=["Guy", "Gal"]) t = Template(; user=me, authors=["Guy", "Gal"])
@test t.authors == "Guy, Gal" @test t.authors == "Guy, Gal"
@ -79,30 +66,6 @@ write(test_file, template_text)
t = Template(; user=me, julia_version=v"0.1.2") t = Template(; user=me, julia_version=v"0.1.2")
@test t.julia_version == v"0.1.2" @test t.julia_version == v"0.1.2"
t = Template(; user=me, requirements=["$test_pkg 0.1"])
@test t.requirements == ["$test_pkg 0.1"]
# Duplicate requirements should warn.
@test_logs (:warn, r".+") t = Template(; user=me, requirements=[test_pkg, test_pkg])
@test t.requirements == [test_pkg]
# Duplicate requirements with non-matching versions should throw.
@test_throws ArgumentError Template(;
user=me,
requirements=[test_pkg, "$test_pkg 0.1"]
)
t = Template(; user=me, gitconfig=gitconfig)
@test t.gitconfig == gitconfig
# Git options should be used as fallbacks for template user and authors.
# But an explicitly passed username trumps the gitconfig.
t = Template(; user=me, gitconfig=gitconfig)
@test t.authors == gitconfig["user.name"]
t = Template(; gitconfig=gitconfig)
@test t.user == gitconfig["github.user"]
@test t.authors == gitconfig["user.name"]
# The template should contain whatever plugins you give it. # The template should contain whatever plugins you give it.
t = Template(; t = Template(;
user=me, user=me,
@ -144,31 +107,24 @@ end
@testset "Show methods" begin @testset "Show methods" begin
pkg_dir = replace(default_dir, homedir() => "~") pkg_dir = replace(default_dir, homedir() => "~")
buf = IOBuffer() buf = IOBuffer()
t = Template(; user=me, gitconfig=gitconfig) t = Template(; user=me)
show(buf, t) show(buf, t)
text = String(take!(buf)) text = String(take!(buf))
expected = """ expected = """
Template: Template:
User: $me User: $me
Host: github.com Host: github.com
License: MIT ($(gitconfig["user.name"]) $(Dates.year(now()))) License: MIT ($(LibGit2.getconfig("user.name", "")) $(Dates.year(now())))
Package directory: $pkg_dir Package directory: $pkg_dir
Minimum Julia version: v$(PkgTemplates.version_floor()) Minimum Julia version: v$(PkgTemplates.version_floor())
SSH remote: No SSH remote: No
0 package requirements
Git configuration options:
github.user = $(gitconfig["github.user"])
user.email = $(gitconfig["user.email"])
user.name = $(gitconfig["user.name"])
Plugins: None Plugins: None
""" """
@test text == rstrip(expected) @test text == rstrip(expected)
t = Template( t = Template(
user=me, user=me,
license="", license="",
requirements=["Foo", "Bar"],
ssh=true, ssh=true,
gitconfig=gitconfig,
plugins=[ plugins=[
TravisCI(), TravisCI(),
CodeCov(), CodeCov(),
@ -185,11 +141,6 @@ end
Package directory: $pkg_dir Package directory: $pkg_dir
Minimum Julia version: v$(PkgTemplates.version_floor()) Minimum Julia version: v$(PkgTemplates.version_floor())
SSH remote: Yes SSH remote: Yes
2 package requirements: Bar, Foo
Git configuration options:
github.user = $(gitconfig["github.user"])
user.email = $(gitconfig["user.email"])
user.name = $(gitconfig["user.name"])
Plugins: Plugins:
CodeCov: CodeCov:
Config file: None Config file: None
@ -208,8 +159,6 @@ end
t = Template(; t = Template(;
user=me, user=me,
license="MPL", license="MPL",
requirements=[test_pkg],
gitconfig=gitconfig,
plugins=[Coveralls(), TravisCI(), CodeCov(), GitHubPages(), AppVeyor()], plugins=[Coveralls(), TravisCI(), CodeCov(), GitHubPages(), AppVeyor()],
) )
temp_dir = mktempdir() temp_dir = mktempdir()
@ -264,30 +213,32 @@ end
license = readchomp(joinpath(pkg_dir, "LICENSE")) license = readchomp(joinpath(pkg_dir, "LICENSE"))
rm(joinpath(pkg_dir, "LICENSE")) rm(joinpath(pkg_dir, "LICENSE"))
@test occursin(t.authors, license) @test occursin(t.authors, license)
@test occursin(t.years, license)
@test occursin(read_license(t.license), license) @test occursin(read_license(t.license), license)
# Test the REQUIRE generation. # Test the REQUIRE generation.
@test gen_require(pkg_dir, t) == ["REQUIRE"] @test gen_require(pkg_dir, t) == ["REQUIRE"]
@test isfile(joinpath(pkg_dir, "REQUIRE")) @test isfile(joinpath(pkg_dir, "REQUIRE"))
vf = version_floor(t.julia_version) vf = version_floor(t.julia_version)
@test readchomp(joinpath(pkg_dir, "REQUIRE")) == "julia $vf\n$test_pkg" @test readchomp(joinpath(pkg_dir, "REQUIRE")) == "julia $vf"
rm(joinpath(pkg_dir, "REQUIRE")) rm(joinpath(pkg_dir, "REQUIRE"))
# Test the test generation. # Test the test generation.
@test gen_tests(pkg_dir, t) == ["Manifest.toml", "test/"] @test gen_tests(pkg_dir, t) == ["Manifest.toml", "test/"]
@test isdir(joinpath(pkg_dir, "test")) @test isdir(joinpath(pkg_dir, "test"))
@test isfile(joinpath(pkg_dir, "test", "runtests.jl")) @test isfile(joinpath(pkg_dir, "test", "runtests.jl"))
runtests = readchomp(joinpath(pkg_dir, "test", "runtests.jl")) @test isfile(joinpath(pkg_dir, "Manifest.toml"))
runtests = read(joinpath(pkg_dir, "test", "runtests.jl"), String)
rm(joinpath(pkg_dir, "test"); recursive=true) rm(joinpath(pkg_dir, "test"); recursive=true)
@test occursin("using $test_pkg", runtests) @test occursin("using $test_pkg", runtests)
@test occursin("using Test", runtests) @test occursin("using Test", runtests)
manifest = read(joinpath(pkg_dir, "Manifest.toml"), String)
@test occursin("[[Test]]", manifest)
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
end end
@testset "Package generation" begin @testset "Package generation" begin
t = Template(; user=me, gitconfig=gitconfig) t = Template(; user=me)
generate(test_pkg, t) generate(test_pkg, t)
pkg_dir = joinpath(default_dir, test_pkg) pkg_dir = joinpath(default_dir, test_pkg)
@ -302,30 +253,27 @@ end
@test isdir(joinpath(pkg_dir, "test")) @test isdir(joinpath(pkg_dir, "test"))
@test isfile(joinpath(pkg_dir, "test", "runtests.jl")) @test isfile(joinpath(pkg_dir, "test", "runtests.jl"))
@test isfile(joinpath(pkg_dir, "Manifest.toml")) @test isfile(joinpath(pkg_dir, "Manifest.toml"))
# Check the gitconfig.
repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo))
@test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"]
# Check the configured remote and branches. # Check the configured remote and branches.
# Note: This test will fail on your system if you've configured Git # Note: This test will fail on your system if you've configured Git
# to replace all HTTPS URLs with SSH. # to replace all HTTPS URLs with SSH.
repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo))
@test LibGit2.url(remote) == "https://github.com/$me/$test_pkg.jl" @test LibGit2.url(remote) == "https://github.com/$me/$test_pkg.jl"
@test in("master", branches) @test branches == ["master"]
@test !in("gh-pages", branches)
@test !LibGit2.isdirty(repo) @test !LibGit2.isdirty(repo)
rm(pkg_dir; recursive=true) rm(pkg_dir; recursive=true)
# Check that the remote is an SSH URL when we want it to be. # Check that the remote is an SSH URL when we want it to be.
t = Template(; user=me, gitconfig=gitconfig, ssh=true) t = Template(; user=me, ssh=true)
generate(t, test_pkg) # Test the reversed-arguments method. generate(t, test_pkg) # Test the reversed-arguments method here.
repo = LibGit2.GitRepo(pkg_dir) repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "git@github.com:$me/$test_pkg.jl.git" @test LibGit2.url(remote) == "git@github.com:$me/$test_pkg.jl.git"
rm(pkg_dir; recursive=true) rm(pkg_dir; recursive=true)
# Check that the remote is set correctly for non-default hosts. # Check that the remote is set correctly for non-default hosts.
t = Template(; user=me, host="gitlab.com", gitconfig=gitconfig) t = Template(; user=me, host="gitlab.com")
generate(test_pkg, t) generate(test_pkg, t)
repo = LibGit2.GitRepo(pkg_dir) repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@ -334,42 +282,10 @@ end
# Check that the package ends up in the right directory. # Check that the package ends up in the right directory.
temp_dir = mktempdir() temp_dir = mktempdir()
t = Template(; user=me, dir=temp_dir, gitconfig=gitconfig) t = Template(; user=me, dir=temp_dir)
generate(test_pkg, t) generate(test_pkg, t)
@test isdir(joinpath(temp_dir, test_pkg)) @test isdir(joinpath(temp_dir, test_pkg))
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
# Check that all the plugin files are generated.
t = Template(;
user=me,
license="",
gitconfig=gitconfig,
plugins=[AppVeyor(), GitHubPages(), Coveralls(), CodeCov(), TravisCI()],
)
generate(test_pkg, t)
@test isdir(pkg_dir)
@test !isfile(joinpath(pkg_dir, "LICENSE"))
@test isfile(joinpath(pkg_dir, ".travis.yml"))
@test isfile(joinpath(pkg_dir, ".appveyor.yml"))
@test isdir(joinpath(pkg_dir, "docs"))
@test isfile(joinpath(pkg_dir, "docs", "make.jl"))
@test isdir(joinpath(pkg_dir, "docs", "src"))
@test isfile(joinpath(pkg_dir, "docs", "src", "index.md"))
# Test that the gh-pages exists for GitHubPages.
repo = LibGit2.GitRepo(pkg_dir)
@test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"]
branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo))
@test in("gh-pages", branches)
@test !LibGit2.isdirty(repo)
rm(pkg_dir; recursive=true)
# Check that the generated docs root is just the copied README.
t = Template(; user=me, gitconfig=gitconfig, plugins=[GitHubPages()])
generate(test_pkg, t)
readme = read(joinpath(pkg_dir, "README.md"), String)
index = read(joinpath(pkg_dir, "docs", "src", "index.md"), String)
@test readme == index
rm(pkg_dir; recursive=true)
end end
@testset "Version floor" begin @testset "Version floor" begin
@ -451,7 +367,6 @@ end
end end
@testset "Plugins" begin @testset "Plugins" begin
user = gitconfig["github.user"]
t = Template(; user=me) t = Template(; user=me)
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
@ -464,11 +379,11 @@ end
@test format(badge) == "[![A](B)](C)" @test format(badge) == "[![A](B)](C)"
p = Bar() p = Bar()
@test isempty(badges(p, user, test_pkg)) @test isempty(badges(p, me, test_pkg))
@test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test isempty(gen_plugin(p, t, temp_dir, test_pkg))
p = Baz() p = Baz()
@test isempty(badges(p, user, test_pkg)) @test isempty(badges(p, me, test_pkg))
@test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test isempty(gen_plugin(p, t, temp_dir, test_pkg))
include(joinpath("plugins", "travisci.jl")) include(joinpath("plugins", "travisci.jl"))