Add execution priority to plugins
This commit is contained in:
parent
980452fde3
commit
0cf6d47ada
@ -19,9 +19,8 @@ However, it's probably desirable to customize the template to your liking with v
|
||||
```jl
|
||||
t = Template(;
|
||||
dir="~/code",
|
||||
ssh=true,
|
||||
manifest=true,
|
||||
plugins=[
|
||||
Git(; manifest=true, ssh=true),
|
||||
Codecov(),
|
||||
TravisCI(; x86=true),
|
||||
Documenter{TravisCI}(),
|
||||
|
@ -94,6 +94,7 @@ view
|
||||
Finally, we implement [`hook`](@ref), which is the real workhorse for the plugin.
|
||||
|
||||
TODO prehook and posthook in examples
|
||||
TODO priority
|
||||
|
||||
```@docs
|
||||
prehook
|
||||
|
@ -5,8 +5,10 @@
|
||||
|
||||
function Base.show(io::IO, ::MIME"text/plain", p::T) where T <: Plugin
|
||||
indent = get(io, :indent, 0)
|
||||
print(io, repeat(' ', indent), T, ":")
|
||||
foreach(fieldnames(T)) do n
|
||||
print(io, repeat(' ', indent), T)
|
||||
ns = fieldnames(T)
|
||||
isempty(ns) || print(io, ":")
|
||||
foreach(ns) do n
|
||||
println(io)
|
||||
print(io, repeat(' ', indent + 2), n, ": ", show_field(getfield(p, n)))
|
||||
end
|
||||
@ -28,7 +30,7 @@ function Base.show(io::IO, m::MIME"text/plain", t::Template)
|
||||
print(io, " plugins: None")
|
||||
else
|
||||
print(io, repeat(' ', 2), "plugins:")
|
||||
foreach(sort(collect(values(t.plugins)); by=string)) do p
|
||||
foreach(sort(t.plugins; by=string)) do p
|
||||
println(io)
|
||||
show(IOContext(io, :indent => 4), m, p)
|
||||
end
|
||||
|
@ -1,4 +1,5 @@
|
||||
const TEMPLATES_DIR = normpath(joinpath(@__DIR__, "..", "templates"))
|
||||
const DEFAULT_PRIORITY = 1000
|
||||
|
||||
"""
|
||||
A simple plugin that, in general, creates a single file.
|
||||
@ -59,6 +60,14 @@ By default, the tags are `"{{"` and `"}}"`.
|
||||
"""
|
||||
tags(::Plugin) = "{{", "}}"
|
||||
|
||||
"""
|
||||
priority(::Plugin) -> Int
|
||||
|
||||
Determines the order in which plugins are processed (higher goes first).
|
||||
The default priority (`DEFAULT_PRIORITY`), is `$DEFAULT_PRIORITY`.
|
||||
"""
|
||||
priority(::Plugin) = DEFAULT_PRIORITY
|
||||
|
||||
"""
|
||||
gitignore(::Plugin) -> Vector{String}
|
||||
|
||||
@ -131,7 +140,7 @@ At this point, `pkg_dir` is an empty directory that will eventually contain the
|
||||
|
||||
!!! note
|
||||
`pkg_dir` only stays empty until the first plugin chooses to create a file.
|
||||
Don't count on the order in which the plugins are sorted!
|
||||
See also: [`priority`](@ref).
|
||||
"""
|
||||
prehook(::Plugin, ::Template, ::AbstractString) = nothing
|
||||
|
||||
|
@ -254,10 +254,10 @@ end
|
||||
|
||||
|
||||
"""
|
||||
is_ci(::Type{T}) -> Bool
|
||||
is_ci(::Plugin) -> Bool
|
||||
|
||||
Determine whether or not `T` is a CI plugin.
|
||||
Determine whether or not a plugin is a CI plugin.
|
||||
If you are adding a CI plugin, you should implement this function and return `true`.
|
||||
"""
|
||||
is_ci(::Type) = false
|
||||
is_ci(::Type{<:Union{AppVeyor, TravisCI, CirrusCI, GitLabCI}}) = true
|
||||
is_ci(::Plugin) = false
|
||||
is_ci(::Union{AppVeyor, TravisCI, CirrusCI, GitLabCI}) = true
|
||||
|
@ -45,10 +45,10 @@ badges(::Coveralls) = Badge(
|
||||
gitignore(::Union{Codecov, Coveralls}) = COVERAGE_GITIGNORE
|
||||
|
||||
"""
|
||||
is_coverage(::Type{T}) -> Bool
|
||||
is_coverage(::Plugin) -> Bool
|
||||
|
||||
Determine whether or not `T` is a coverage plugin.
|
||||
Determine whether or not a plugin is a coverage plugin.
|
||||
If you are adding a coverage plugin, you should implement this function and return `true`.
|
||||
"""
|
||||
is_coverage(::Type) = false
|
||||
is_coverage(::Type{<:Union{Codecov, Coveralls}}) = true
|
||||
is_coverage(::Plugin) = false
|
||||
is_coverage(::Union{Codecov, Coveralls}) = true
|
||||
|
@ -50,7 +50,7 @@ end
|
||||
|
||||
# Create the .gitignore.
|
||||
function hook(p::Git, t::Template, pkg_dir::AbstractString)
|
||||
ignore = mapreduce(gitignore, append!, values(t.plugins))
|
||||
ignore = mapreduce(gitignore, append!, t.plugins)
|
||||
# Only ignore manifests at the repo root.
|
||||
p.manifest || "Manifest.toml" in ignore || push!(ignore, "/Manifest.toml")
|
||||
unique!(sort!(ignore))
|
||||
|
@ -5,8 +5,10 @@ Creates a `Project.toml`.
|
||||
"""
|
||||
struct ProjectFile <: Plugin end
|
||||
|
||||
# Create Project.toml in the prehook because other hooks might depend on it.
|
||||
function prehook(::ProjectFile, t::Template, pkg_dir::AbstractString)
|
||||
# Other plugins like Tests will modify this file.
|
||||
priority(::ProjectFile) = typemax(Int) - DEFAULT_PRIORITY + 1
|
||||
|
||||
function hook(::ProjectFile, t::Template, pkg_dir::AbstractString)
|
||||
toml = Dict(
|
||||
"name" => basename(pkg_dir),
|
||||
"uuid" => uuid4(),
|
||||
|
@ -29,19 +29,18 @@ function view(p::Readme, t::Template, pkg::AbstractString)
|
||||
done = DataType[]
|
||||
foreach(badge_order()) do T
|
||||
if hasplugin(t, T)
|
||||
bs = badges(t.plugins[T], t, pkg)
|
||||
append!(strings, badges(t.plugins[T], t, pkg))
|
||||
append!(strings, badges(getplugin(t, T), t, pkg))
|
||||
push!(done, T)
|
||||
end
|
||||
end
|
||||
foreach(setdiff(keys(t.plugins), done)) do T
|
||||
bs = badges(t.plugins[T], t, pkg)
|
||||
append!(strings, badges(t.plugins[T], t, pkg))
|
||||
# And the rest go after, in no particular order.
|
||||
foreach(setdiff(map(typeof, t.plugins), done)) do T
|
||||
append!(strings, badges(getplugin(t, T), t, pkg))
|
||||
end
|
||||
|
||||
return Dict(
|
||||
"BADGES" => strings,
|
||||
"HAS_CITATION" => hasplugin(t, Citation) && t.plugins[Citation].readme,
|
||||
"HAS_CITATION" => hasplugin(t, Citation) && getplugin(t, Citation).readme,
|
||||
"HAS_INLINE_BADGES" => !isempty(strings) && p.inline_badges,
|
||||
"PKG" => pkg,
|
||||
)
|
||||
|
@ -54,7 +54,7 @@ struct Template
|
||||
dir::String
|
||||
host::String
|
||||
julia_version::VersionNumber
|
||||
plugins::Dict{DataType, <:Plugin}
|
||||
plugins::Vector{<:Plugin}
|
||||
user::String
|
||||
end
|
||||
|
||||
@ -72,33 +72,17 @@ function Template(::Val{false}; kwargs...)
|
||||
host = replace(getkw(kwargs, :host), r".*://" => "")
|
||||
julia_version = getkw(kwargs, :julia_version)
|
||||
|
||||
# User-supplied plugins come first, so that deduping the list will remove the defaults.
|
||||
plugins = Plugin[]
|
||||
append!(plugins, getkw(kwargs, :plugins))
|
||||
disabled = getkw(kwargs, :disable_defaults)
|
||||
enabled = filter(p -> !(typeof(p) in disabled), default_plugins())
|
||||
append!(enabled, getkw(kwargs, :plugins))
|
||||
# This comprehension resolves duplicate plugin types by overwriting,
|
||||
# which means that default plugins get replaced by user values.
|
||||
plugins = Dict(typeof(p) => p for p in enabled)
|
||||
append!(plugins, filter(p -> !(typeof(p) in disabled), default_plugins()))
|
||||
plugins = unique(typeof, plugins)
|
||||
sort!(plugins; by=priority, rev=true)
|
||||
|
||||
return Template(authors, dir, host, julia_version, plugins, user)
|
||||
end
|
||||
|
||||
# Does the template have a plugin that satisfies some predicate?
|
||||
hasplugin(t::Template, f::Function) = any(f, keys(t.plugins))
|
||||
hasplugin(t::Template, ::Type{T}) where T <: Plugin = hasplugin(t, U -> U <: T)
|
||||
|
||||
# Get a keyword, or compute some default value.
|
||||
getkw(kwargs, k) = get(() -> defaultkw(k), kwargs, k)
|
||||
|
||||
# Default Template keyword values.
|
||||
defaultkw(s::Symbol) = defaultkw(Val(s))
|
||||
defaultkw(::Val{:authors}) = default_authors()
|
||||
defaultkw(::Val{:dir}) = Pkg.devdir()
|
||||
defaultkw(::Val{:disable_defaults}) = DataType[]
|
||||
defaultkw(::Val{:host}) = "github.com"
|
||||
defaultkw(::Val{:julia_version}) = default_version()
|
||||
defaultkw(::Val{:plugins}) = Plugin[]
|
||||
defaultkw(::Val{:user}) = default_user()
|
||||
|
||||
"""
|
||||
(::Template)(pkg::AbstractString)
|
||||
|
||||
@ -113,7 +97,7 @@ function (t::Template)(pkg::AbstractString)
|
||||
try
|
||||
foreach((prehook, hook, posthook)) do h
|
||||
@info "Running $(h)s"
|
||||
foreach(values(t.plugins)) do p
|
||||
foreach(t.plugins) do p
|
||||
h(p, t, pkg_dir)
|
||||
end
|
||||
end
|
||||
@ -124,3 +108,26 @@ function (t::Template)(pkg::AbstractString)
|
||||
|
||||
@info "New package is at $pkg_dir"
|
||||
end
|
||||
|
||||
# Does the template have a plugin that satisfies some predicate?
|
||||
hasplugin(t::Template, f::Function) = any(f, t.plugins)
|
||||
hasplugin(t::Template, ::Type{T}) where T <: Plugin = hasplugin(t, p -> p isa T)
|
||||
|
||||
# Get a plugin by type.
|
||||
function getplugin(t::Template, ::Type{T}) where T <: Plugin
|
||||
i = findfirst(p -> p isa T, t.plugins)
|
||||
i === nothing ? nothing : t.plugins[i]
|
||||
end
|
||||
|
||||
# Get a keyword, or compute some default value.
|
||||
getkw(kwargs, k) = get(() -> defaultkw(k), kwargs, k)
|
||||
|
||||
# Default Template keyword values.
|
||||
defaultkw(s::Symbol) = defaultkw(Val(s))
|
||||
defaultkw(::Val{:authors}) = default_authors()
|
||||
defaultkw(::Val{:dir}) = Pkg.devdir()
|
||||
defaultkw(::Val{:disable_defaults}) = DataType[]
|
||||
defaultkw(::Val{:host}) = "github.com"
|
||||
defaultkw(::Val{:julia_version}) = default_version()
|
||||
defaultkw(::Val{:plugins}) = Plugin[]
|
||||
defaultkw(::Val{:user}) = default_user()
|
||||
|
@ -39,7 +39,7 @@ const LICENSES_DIR = joinpath(TEMPLATES_DIR, "licenses")
|
||||
License:
|
||||
path: "$(joinpath(LICENSES_DIR, "MIT"))"
|
||||
destination: "LICENSE"
|
||||
ProjectFile:
|
||||
ProjectFile
|
||||
Readme:
|
||||
file: "$(joinpath(TEMPLATES_DIR, "README.md"))"
|
||||
destination: "README.md"
|
||||
|
@ -28,7 +28,7 @@
|
||||
@testset "plugins / disabled_defaults" begin
|
||||
function test_plugins(plugins, expected, disabled=DataType[])
|
||||
t = tpl(; plugins=plugins, disable_defaults=disabled)
|
||||
@test issetequal(values(t.plugins), expected)
|
||||
@test issetequal(t.plugins, expected)
|
||||
end
|
||||
|
||||
defaults = PT.default_plugins()
|
||||
|
Loading…
Reference in New Issue
Block a user