Overhaul plugin system to facilitate adding simple new plugins

This commit is contained in:
Chris de Graaf 2017-08-17 01:57:58 -05:00
parent 2b74813e1f
commit a265956339
11 changed files with 282 additions and 226 deletions

View File

@ -4,17 +4,20 @@ using AutoHashEquals
using Mustache using Mustache
using URIParser using URIParser
export generate, show_license, Template, GitHubPages, AppVeyor, TravisCI, CodeCov export generate, show_license, Template, GitHubPages, AppVeyor, TravisCI,
CodeCov, Coveralls
abstract type Plugin end abstract type Plugin end
include("license.jl") include("license.jl")
include("template.jl") include("template.jl")
include("generate.jl") include("generate.jl")
include("plugin.jl")
include(joinpath("plugins", "documenter.jl")) include(joinpath("plugins", "documenter.jl"))
include(joinpath("plugins", "coveralls.jl"))
include(joinpath("plugins", "appveyor.jl")) include(joinpath("plugins", "appveyor.jl"))
include(joinpath("plugins", "codecov.jl")) include(joinpath("plugins", "codecov.jl"))
include(joinpath("plugins", "travis.jl")) include(joinpath("plugins", "travisci.jl"))
include(joinpath("plugins", "githubpages.jl")) include(joinpath("plugins", "githubpages.jl"))
@ -30,6 +33,6 @@ const LICENSES = Dict(
"LGPL-2.1+" => "Lesser GNU Public License, Version 2.1+", "LGPL-2.1+" => "Lesser GNU Public License, Version 2.1+",
"LGPL-3.0+" => "Lesser GNU Public License, Version 3.0+" "LGPL-3.0+" => "Lesser GNU Public License, Version 3.0+"
) )
const BADGE_ORDER = [GitHubPages, TravisCI, AppVeyor, CodeCov] const BADGE_ORDER = [GitHubPages, TravisCI, AppVeyor, CodeCov, Coveralls]
end end

View File

