Overhaul plugin system to facilitate adding simple new plugins
This commit is contained in:
parent
2b74813e1f
commit
a265956339
@ -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
|
||||||
|
@ -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
54
src/plugin.jl
Normal 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
|
@ -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",
|
||||||
|
["[](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 [
|
|
||||||
"[](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
|
|
||||||
|
@ -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",
|
||||||
|
["[](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 [
|
|
||||||
"[](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
29
src/plugins/coveralls.jl
Normal 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",
|
||||||
|
["[](https://coveralls.io/github/{{USER}}/{{PKGNAME}}.jl?branch=master)"],
|
||||||
|
Dict{String, Any}(),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
@ -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
|
||||||
|
@ -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 [
|
||||||
"[](https://$user.github.io/$pkg_name.jl/stable)"
|
"[](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},
|
||||||
|
@ -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 [
|
|
||||||
"[](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
33
src/plugins/travisci.jl
Normal 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",
|
||||||
|
["[](https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl)"],
|
||||||
|
Dict{String, Any}(),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
117
test/tests.jl
117
test/tests.jl
@ -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 == ["[](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 == ["[](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 == ["[](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 == ["[](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) == ["[](https://ci.appveyor.com/project/$user/$test_pkg-jl)"]
|
||||||
|
|
||||||
|
p = TravisCI()
|
||||||
|
@test badges(p, user, test_pkg) == ["[](https://travis-ci.org/$user/$test_pkg.jl)"]
|
||||||
|
|
||||||
|
p = CodeCov()
|
||||||
|
@test badges(p, user, test_pkg) == ["[](https://codecov.io/gh/$user/$test_pkg.jl)"]
|
||||||
|
|
||||||
|
p = Coveralls()
|
||||||
|
@test badges(p, user, test_pkg) == ["[](https://coveralls.io/github/$user/$test_pkg.jl?branch=master)"]
|
||||||
|
|
||||||
|
p = GitHubPages()
|
||||||
|
@test badges(p, user, test_pkg) == [
|
||||||
|
"[](https://$user.github.io/$test_pkg.jl/stable)"
|
||||||
|
"[](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)
|
||||||
|
Loading…
Reference in New Issue
Block a user