2019-02-05 17:31:51 +00:00
|
|
|
const DEFAULTS_DIR = normpath(joinpath(@__DIR__, "..", "defaults"))
|
|
|
|
|
2019-09-01 01:36:33 +00:00
|
|
|
badge_order() = [
|
|
|
|
Documenter{GitLabCI},
|
|
|
|
Documenter{TravisCI},
|
|
|
|
GitLabCI,
|
|
|
|
TravisCI,
|
|
|
|
AppVeyor,
|
|
|
|
CirrusCI,
|
|
|
|
Codecov,
|
|
|
|
Coveralls,
|
|
|
|
]
|
|
|
|
|
2019-08-27 11:17:15 +00:00
|
|
|
"""
|
2019-09-01 14:03:19 +00:00
|
|
|
A simple plugin that, in general, creates a single file.
|
2019-08-27 11:17:15 +00:00
|
|
|
|
2019-09-01 14:03:19 +00:00
|
|
|
You needn't implement [`gen_plugin`](@ref) for your subtypes.
|
|
|
|
Instead, you're left to implement a couple of much simpler functions:
|
|
|
|
|
|
|
|
- [`source`](@ref)
|
|
|
|
- [`destination`](@ref)
|
|
|
|
|
|
|
|
For examples, see the plugins in the [Continuous Integration (CI)](@ref) and [Code Coverage](@ref) sections.
|
|
|
|
For an example of a plugin that creates a file and then does some additional work, see [`Tests`](@ref).
|
2019-08-27 11:17:15 +00:00
|
|
|
"""
|
2019-02-05 17:31:51 +00:00
|
|
|
abstract type BasicPlugin <: Plugin end
|
|
|
|
|
2019-08-27 11:17:15 +00:00
|
|
|
# Compute the path to a default template file in this repository.
|
2019-02-05 17:31:51 +00:00
|
|
|
default_file(paths::AbstractString...) = joinpath(DEFAULTS_DIR, paths...)
|
|
|
|
|
2017-08-17 22:06:05 +00:00
|
|
|
"""
|
2019-08-27 14:59:25 +00:00
|
|
|
view(::Plugin, ::Template, pkg::AbstractString) -> Dict{String, Any}
|
2017-08-21 21:19:40 +00:00
|
|
|
|
2019-09-01 14:03:19 +00:00
|
|
|
Return the view to be passed to the text templating engine for this plugin.
|
2019-08-27 14:59:25 +00:00
|
|
|
`pkg` is the name of the package being generated.
|
2019-09-01 14:03:19 +00:00
|
|
|
|
|
|
|
For [`BasicPlugin`](@ref)s, this is used for both the plugin badges (see [`badges`](@ref)) and the template file (see [`source`](@ref)).
|
|
|
|
For other [`Plugin`](@ref)s, it is used only for badges, but you can always call it yourself as part of your [`gen_plugin`](@ref) implementation.
|
|
|
|
|
|
|
|
By default, an empty `Dict` is returned.
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
For more information on templating with Mustache, see the [Mustache.jl](https://github.com/jverzani/Mustache.jl) documentation.
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
|
2017-08-17 22:06:05 +00:00
|
|
|
|
2019-08-27 14:59:25 +00:00
|
|
|
"""
|
|
|
|
user_view(::Plugin, ::Template, pkg::AbstractString) -> Dict{String, Any}
|
|
|
|
|
2019-09-01 14:03:19 +00:00
|
|
|
The same as [`view`](@ref), but for use by package *users* for extension.
|
|
|
|
|
|
|
|
For example, suppose you were using the [`Readme`](@ref) with a custom template file that looked like this:
|
|
|
|
|
|
|
|
```md
|
|
|
|
# {{PKG}}
|
|
|
|
|
|
|
|
Created on *{{TODAY}}*.
|
|
|
|
```
|
|
|
|
|
|
|
|
The [`view`](@ref) function supplies a value for `PKG`, but it does not supply a value for `TODAY`.
|
|
|
|
Rather than override [`view`](@ref), we can implement this function to get both the default values and whatever else we need to add.
|
|
|
|
|
|
|
|
```julia
|
|
|
|
user_view(::Readme, ::Template, ::AbstractString) = Dict("TODAY" => today())
|
|
|
|
```
|
|
|
|
|
|
|
|
Values returned by this function will override those from [`view`](@ref) when the keys are the same.
|
2019-08-27 14:59:25 +00:00
|
|
|
"""
|
|
|
|
user_view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
|
|
|
|
|
|
|
|
"""
|
|
|
|
tags(::Plugin) -> Tuple{String, String}
|
|
|
|
|
|
|
|
Return the tags used for Mustache templating.
|
2019-09-01 14:03:19 +00:00
|
|
|
See the [`Citation`](@ref) plugin for a rare case where changing the tags is necessary.
|
|
|
|
|
|
|
|
By default, the tags are `"{{"` and `"}}"`.
|
2019-08-27 14:59:25 +00:00
|
|
|
"""
|
|
|
|
tags(::Plugin) = ("{{", "}}")
|
|
|
|
|
2017-08-17 22:06:05 +00:00
|
|
|
"""
|
2019-02-05 17:31:51 +00:00
|
|
|
gitignore(::Plugin) -> Vector{String}
|
2017-08-17 06:57:58 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
Return patterns that should be added to `.gitignore`.
|
2019-09-01 14:03:19 +00:00
|
|
|
These are used by the [`Gitignore`](@ref) plugin.
|
|
|
|
|
|
|
|
By default, an empty list is returned.
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
gitignore(::Plugin) = String[]
|
2017-12-01 17:33:57 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
badges(::Plugin) -> Union{Badge, Vector{Badge}}
|
2017-12-01 17:33:57 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
Return a list of [`Badge`](@ref)s, or just one, to be added to `README.md`.
|
2019-09-01 14:03:19 +00:00
|
|
|
These are used by the [`Readme`](@ref) plugin to add badges to the README.
|
|
|
|
|
|
|
|
By default, an empty list is returned.
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
badges(::Plugin) = Badge[]
|
2017-12-01 17:33:57 +00:00
|
|
|
|
2017-08-17 06:57:58 +00:00
|
|
|
"""
|
2019-02-05 17:31:51 +00:00
|
|
|
source(::BasicPlugin) -> Union{String, Nothing}
|
2017-08-22 16:25:00 +00:00
|
|
|
|
2019-09-01 14:03:19 +00:00
|
|
|
Return the path to a plugin's template file, or `nothing` to indicate no file.
|
|
|
|
|
|
|
|
By default, `nothing` is returned.
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
source(::BasicPlugin) = nothing
|
2017-08-17 22:06:05 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
destination(::BasicPlugin) -> String
|
2017-08-22 16:25:00 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
Return the destination, relative to the package root, of a plugin's configuration file.
|
2019-09-01 14:03:19 +00:00
|
|
|
|
|
|
|
This function **must** be implemented.
|
2017-08-17 22:06:05 +00:00
|
|
|
"""
|
2019-02-05 17:31:51 +00:00
|
|
|
function destination end
|
2017-08-17 06:57:58 +00:00
|
|
|
|
2017-08-18 04:06:15 +00:00
|
|
|
"""
|
|
|
|
Badge(hover::AbstractString, image::AbstractString, link::AbstractString) -> Badge
|
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
Container for Markdown badge data.
|
2019-09-01 14:03:19 +00:00
|
|
|
Each argument can contain placeholders (which will be filled in with values from [`combined_view`](@ref)).
|
2017-08-18 04:06:15 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
## Arguments
|
2017-08-18 04:06:15 +00:00
|
|
|
* `hover::AbstractString`: Text to appear when the mouse is hovered over the badge.
|
|
|
|
* `image::AbstractString`: URL to the image to display.
|
|
|
|
* `link::AbstractString`: URL to go to upon clicking the badge.
|
|
|
|
"""
|
2018-12-20 19:21:17 +00:00
|
|
|
struct Badge
|
|
|
|
hover::String
|
|
|
|
image::String
|
|
|
|
link::String
|
2017-08-18 04:06:15 +00:00
|
|
|
end
|
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
Base.string(b::Badge) = "[)]($(b.link))"
|
2017-08-18 04:06:15 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
# Format a plugin's badges as a list of strings, with all substitutions applied.
|
2019-08-27 14:59:25 +00:00
|
|
|
function badges(p::Plugin, t::Template, pkg::AbstractString)
|
2019-02-05 17:31:51 +00:00
|
|
|
bs = badges(p)
|
|
|
|
bs isa Vector || (bs = [bs])
|
2019-08-27 14:59:25 +00:00
|
|
|
return map(b -> render_text(string(b), combined_view(p, t, pkg)), bs)
|
2019-02-05 17:31:51 +00:00
|
|
|
end
|
2017-08-18 04:06:15 +00:00
|
|
|
|
2017-08-17 06:57:58 +00:00
|
|
|
"""
|
2019-08-27 14:59:25 +00:00
|
|
|
gen_plugin(::Plugin, ::Template, pkg::AbstractString)
|
2017-08-17 06:57:58 +00:00
|
|
|
|
2019-08-27 14:59:25 +00:00
|
|
|
Perform any work associated with a plugin.
|
2019-08-27 11:17:15 +00:00
|
|
|
`pkg` is the name of the package being generated.
|
2019-09-01 14:03:19 +00:00
|
|
|
|
|
|
|
For [`Plugin`](@ref)s that are not [`BasicPlugin`](@ref)s, this is the only function that really needs to be implemented.
|
|
|
|
If you want your plugin to do anything at all during package generation, you should implement it here.
|
|
|
|
|
|
|
|
You should **not** implement this function for `BasicPlugin`s.
|
2019-02-05 17:31:51 +00:00
|
|
|
"""
|
|
|
|
gen_plugin(::Plugin, ::Template, ::AbstractString) = nothing
|
|
|
|
|
2019-08-27 14:59:25 +00:00
|
|
|
function gen_plugin(p::BasicPlugin, t::Template, pkg_dir::AbstractString)
|
2019-08-29 16:04:11 +00:00
|
|
|
source(p) === nothing && return
|
2019-08-27 14:59:25 +00:00
|
|
|
pkg = basename(pkg_dir)
|
|
|
|
path = joinpath(pkg_dir, destination(p))
|
|
|
|
text = render_plugin(p, t, pkg)
|
|
|
|
gen_file(path, text)
|
|
|
|
end
|
|
|
|
|
|
|
|
function render_plugin(p::BasicPlugin, t::Template, pkg::AbstractString)
|
2019-08-27 11:17:15 +00:00
|
|
|
# TODO template rendering code
|
2019-08-29 16:04:11 +00:00
|
|
|
return render_file(source(p), combined_view(p, t, pkg), tags(p))
|
2017-08-17 22:06:05 +00:00
|
|
|
end
|
|
|
|
|
2019-09-01 14:03:19 +00:00
|
|
|
"""
|
|
|
|
combined_view(::Plugin, ::Template, pkg::AbstractString) -> Dict{String, Any}
|
|
|
|
|
|
|
|
This function combines [`view`](@ref) and [`user_view`](@ref) for use in text templating.
|
|
|
|
If you're doing manual creation (i.e. writing [`Plugin`](@ref)s that are not [`BasicPlugin`](@ref)s, then you should use this function rather than either of the former two.
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
You should **not** implement this function yourself.
|
|
|
|
"""
|
2019-08-27 14:59:25 +00:00
|
|
|
function combined_view(p::Plugin, t::Template, pkg::AbstractString)
|
|
|
|
return merge(view(p, t, pkg), user_view(p, t, pkg))
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-17 22:06:05 +00:00
|
|
|
"""
|
2019-08-27 11:17:15 +00:00
|
|
|
gen_file(file::AbstractString, text::AbstractString)
|
2017-08-17 22:06:05 +00:00
|
|
|
|
2019-02-05 17:31:51 +00:00
|
|
|
Create a new file containing some given text.
|
|
|
|
Trailing whitespace is removed, and the file will end with a newline.
|
|
|
|
"""
|
|
|
|
function gen_file(file::AbstractString, text::AbstractString)
|
|
|
|
mkpath(dirname(file))
|
2019-08-29 16:04:11 +00:00
|
|
|
text = strip(join(map(rstrip, split(text, "\n")), "\n")) * "\n"
|
2019-02-05 17:31:51 +00:00
|
|
|
write(file, text)
|
|
|
|
end
|
2017-08-17 22:06:05 +00:00
|
|
|
|
2019-08-27 14:59:25 +00:00
|
|
|
# Render text from a file.
|
2019-08-29 16:04:11 +00:00
|
|
|
function render_file(file::AbstractString, view::Dict{<:AbstractString}, tags)
|
|
|
|
render_text(read(file, String), view, tags)
|
|
|
|
end
|
2017-08-17 22:06:05 +00:00
|
|
|
|
2019-08-29 16:04:11 +00:00
|
|
|
# Render text using Mustache's templating system. HTML escaping is disabled.
|
2019-08-27 14:59:25 +00:00
|
|
|
function render_text(text::AbstractString, view::Dict{<:AbstractString}, tags=nothing)
|
|
|
|
saved = copy(entityMap)
|
|
|
|
empty!(entityMap)
|
|
|
|
return try
|
|
|
|
if tags === nothing
|
|
|
|
render(text, view)
|
|
|
|
else
|
|
|
|
render(text, view; tags=tags)
|
|
|
|
end
|
|
|
|
finally
|
|
|
|
append!(entityMap, saved)
|
|
|
|
end
|
2017-08-21 19:53:00 +00:00
|
|
|
end
|
2019-02-05 17:31:51 +00:00
|
|
|
|
2019-08-29 16:04:11 +00:00
|
|
|
include(joinpath("plugins", "defaults.jl"))
|
2019-02-05 17:31:51 +00:00
|
|
|
include(joinpath("plugins", "coverage.jl"))
|
|
|
|
include(joinpath("plugins", "ci.jl"))
|
|
|
|
include(joinpath("plugins", "citation.jl"))
|
|
|
|
include(joinpath("plugins", "documenter.jl"))
|