@ -120,9 +120,12 @@ Returns an array of generated file/directory names.
""" """
function gen_gitignore(pkg_name::AbstractString, template::Template) function gen_gitignore(pkg_name::AbstractString, template::Template)
text = ".DS_Store\n" text = ".DS_Store\n"
for plugin in values(template.plugins) seen = []
if !isempty(plugin.gitignore_files) patterns = vcat([plugin.gitignore for plugin in values(template.plugins)]...)
text *= join(plugin.gitignore_files, "\n") * "\n" for pattern in patterns
if !in(pattern, seen)
text *= "$pattern\n"
push!(seen, pattern)
end end
end end
@ -262,8 +265,8 @@ end
""" """
substitute( substitute(
template::AbstractString, template::AbstractString,
pkg_name::AbstractString,
pkg_template::Template; pkg_template::Template;
pkg_name::AbstractString,
view::Dict{String, Any}=Dict{String, Any}(), view::Dict{String, Any}=Dict{String, Any}(),
) -> String ) -> String
@ -271,22 +274,23 @@ Replace placeholders in `template`. The input string is not modified.
# Arguments: # Arguments:
* `template::AbstractString`: Template string to make replacements in. * `template::AbstractString`: Template string to make replacements in.
* `pkg_name::AbstractString`: Name of the package being created.
* `pkg_template::Template`: The package template in use. * `pkg_template::Template`: The package template in use.
* `pkg_name::AbstractString`: Name of the package being created.
* `view::Dict{String, Any}=Dict{String, Any}()`: Additional values to be substituted. * `view::Dict{String, Any}=Dict{String, Any}()`: Additional values to be substituted.
Returns the text with substitutions applied. Returns the text with substitutions applied.
""" """
function substitute( function substitute(
template::AbstractString, template::AbstractString,
pkg_name::AbstractString, pkg_template::Template,
pkg_template::Template; pkg_name::AbstractString;
view::Dict{String, Any}=Dict{String, Any}(), view::Dict{String, Any}=Dict{String, Any}(),
) )
# Don't use version_floor here because we don't want the trailing '-' on prereleases.
d = merge!(Dict{String, Any}(), view) d = merge!(Dict{String, Any}(), view)
d["PKGNAME"] = pkg_name d["PKGNAME"] = pkg_name
d["USER"] = pkg_template.user
v = pkg_template.julia_version v = pkg_template.julia_version
# Don't use version_floor here because we don't want the trailing '-' on prereleases.
d["VERSION"] = "$(v.major).$(v.minor)" d["VERSION"] = "$(v.major).$(v.minor)"
# d["AFTER"] is true whenever something needs to occur in a CI "after_script". # d["AFTER"] is true whenever something needs to occur in a CI "after_script".
if any(isa(p, Documenter) for p in values(pkg_template.plugins)) if any(isa(p, Documenter) for p in values(pkg_template.plugins))
@ -299,3 +303,30 @@ function substitute(
end end
return render(template, d) return render(template, d)
end end
"""
substitute(
template::AbstractString,
pkg_plugin::Plugin;
pkg_name::AbstractString,
view::Dict{String, Any}=Dict{String, Any}(),
) -> String
Replace placeholders in `template`. The input string is not modified.
# Arguments:
* `template::AbstractString`: Template string to make replacements in.
* `pkg_plugin::Plugin`: The plugin in use.
* `pkg_name::AbstractString`: Name of the package being created.
* `view::Dict{String, Any}=Dict{String, Any}()`: Additional values to be substituted.
Returns the text with substitutions applied.
"""
function substitute(
template::AbstractString,
pkg_plugin::Plugin,
pkg_name::AbstractString;
view::Dict{String, Any}=Dict{String, Any}(),
)
return render(template, merge(Dict("PKGNAME" => pkg_name), view))
end

54
src/plugin.jl Normal file
View File

@ -0,0 +1,54 @@
abstract type GenericPlugin <: Plugin end
abstract type CustomPlugin <: Plugin end
"""
badges(\_::Plugin, user::AbstractString, pkg_name::AbstractString)
Generate Markdown badges for the current package.
# Arguments
* `plugin::Plugin`: Plugin whose badges we are generating.
* `user::AbstractString`: Username of the package creator.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges.
"""
badges(plugin::Plugin, user::AbstractString, pkg_name::AbstractString) = String[]
function badges(plugin::GenericPlugin, user::AbstractString, pkg_name::AbstractString)
return substitute.(
plugin.badges,
plugin,
pkg_name;
view=Dict{String, Any}("USER" => user)
)
end
"""
gen_plugin(plugin::Plugin, template::Template, pkg_name::AbstractString) -> Vector{String}
Generate any files associated with a plugin.
# Arguments
* `plugin::Plugin`: Plugin whose files are being generated.
* `template::Template`: Template configuration.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of generated file/directory names.
"""
gen_plugin(plugin::Plugin, template::Template, pkg_name::AbstractString) = String[]
function gen_plugin(plugin::GenericPlugin, template::Template, pkg_name::AbstractString)
try
text = substitute(
readstring(get(plugin.src)),
template,
pkg_name;
view=plugin.view,
)
gen_file(joinpath(template.temp_dir, pkg_name, plugin.dest), text)
return [plugin.dest]
catch
return String[]
end
end

View File

@ -1,64 +1,33 @@
""" """
AppVeyor(; config_file::Union{AbstractString, Void}="") -> AppVeyor AppVeyor(; config_file::Union{AbstractString, Void}="") -> GenericPlugin
Add AppVeyor to a template's plugins to add AppVeyor CI support. Add AppVeyor to a template's plugins to add AppVeyor CI support.
# Keyword Arguments # Keyword Arguments
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.appveyor.yml`. * `config_file::Union{AbstractString, Void}=""`: Path to a custom `.appveyor.yml`.
If `nothing` is supplied, then no file will be generated. If `nothing` is supplied, no file will be generated.
""" """
@auto_hash_equals struct AppVeyor <: Plugin @auto_hash_equals struct AppVeyor <: GenericPlugin
gitignore_files::Vector{AbstractString} gitignore::Vector{AbstractString}
config_file::Union{AbstractString, Void} src::Nullable{AbstractString}
dest::AbstractString
badges::Vector{AbstractString}
view::Dict{String, Any}
function AppVeyor(; config_file::Union{AbstractString, Void}="") function AppVeyor(; config_file::Union{AbstractString, Void}="")
if config_file != nothing if config_file != nothing
if isempty(config_file) if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "appveyor.yml") config_file = joinpath(DEFAULTS_DIR, "appveyor.yml")
end elseif !isfile(config_file)
if !isfile(config_file)
throw(ArgumentError("File $(abspath(config_file)) does not exist")) throw(ArgumentError("File $(abspath(config_file)) does not exist"))
end end
end end
new(AbstractString[], config_file) new(
[],
config_file,
".appveyor.yml",
["[![Build Status](https://ci.appveyor.com/api/projects/status/github/{{USER}}/{{PKGNAME}}.jl?svg=true)](https://ci.appveyor.com/project/{{USER}}/{{PKGNAME}}-jl)"],
Dict{String, Any}(),
)
end end
end end
"""
badges(\_::AppVeyor, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package.
# Arguments
* `_::AppVeyor`: Plugin whose badges we are generating.
* `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges.
"""
function badges(_::AppVeyor, user::AbstractString, pkg_name::AbstractString)
return [
"[![Build Status](https://ci.appveyor.com/api/projects/status/github/$user/$pkg_name.jl?svg=true)](https://ci.appveyor.com/project/$user/$pkg_name-jl)"
]
end
"""
gen_plugin(plugin::AppVeyor, template::Template, pkg_name::AbstractString) -> Vector{String}
Generate a .appveyor.yml.
# Arguments
* `plugin::AppVeyor`: Plugin whose files are being generated.
* `template::Template`: Template configuration and plugins.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of generated file/directory names.
"""
function gen_plugin(plugin::AppVeyor, template::Template, pkg_name::AbstractString)
if plugin.config_file == nothing
return String[]
end
text = substitute(readstring(plugin.config_file), pkg_name, template)
gen_file(joinpath(template.temp_dir, pkg_name, ".appveyor.yml"), text)
return [".appveyor.yml"]
end

View File

@ -1,64 +1,33 @@
""" """
CodeCov(; config_file::Union{AbstractString, Void}="") -> CodeCov CodeCov(; config_file::Union{AbstractString, Void}="") -> GenericPlugin
Add CodeCov to a template's plugins to enable CodeCov coverage reports. Add CodeCov to a template's plugins to enable CodeCov coverage reports.
# Keyword Arguments: # Keyword Arguments:
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.codecov.yml`. * `config_file::Union{AbstractString, Void}=""`: Path to a custom `.codecov.yml`.
If `nothing` is supplied, then no file will be generated. If `nothing` is supplied, no file will be generated.
""" """
@auto_hash_equals struct CodeCov <: Plugin @auto_hash_equals struct CodeCov <: GenericPlugin
gitignore_files::Vector{AbstractString} gitignore::Vector{AbstractString}
config_file::Union{AbstractString, Void} src::Nullable{AbstractString}
dest::AbstractString
badges::Vector{AbstractString}
view::Dict{String, Any}
function CodeCov(; config_file::Union{AbstractString, Void}="") function CodeCov(; config_file::Union{AbstractString, Void}="")
if config_file != nothing if config_file != nothing
if isempty(config_file) if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "codecov.yml") config_file = joinpath(DEFAULTS_DIR, "codecov.yml")
end elseif !isfile(config_file)
if !isfile(config_file)
throw(ArgumentError("File $(abspath(config_file)) does not exist")) throw(ArgumentError("File $(abspath(config_file)) does not exist"))
end end
end end
new(["*.jl.cov", "*.jl.*.cov", "*.jl.mem"], config_file) new(
["*.jl.cov", "*.jl.*.cov", "*.jl.mem"],
config_file,
".codecov.yml",
["[![CodeCov](https://codecov.io/gh/{{USER}}/{{PKGNAME}}.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/{{USER}}/{{PKGNAME}}.jl)"],
Dict{String, Any}(),
)
end end
end end
"""
badges(\_::CodeCov, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package.
# Arguments
* `_::CodeCov`: Plugin whose badges we are generating.
* `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges.
"""
function badges(_::CodeCov, user::AbstractString, pkg_name::AbstractString)
return [
"[![CodeCov](https://codecov.io/gh/$user/$pkg_name.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/$user/$pkg_name.jl)"
]
end
"""
gen_plugin(plugin::CodeCov, template::Template, pkg_name::AbstractString) -> Vector{String}
Generate a .codecov.yml.
# Arguments
* `plugin::CodeCov`: Plugin whose files are being generated.
* `template::Template`: Template configuration and plugins.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of generated file/directory names.
"""
function gen_plugin(plugin::CodeCov, template::Template, pkg_name::AbstractString)
if plugin.config_file == nothing
return String[]
end
text = substitute(readstring(plugin.config_file), pkg_name, template)
gen_file(joinpath(template.temp_dir, pkg_name, ".codecov.yml"), text)
return [".codecov.yml"]
end

29
src/plugins/coveralls.jl Normal file
View File

@ -0,0 +1,29 @@
"""
Coveralls(; config_file::Union{AbstractString, Void}="") -> Coveralls
Add Coveralls to a template's plugins to enable Coveralls coverage reports.
# Keyword Arguments:
* `config_file::Union{AbstractString, Void}=nothing`: Path to a custom `.coveralls.yml`.
If left unset, no file will be generated.
"""
@auto_hash_equals struct Coveralls <: GenericPlugin
gitignore::Vector{AbstractString}
src::Nullable{AbstractString}
dest::AbstractString
badges::Vector{AbstractString}
view::Dict{String, Any}
function Coveralls(; config_file::Union{AbstractString, Void}=nothing)
if config_file != nothing && !isfile(config_file)
throw(ArgumentError("File $(abspath(config_file)) does not exist"))
end
new(
["*.jl.cov", "*.jl.*.cov", "*.jl.mem"],
config_file,
".coveralls.yml",
["[![Coveralls](https://coveralls.io/repos/github/{{USER}}/{{PKGNAME}}.jl/badge.svg?branch=master)](https://coveralls.io/github/{{USER}}/{{PKGNAME}}.jl?branch=master)"],
Dict{String, Any}(),
)
end
end

View File

@ -2,7 +2,7 @@
Add a Documenter subtype to a template's plugins to add support for Add a Documenter subtype to a template's plugins to add support for
[Documenter.jl](https://github.com/JuliaDocs/Documenter.jl). [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl).
""" """
abstract type Documenter <: Plugin end abstract type Documenter <: CustomPlugin end
""" """
gen_plugin(plugin::Documenter, template::Template, pkg_name::AbstractString) -> Void gen_plugin(plugin::Documenter, template::Template, pkg_name::AbstractString) -> Void

View File

@ -7,7 +7,7 @@ Add GitHubPages to a template's plugins to add Documenter.jl support via GitHub
* `assets::Vector{String}=String[]`: Array of paths to Documenter asset files. * `assets::Vector{String}=String[]`: Array of paths to Documenter asset files.
""" """
@auto_hash_equals struct GitHubPages <: Documenter @auto_hash_equals struct GitHubPages <: Documenter
gitignore_files::Vector{AbstractString} gitignore::Vector{AbstractString}
assets::Vector{AbstractString} assets::Vector{AbstractString}
function GitHubPages(; assets::Vector{String}=String[]) function GitHubPages(; assets::Vector{String}=String[])
@ -21,18 +21,6 @@ Add GitHubPages to a template's plugins to add Documenter.jl support via GitHub
end end
end end
"""
badges(\_::GitHubPages, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package.
# Arguments
* `_::GitHubPages`: plugin whose badges we are generating.
* `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges.
"""
function badges(_::GitHubPages, user::AbstractString, pkg_name::AbstractString) function badges(_::GitHubPages, user::AbstractString, pkg_name::AbstractString)
return [ return [
"[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$user.github.io/$pkg_name.jl/stable)" "[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$user.github.io/$pkg_name.jl/stable)"
@ -40,19 +28,6 @@ function badges(_::GitHubPages, user::AbstractString, pkg_name::AbstractString)
] ]
end end
"""
gen_plugin(plugin::GitHubPages, template::Template, pkg_name::AbstractString)
Generate the "docs" directory and set up direct HTML output from Documenter to be pushed
to GitHub Pages.
# Arguments
* `plugin::GitHubPages`: Plugin whose files are being generated.
* `template::Template`: Template configuration and plugins.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of generated file/directory names.
"""
function gen_plugin(plugin::GitHubPages, template::Template, pkg_name::AbstractString) function gen_plugin(plugin::GitHubPages, template::Template, pkg_name::AbstractString)
invoke( invoke(
gen_plugin, Tuple{Documenter, Template, AbstractString}, gen_plugin, Tuple{Documenter, Template, AbstractString},

View File

@ -1,64 +0,0 @@
"""
TravisCI(; config_file::Union{AbstractString, Void}="") -> TravisCI
Add TravisCI to a template's plugins to add Travis CI support.
# Keyword Arguments:
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.travis.yml`.
If `nothing` is supplied, then no file will be generated.
"""
@auto_hash_equals struct TravisCI <: Plugin
gitignore_files::Vector{AbstractString}
config_file::Union{AbstractString, Void}
function TravisCI(; config_file::Union{AbstractString, Void}="")
if config_file != nothing
if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "travis.yml")
end
if !isfile(config_file)
throw(ArgumentError("File $(abspath(config_file)) does not exist"))
end
end
new(AbstractString[], config_file)
end
end
"""
badges(\_::TravisCI, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package.
# Arguments
* `_::TravisCI`: plugin whose badges we are generating.
* `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges.
"""
function badges(_::TravisCI, user::AbstractString, pkg_name::AbstractString)
return [
"[![Build Status](https://travis-ci.org/$user/$pkg_name.jl.svg?branch=master)](https://travis-ci.org/$user/$pkg_name.jl)"
]
end
"""
gen_plugin(plugin::TravisCI, template::Template, pkg_name::AbstractString) -> Vector{String}
Generate a .travis.yml.
# Arguments
* `plugin::TravisCI`: The plugin whose files are being generated.
* `template::Template`: Template configuration and plugins.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of generated file/directory names.
"""
function gen_plugin(plugin::TravisCI, template::Template, pkg_name::AbstractString)
if plugin.config_file == nothing
return String[]
end
text = substitute(readstring(plugin.config_file), pkg_name, template)
gen_file(joinpath(template.temp_dir, pkg_name, ".travis.yml"), text)
return [".travis.yml"]
end

33
src/plugins/travisci.jl Normal file
View File

@ -0,0 +1,33 @@
"""
TravisCI(; config_file::Union{AbstractString, Void}="") -> GenericPlugin
Add TravisCI to a template's plugins to add Travis CI support.
# Keyword Arguments:
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.travis.yml`.
If `nothing` is supplied, no file will be generated.
"""
@auto_hash_equals struct TravisCI <: GenericPlugin
gitignore::Vector{AbstractString}
src::Nullable{AbstractString}
dest::AbstractString
badges::Vector{AbstractString}
view::Dict{String, Any}
function TravisCI(; config_file::Union{AbstractString, Void}="")
if config_file != nothing
if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "travis.yml")
elseif !isfile(config_file)
throw(ArgumentError("File $(abspath(config_file)) does not exist"))
end
end
new(
[],
config_file,
".travis.yml",
["[![Build Status](https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl.svg?branch=master)](https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl)"],
Dict{String, Any}(),
)
end
end

View File

@ -83,42 +83,92 @@ write(test_file, template_text)
rm(t.temp_dir; recursive=true) rm(t.temp_dir; recursive=true)
if isempty(LibGit2.getconfig("github.username", "")) if isempty(LibGit2.getconfig("github.username", ""))
@test_throws ArgumentError Template() @test_throws ArgumentError t = Template()
else else
t = Template() t = Template()
rm(t.temp_dir; recursive=true) rm(t.temp_dir; recursive=true)
@test t.user == LibGit2.getconfig("github.username", "") @test t.user == LibGit2.getconfig("github.username", "")
end end
@test_throws ArgumentError Template(; user="invenia", license="FakeLicense") @test_throws ArgumentError t = Template(; user="invenia", license="FakeLicense")
end end
@testset "Plugin creation" begin @testset "Plugin creation" begin
p = AppVeyor() p = AppVeyor()
@test isempty(p.gitignore_files) @test isempty(p.gitignore)
@test p.config_file == joinpath(PkgTemplates.DEFAULTS_DIR, "appveyor.yml") @test get(p.src) == joinpath(PkgTemplates.DEFAULTS_DIR, "appveyor.yml")
@test p.dest == ".appveyor.yml"
@test p.badges == ["[![Build Status](https://ci.appveyor.com/api/projects/status/github/{{USER}}/{{PKGNAME}}.jl?svg=true)](https://ci.appveyor.com/project/{{USER}}/{{PKGNAME}}-jl)"]
@test isempty(p.view)
p = AppVeyor(; config_file=nothing) p = AppVeyor(; config_file=nothing)
@test p.config_file == nothing @test_throws NullException get(p.src)
p = AppVeyor(; config_file=test_file) p = AppVeyor(; config_file=test_file)
@test p.config_file == test_file @test get(p.src) == test_file
@test_throws ArgumentError AppVeyor(; config_file=fake_path) @test_throws ArgumentError p = AppVeyor(; config_file=fake_path)
p = TravisCI() p = TravisCI()
@test isempty(p.gitignore_files) @test isempty(p.gitignore)
@test p.config_file == joinpath(PkgTemplates.DEFAULTS_DIR, "travis.yml") @test get(p.src) == joinpath(PkgTemplates.DEFAULTS_DIR, "travis.yml")
@test p.dest == ".travis.yml"
@test p.badges == ["[![Build Status](https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl.svg?branch=master)](https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl)"]
@test isempty(p.view)
p = TravisCI(; config_file=nothing) p = TravisCI(; config_file=nothing)
@test p.config_file == nothing @test_throws NullException get(p.src)
p = TravisCI(; config_file=test_file) p = TravisCI(; config_file=test_file)
@test p.config_file == test_file @test get(p.src) == test_file
@test_throws ArgumentError TravisCI(; config_file=fake_path) @test_throws ArgumentError p = TravisCI(; config_file=fake_path)
p = CodeCov() p = CodeCov()
@test p.gitignore_files == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"] @test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
@test p.config_file == joinpath(PkgTemplates.DEFAULTS_DIR, "codecov.yml") @test get(p.src) == joinpath(PkgTemplates.DEFAULTS_DIR, "codecov.yml")
@test p.dest == ".codecov.yml"
@test p.badges == ["[![CodeCov](https://codecov.io/gh/{{USER}}/{{PKGNAME}}.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/{{USER}}/{{PKGNAME}}.jl)"]
@test isempty(p.view)
p = CodeCov(; config_file=nothing) p = CodeCov(; config_file=nothing)
@test p.config_file == nothing @test_throws NullException get(p.src)
p = CodeCov(; config_file=test_file) p = CodeCov(; config_file=test_file)
@test p.config_file == test_file @test get(p.src) == test_file
@test_throws ArgumentError CodeCov(; config_file=fake_path) @test_throws ArgumentError p = CodeCov(; config_file=fake_path)
p = Coveralls()
@test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
@test_throws NullException get(p.src)
@test p.dest == ".coveralls.yml"
@test p.badges == ["[![Coveralls](https://coveralls.io/repos/github/{{USER}}/{{PKGNAME}}.jl/badge.svg?branch=master)](https://coveralls.io/github/{{USER}}/{{PKGNAME}}.jl?branch=master)"]
@test isempty(p.view)
p = Coveralls(; config_file=nothing)
@test_throws NullException get(p.src)
p = Coveralls(; config_file=test_file)
@test get(p.src) == test_file
@test_throws ArgumentError p = Coveralls(; config_file=fake_path)
p = GitHubPages()
@test p.gitignore == ["/docs/build/", "/docs/site/"]
@test isempty(p.assets)
p = GitHubPages(; assets=[test_file])
@test p.assets == [test_file]
@test_throws ArgumentError p = GitHubPages(; assets=[fake_path])
end
@testset "Badge generation" begin
user = git_config["github.username"]
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)"]
p = TravisCI()
@test badges(p, user, test_pkg) == ["[![Build Status](https://travis-ci.org/$user/$test_pkg.jl.svg?branch=master)](https://travis-ci.org/$user/$test_pkg.jl)"]
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)"]
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)"]
p = GitHubPages()
@test badges(p, user, test_pkg) == [
"[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$user.github.io/$test_pkg.jl/stable)"
"[![Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://$user.github.io/$test_pkg.jl/latest)"
]
end end
@testset "File generation" begin @testset "File generation" begin
@ -156,7 +206,7 @@ end
rm(joinpath(pkg_dir, ".gitignore")) rm(joinpath(pkg_dir, ".gitignore"))
@test contains(gitignore, ".DS_Store") @test contains(gitignore, ".DS_Store")
for p in values(t.plugins) for p in values(t.plugins)
for entry in p.gitignore_files for entry in p.gitignore
@test contains(gitignore, entry) @test contains(gitignore, entry)
end end
end end
@ -201,14 +251,14 @@ end
@test isfile(Pkg.dir(test_pkg, "REQUIRE")) @test isfile(Pkg.dir(test_pkg, "REQUIRE"))
@test isfile(Pkg.dir(test_pkg, ".gitignore")) @test isfile(Pkg.dir(test_pkg, ".gitignore"))
@test isdir(Pkg.dir(test_pkg, "src")) @test isdir(Pkg.dir(test_pkg, "src"))
@test isfile(Pkg.dir(test_pkg, "src", "TestPkg.jl")) @test isfile(Pkg.dir(test_pkg, "src", "$test_pkg.jl"))
@test isdir(Pkg.dir(test_pkg, "test")) @test isdir(Pkg.dir(test_pkg, "test"))
@test isfile(Pkg.dir(test_pkg, "test", "runtests.jl")) @test isfile(Pkg.dir(test_pkg, "test", "runtests.jl"))
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) repo = LibGit2.GitRepo(Pkg.dir(test_pkg))
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
branches = [LibGit2.shortname(branch[1]) for branch in LibGit2.GitBranchIter(repo)] branches = [LibGit2.shortname(branch[1]) for branch in LibGit2.GitBranchIter(repo)]
@test LibGit2.getconfig(repo, "user.name", "") == LibGit2.getconfig("user.name", "") @test LibGit2.getconfig(repo, "user.name", "") == LibGit2.getconfig("user.name", "")
@test LibGit2.url(remote) == "https://github.com/invenia/TestPkg.jl" @test LibGit2.url(remote) == "https://github.com/invenia/$test_pkg.jl"
@test in("master", branches) @test in("master", branches)
@test !in("gh-pages", branches) @test !in("gh-pages", branches)
@test !LibGit2.isdirty(repo) @test !LibGit2.isdirty(repo)
@ -217,14 +267,14 @@ end
generate(test_pkg, t; ssh=true) generate(test_pkg, t; ssh=true)
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) repo = LibGit2.GitRepo(Pkg.dir(test_pkg))
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "git@github.com:invenia/TestPkg.jl.git" @test LibGit2.url(remote) == "git@github.com:invenia/$test_pkg.jl.git"
rm(Pkg.dir(test_pkg); recursive=true) rm(Pkg.dir(test_pkg); recursive=true)
t = Template(; user="invenia", host="gitlab.com") t = Template(; user="invenia", host="gitlab.com")
generate(test_pkg, t) generate(test_pkg, t)
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) repo = LibGit2.GitRepo(Pkg.dir(test_pkg))
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "https://gitlab.com/invenia/TestPkg.jl" @test LibGit2.url(remote) == "https://gitlab.com/invenia/$test_pkg.jl"
rm(Pkg.dir(test_pkg); recursive=true) rm(Pkg.dir(test_pkg); recursive=true)
temp_dir = mktempdir() temp_dir = mktempdir()
@ -237,7 +287,7 @@ end
user="invenia", user="invenia",
license="MIT", license="MIT",
git_config=git_config, git_config=git_config,
plugins=[AppVeyor(), GitHubPages(), CodeCov(), TravisCI()], plugins=[AppVeyor(), GitHubPages(), Coveralls(), CodeCov(), TravisCI()],
) )
generate(test_pkg, t) generate(test_pkg, t)
@test isfile(Pkg.dir(test_pkg, "LICENSE")) @test isfile(Pkg.dir(test_pkg, "LICENSE"))
@ -310,7 +360,7 @@ end
@test isdir(joinpath(pkg_dir, "docs", "src")) @test isdir(joinpath(pkg_dir, "docs", "src"))
@test isfile(joinpath(pkg_dir, "docs", "src", "index.md")) @test isfile(joinpath(pkg_dir, "docs", "src", "index.md"))
index = readchomp(joinpath(pkg_dir, "docs", "src", "index.md")) index = readchomp(joinpath(pkg_dir, "docs", "src", "index.md"))
@test index == "# TestPkg" @test index == "# $test_pkg"
rm(joinpath(pkg_dir, "docs"); recursive=true) rm(joinpath(pkg_dir, "docs"); recursive=true)
p = GitHubPages(; assets=[test_file]) p = GitHubPages(; assets=[test_file])
@test gen_plugin(p, t, test_pkg) == ["docs/"] @test gen_plugin(p, t, test_pkg) == ["docs/"]
@ -345,29 +395,36 @@ end
@testset "Mustache substitution" begin @testset "Mustache substitution" begin
t = Template(; user="invenia") t = Template(; user="invenia")
rm(t.temp_dir; recursive=true) rm(t.temp_dir; recursive=true)
p = Coveralls()
view = Dict{String, Any}("OTHER" => false) view = Dict{String, Any}("OTHER" => false)
text = substitute(template_text, test_pkg, t; view=view) text = substitute(template_text, t, test_pkg; view=view)
@test contains(text, "PKGNAME: TestPkg") @test contains(text, "PKGNAME: $test_pkg")
@test contains(text, "VERSION: $(t.julia_version.major).$(t.julia_version.minor)") @test contains(text, "VERSION: $(t.julia_version.major).$(t.julia_version.minor)")
@test !contains(text, "Documenter") @test !contains(text, "Documenter")
@test !contains(text, "After") @test !contains(text, "After")
@test !contains(text, "Other") @test !contains(text, "Other")
t.plugins[GitHubPages] = GitHubPages() t.plugins[GitHubPages] = GitHubPages()
text = substitute(template_text, test_pkg, t; view=view) text = substitute(template_text, t, test_pkg; view=view)
@test contains(text, "Documenter") @test contains(text, "Documenter")
@test contains(text, "After") @test contains(text, "After")
empty!(t.plugins) empty!(t.plugins)
t.plugins[CodeCov] = CodeCov() t.plugins[CodeCov] = CodeCov()
text = substitute(template_text, test_pkg, t; view=view) text = substitute(template_text, t, test_pkg; view=view)
@test contains(text, "CodeCov") @test contains(text, "CodeCov")
@test contains(text, "After") @test contains(text, "After")
empty!(t.plugins) empty!(t.plugins)
view["OTHER"] = true view["OTHER"] = true
text = substitute(template_text, test_pkg, t; view=view) text = substitute(template_text, t, test_pkg; view=view)
@test contains(text, "Other")
text = substitute(template_text, p, test_pkg)
@test contains(text, "PKGNAME: $test_pkg")
text = substitute(template_text, p, test_pkg; view=view)
@test contains(text, "Other") @test contains(text, "Other")
end end
@ -387,7 +444,7 @@ end
end end
@test strip(mit) == strip(read_license("MIT")) @test strip(mit) == strip(read_license("MIT"))
@test strip(read_license("MIT")) == strip(readstring(joinpath(LICENSE_DIR, "MIT"))) @test strip(read_license("MIT")) == strip(readstring(joinpath(LICENSE_DIR, "MIT")))
@test_throws ArgumentError read_license("FakeLicense") @test_throws ArgumentError read_license(fake_path)
end end
rm(test_file) rm(test_file)