Lots of documentation changes
This commit is contained in:
parent
2d7c851fca
commit
7a2a43f3f4
@ -28,9 +28,9 @@ matrix:
|
||||
- stage: Documentation
|
||||
julia: 1.0
|
||||
script:
|
||||
- git config --global user.name Your-Name
|
||||
- git config --global user.email your-email
|
||||
- git config --global github.user your-username
|
||||
- git config --global user.name name
|
||||
- git config --global user.email email
|
||||
- git config --global github.user username
|
||||
- julia --project=docs -e '
|
||||
using Pkg;
|
||||
Pkg.develop(PackageSpec(; path=pwd()));
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Documenter
|
||||
using Documenter: Documenter, makedocs, deploydocs
|
||||
using PkgTemplates: PkgTemplates
|
||||
|
||||
makedocs(;
|
||||
@ -11,7 +11,8 @@ makedocs(;
|
||||
assets=String[],
|
||||
),
|
||||
pages=[
|
||||
"Home" => "user.md",
|
||||
"Home" => "index.md",
|
||||
"User Guide" => "user.md",
|
||||
"Developer Guide" => "developer.md",
|
||||
],
|
||||
)
|
||||
|
@ -4,28 +4,237 @@ CurrentModule = PkgTemplates
|
||||
|
||||
# PkgTemplates Developer Guide
|
||||
|
||||
```@contents
|
||||
Pages = ["developer.md"]
|
||||
```
|
||||
|
||||
PkgTemplates can be easily extended by adding new [`Plugin`](@ref)s.
|
||||
|
||||
## The `Plugin` Interface
|
||||
There are two types of plugins: [`Plugin`](@ref) and [`BasicPlugin`](@ref).
|
||||
|
||||
```@docs
|
||||
Plugin
|
||||
BasicPlugin
|
||||
```
|
||||
|
||||
## `Plugin` Walkthrough
|
||||
|
||||
Concrete types that subtype [`Plugin`](@ref) directly are free to do almost anything.
|
||||
To understand how they're implemented, let's look at a simplified version of [`Documenter`](@ref):
|
||||
|
||||
```julia
|
||||
@with_kw_noshow struct Documenter <: Plugin
|
||||
make_jl::String = default_file("make.jl")
|
||||
index_md::String = default_file("index.md")
|
||||
end
|
||||
|
||||
gitignore(::Documenter) = ["/docs/build/", "/docs/site/"]
|
||||
|
||||
badges(::Documenter) = [
|
||||
Badge(
|
||||
"Stable",
|
||||
"https://img.shields.io/badge/docs-stable-blue.svg",
|
||||
"https://{{USER}}.github.io/{{PKG}}.jl/stable",
|
||||
),
|
||||
Badge(
|
||||
"Dev",
|
||||
"https://img.shields.io/badge/docs-dev-blue.svg",
|
||||
"https://{{USER}}.github.io/{{PKG}}.jl/dev",
|
||||
),
|
||||
]
|
||||
|
||||
view(p::Documenter, t::Template, pkg::AbstractString) = Dict(
|
||||
"AUTHORS" => join(t.authors, ", "),
|
||||
"PKG" => pkg,
|
||||
"REPO" => "$(t.host)/$(t.user)/$pkg.jl",
|
||||
"USER" => t.user,
|
||||
)
|
||||
|
||||
function gen_plugin(p::Documenter, t::Template, pkg_dir::AbstractString)
|
||||
pkg = basename(pkg_dir)
|
||||
docs_dir = joinpath(pkg_dir, "docs")
|
||||
|
||||
make = render_file(p.make_jl, combined_view(p, t, pkg), tags(p))
|
||||
gen_file(joinpath(docs_dir, "make.jl"), make)
|
||||
|
||||
index = render_file(p.index_md, combined_view(p, t, pkg), tags(p))
|
||||
gen_file(joinpath(docs_dir, "src", "index.md"), index)
|
||||
|
||||
# What this function does is not relevant here.
|
||||
create_documentation_project()
|
||||
end
|
||||
```
|
||||
|
||||
First of all, `@with_kw_noshow` comes from [Parameters.jl](https://github.com/mauro3/Parameters.jl), and it just defines a nice keyword constructor for us.
|
||||
The default values for our type are using [`default_file`](@ref) to point to files in this repository.
|
||||
|
||||
```@docs
|
||||
default_file
|
||||
```
|
||||
|
||||
The first method we implement for `Documenter` is [`gitignore`](@ref), so that packages created with this plugin ignore documentation build artifacts.
|
||||
|
||||
```@docs
|
||||
gitignore
|
||||
```
|
||||
|
||||
Second, we implement [`badges`](@ref) to add a couple of badges to new packages' README files.
|
||||
|
||||
```@docs
|
||||
badges
|
||||
Badge
|
||||
```
|
||||
|
||||
Third, we implement [`view`](@ref), which is used to fill placeholders in badges and rendered files.
|
||||
|
||||
```@docs
|
||||
view
|
||||
```
|
||||
|
||||
Finally, we implement [`gen_plugin`](@ref), which is the real workhorse for the plugin.
|
||||
|
||||
```@docs
|
||||
gen_plugin
|
||||
gitignore
|
||||
badges
|
||||
Badge
|
||||
view
|
||||
user_view
|
||||
```
|
||||
|
||||
Inside of this function, we call a few more functions, which help us with text templating.
|
||||
|
||||
```@docs
|
||||
render_file
|
||||
render_text
|
||||
gen_file
|
||||
combined_view
|
||||
tags
|
||||
```
|
||||
|
||||
## The `BasicPlugin` Interface
|
||||
todo more
|
||||
|
||||
While subtyping [`Plugin`](@ref) gives you complete freedom, it's not always necessary.
|
||||
For more constrained cases, a simpler API exists.
|
||||
## `BasicPlugin` Walkthrough
|
||||
|
||||
Plugins that subtype [`BasicPlugin`](@ref) perform a much more limited task.
|
||||
In general, they just generate one templated file.
|
||||
|
||||
To illustrate, let's look at the [`Citation`](@ref) plugin, which creates a `CITATION.bib` file.
|
||||
|
||||
```julia
|
||||
@with_kw_noshow struct Citation <: BasicPlugin
|
||||
file::String = default_file("CITATION.bib")
|
||||
end
|
||||
|
||||
source(p::Citation) = p.file
|
||||
destination(::Citation) = "CITATION.bib"
|
||||
|
||||
tags(::Citation) = "<<", ">>"
|
||||
|
||||
view(::Citation, t::Template, pkg::AbstractString) = Dict(
|
||||
"AUTHORS" => join(t.authors, ", "),
|
||||
"MONTH" => month(today()),
|
||||
"PKG" => pkg,
|
||||
"URL" => "https://$(t.host)/$(t.user)/$pkg.jl",
|
||||
"YEAR" => year(today()),
|
||||
)
|
||||
```
|
||||
|
||||
Similar to the `Documenter` example above, we're defining a keyword constructor, and assigning a default template file from this repository.
|
||||
This plugin adds nothing to `.gitignore`, and it doesn't add any badges, so implementations for [`gitignore`](@ref) and [`badges`](@ref) are omitted.
|
||||
|
||||
First, we implement [`source`](@ref) and [`destination`](@ref) to define where the template file comes from, and where it goes.
|
||||
These functions are specific to [`BasicPlugin`](@ref)s, and have no effect on regular [`Plugin`](@ref)s by default.
|
||||
|
||||
```@docs
|
||||
BasicPlugin
|
||||
source
|
||||
destination
|
||||
```
|
||||
|
||||
Next, we implement [`tags`](@ref).
|
||||
We briefly saw this function earlier, but in this case it's necessary to change its behaviour from the default.
|
||||
To see why, it might help to see the template file in its entirety:
|
||||
|
||||
```
|
||||
@misc{<<PKG>>.jl,
|
||||
author = {<<AUTHORS>>},
|
||||
title = {<<PKG>>.jl},
|
||||
url = {<<URL>>},
|
||||
version = {v0.1.0},
|
||||
year = {<<YEAR>>},
|
||||
month = {<<MONTH>>}
|
||||
}
|
||||
```
|
||||
|
||||
Because the file contains its own `{}` delimiters, we need to use different ones for templating to work properly.
|
||||
|
||||
Finally, we implement [`view`](@ref) to fill in the placeholders that we saw in the template file.
|
||||
|
||||
## Doing Extra Work With `BasicPlugin`s
|
||||
|
||||
Notice that we didn't have to implement [`gen_plugin`](@ref) for our plugin.
|
||||
It's implemented for all [`BasicPlugin`](@ref)s, like so:
|
||||
|
||||
```julia
|
||||
function render_plugin(p::BasicPlugin, t::Template, pkg::AbstractString)
|
||||
return render_file(source(p), combined_view(p, t, pkg), tags(p))
|
||||
end
|
||||
|
||||
function gen_plugin(p::BasicPlugin, t::Template, pkg_dir::AbstractString)
|
||||
source(p) === nothing && return
|
||||
pkg = basename(pkg_dir)
|
||||
path = joinpath(pkg_dir, destination(p))
|
||||
text = render_plugin(p, t, pkg)
|
||||
gen_file(path, text)
|
||||
end
|
||||
```
|
||||
|
||||
But what if we want to do a little more than just generate one file?
|
||||
|
||||
A good example of this is the [`Tests`](@ref) plugin.
|
||||
It creates `runtests.jl`, but it also modifies the `Project.toml` to include the `Test` dependency.
|
||||
|
||||
Of course, we could use a normal [`Plugin`](@ref), but it turns out there's a way to avoid that while still getting the extra capbilities that we want.
|
||||
|
||||
The plugin implements its own `gen_plugin`, but uses `invoke` to avoid duplicating the file creation code:
|
||||
|
||||
```julia
|
||||
@with_kw_noshow struct Tests <: BasicPlugin
|
||||
file::String = default_file("runtests.jl")
|
||||
end
|
||||
|
||||
source(p::Tests) = p.file
|
||||
destination(::Tests) = joinpath("test", "runtests.jl")
|
||||
view(::Tests, ::Template, pkg::AbstractString) = Dict("PKG" => pkg)
|
||||
|
||||
function gen_plugin(p::Tests, t::Template, pkg_dir::AbstractString)
|
||||
# Do the normal BasicPlugin behaviour to create the test script.
|
||||
invoke(gen_plugin, Tuple{BasicPlugin, Template, AbstractString}, p, t, pkg_dir)
|
||||
# Do some other work.
|
||||
add_test_dependency()
|
||||
end
|
||||
```
|
||||
|
||||
For more examples, see the plugins in the [Continuous Integration (CI)](@ref) and [Code Coverage](@ref) sections.
|
||||
|
||||
## Miscellaneous Tips
|
||||
|
||||
### Writing Template Files
|
||||
|
||||
For an overview of writing template files for Mustache.jl, see [Custom Template Files](@ref) in the user guide.
|
||||
|
||||
### Traits
|
||||
|
||||
There are a few traits for plugin types that are occassionally used to answer questions like "does this `Template` have any code coverage plugins?".
|
||||
If you're implementing a plugin that fits into one of the following categories, it would be wise to implement the corresponding trait function to return `true` for your type.
|
||||
|
||||
```@docs
|
||||
is_ci
|
||||
is_coverage
|
||||
```
|
||||
|
||||
### Formatting Version Numbers
|
||||
|
||||
When writing configuration files for CI services, working with version numbers is often needed.
|
||||
There are a few convenience functions that can be used to make this a little bit easier.
|
||||
|
||||
```@docs
|
||||
compat_version
|
||||
format_version
|
||||
collect_versions
|
||||
```
|
||||
|
25
docs/src/index.md
Normal file
25
docs/src/index.md
Normal file
@ -0,0 +1,25 @@
|
||||
```@meta
|
||||
CurrentModule = PkgTemplates
|
||||
```
|
||||
|
||||
# PkgTemplates
|
||||
|
||||
**PkgTemplates creates new Julia packages in an easy, repeatable, and customizable way.**
|
||||
|
||||
### Foreword: Templating vs. Template
|
||||
|
||||
This documentation refers plenty to [`Template`](@ref)s, the package's main type.
|
||||
But it also refers to "template files" and "text templating", which are plaintext files with placeholders to be filled with data, and the technique of filling those placeholders with data, respectively.
|
||||
|
||||
These concepts should be familiar if you've used [Jinja](https://palletsprojects.com/p/jinja) or [Mustache](https://mustache.github.io) (Mustache is the particular flavour used by PkgTemplates, via [Mustache.jl](https://github.com/jverzani/Mustache.jl)).
|
||||
|
||||
### Documentation
|
||||
|
||||
If you're looking to **create new packages**, see the [User Guide](user.md).
|
||||
|
||||
If you want to **create new plugins**, see the [Developer Guide](developer.md).
|
||||
|
||||
### Index
|
||||
|
||||
```@index
|
||||
```
|
114
docs/src/user.md
114
docs/src/user.md
@ -4,6 +4,10 @@ CurrentModule = PkgTemplates
|
||||
|
||||
# PkgTemplates User Guide
|
||||
|
||||
```@contents
|
||||
Pages = ["user.md"]
|
||||
```
|
||||
|
||||
Using PkgTemplates is straightforward.
|
||||
Just create a [`Template`](@ref), and call it on a package name to generate that package.
|
||||
|
||||
@ -15,16 +19,12 @@ Template
|
||||
|
||||
## Plugins
|
||||
|
||||
Plugins are PkgTemplates' source of customization and extensibility.
|
||||
Add plugins to your templates to enable extra pieces of repository setup.
|
||||
|
||||
```@docs
|
||||
Plugin
|
||||
```
|
||||
Plugins add functionality to `Template`s.
|
||||
There are a number of plugins available to automate common boilerplate tasks.
|
||||
|
||||
### Defaults
|
||||
|
||||
These plugins are included in [`Template`](@ref)s by default.
|
||||
These plugins are included by default.
|
||||
They can be overridden by supplying another value via the `plugins` keyword, or disabled by supplying the type via the `disable_defaults` keyword.
|
||||
|
||||
```@docs
|
||||
@ -66,6 +66,106 @@ Documenter
|
||||
Citation
|
||||
```
|
||||
|
||||
## Custom Template Files
|
||||
|
||||
Many plugins support a `file` argument or similar, which sets the path to the template file to be used for generating files.
|
||||
Each plugin has a sensible default that should make sense for most people, but you might have a specialized workflow that requires a totally different template file.
|
||||
|
||||
If that's the case, a basic understanding of [Mustache](https://mustache.github.io)'s syntax is required.
|
||||
Here's an example template file:
|
||||
|
||||
```
|
||||
Hello, {{name}}.
|
||||
|
||||
{{#weather}}
|
||||
It's {{weather}} outside.
|
||||
{{/weather}}
|
||||
{{^weather}}
|
||||
I don't know what the weather outside is.
|
||||
{{/weather}}
|
||||
|
||||
{{#has_things}}
|
||||
I have the following things:
|
||||
{{/has_things}}
|
||||
{{#things}}
|
||||
- Here's a thing: {{.}}
|
||||
{{/things}}
|
||||
|
||||
{{#people}}
|
||||
- {{name}} is {{mood}}
|
||||
{{/people}}
|
||||
```
|
||||
|
||||
In the first section, `name` is a key, and its value replaces `{{name}}`.
|
||||
|
||||
In the second section, `weather`'s value may or may not exist.
|
||||
If it does exist, then "It's $weather outside" is printed.
|
||||
Otherwise, "I don't know what the weather outside is" is printed.
|
||||
Mustache uses a notion of "truthiness" similar to Python or JavaScript, where values of `nothing`, `false`, or empty collections are all considered to not exist.
|
||||
|
||||
In the third section, `has_things`' value is printed if it's truthy.
|
||||
Then, if the `things` list is truthy (i.e. not empty), its values are each printed on their own line.
|
||||
The reason that we have two separate keys is that `{{#things}}` iterates over the whole `things` list, even when there are no `{{.}}` placeholders, which would duplicate "I have the following things:" `n` times.
|
||||
|
||||
The fourth section iterates over the `people` list, but instead of using the `{{.}}` placeholder, we have `name` and `mood`, which are keys or fields of the list elements.
|
||||
Most types are supported here, including `Dict`s and structs.
|
||||
`NamedTuple`s require you to use `{{:name}}` instead of the normal `{{name}}`, though.
|
||||
|
||||
Assuming the following view:
|
||||
|
||||
```julia
|
||||
struct Person; name::String; mood::String; end
|
||||
things = ["a", "b", "c"]
|
||||
view = Dict(
|
||||
"name" => "Chris",
|
||||
"weather" => "sunny",
|
||||
"has_things" => !isempty(things),
|
||||
"things" => things,
|
||||
"people" => [Person("John", "happy"), Person("Jane", "sad")],
|
||||
)
|
||||
```
|
||||
|
||||
Our example template would produce this:
|
||||
|
||||
```
|
||||
Hello, Chris.
|
||||
|
||||
It's sunny outside.
|
||||
|
||||
I have the following things:
|
||||
- Here's a thing: a
|
||||
- Here's a thing: b
|
||||
- Here's a thing: c
|
||||
|
||||
- John is happy
|
||||
- Jane is sad
|
||||
```
|
||||
|
||||
## Extending Existing Plugins
|
||||
|
||||
Most of the existing plugins generate a file from a template file.
|
||||
If you want to use custom template files, you may run into situations where the data passed into the templating engine is not sufficient.
|
||||
In this case, you can look into implementing [`user_view`](@ref) to supply whatever data is necessary for your use case.
|
||||
|
||||
```@docs
|
||||
user_view
|
||||
```
|
||||
|
||||
For example, suppose you were using the [`Readme`](@ref) plugin 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())
|
||||
```
|
||||
|
||||
## Saving Templates
|
||||
|
||||
One of the main reasons for PkgTemplates' existence is for new packages to be consistent.
|
||||
|
@ -5,7 +5,7 @@ using Base.Filesystem: contractuser
|
||||
|
||||
using Dates: month, today, year
|
||||
using InteractiveUtils: subtypes
|
||||
using LibGit2: LibGit2
|
||||
using LibGit2: LibGit2, GitRemote
|
||||
using Pkg: Pkg, TOML, PackageSpec
|
||||
using REPL.TerminalMenus: MultiSelectMenu, RadioMenu, request
|
||||
|
||||
@ -28,7 +28,10 @@ export
|
||||
TravisCI
|
||||
|
||||
"""
|
||||
A plugin to be added to a [`Template`](@ref), which adds some functionality or integration.
|
||||
Plugins are PkgTemplates' source of customization and extensibility.
|
||||
Add plugins to your [`Template`](@ref)s to enable extra pieces of repository setup.
|
||||
|
||||
When implementing a new plugin, subtype this type to have full control over its behaviour.
|
||||
"""
|
||||
abstract type Plugin end
|
||||
|
||||
|
@ -31,10 +31,10 @@ function (t::Template)(pkg::AbstractString)
|
||||
else
|
||||
"https://$(t.host)/$(t.user)/$pkg.jl"
|
||||
end
|
||||
remote = LibGit2.GitRemote(repo, "origin", url)
|
||||
# TODO: `git pull` still requires some Git branch config.
|
||||
LibGit2.add_push!(repo, remote, "refs/heads/master")
|
||||
close(remote)
|
||||
LibGit2.with(GitRemote(repo, "origin", url)) do remote
|
||||
# TODO: `git pull` still requires some Git branch config.
|
||||
LibGit2.add_push!(repo, remote, "refs/heads/master")
|
||||
end
|
||||
end
|
||||
|
||||
# Generate the files.
|
||||
@ -66,10 +66,14 @@ function (t::Template)(pkg::AbstractString)
|
||||
end
|
||||
end
|
||||
|
||||
# Format the version to be included in Project.toml's [compat] section.
|
||||
"""
|
||||
compat_version(v::VersionNumber) -> String
|
||||
|
||||
Format a `VersionNumber` to exclude trailing zero components.
|
||||
"""
|
||||
function compat_version(v::VersionNumber)
|
||||
return if v.patch == 0 && v.minor == 0
|
||||
string(v.major)
|
||||
"$(v.major)"
|
||||
elseif v.patch == 0
|
||||
"$(v.major).$(v.minor)"
|
||||
else
|
||||
|
@ -1,31 +1,15 @@
|
||||
const DEFAULTS_DIR = normpath(joinpath(@__DIR__, "..", "defaults"))
|
||||
|
||||
badge_order() = [
|
||||
Documenter{GitLabCI},
|
||||
Documenter{TravisCI},
|
||||
GitLabCI,
|
||||
TravisCI,
|
||||
AppVeyor,
|
||||
CirrusCI,
|
||||
Codecov,
|
||||
Coveralls,
|
||||
]
|
||||
|
||||
"""
|
||||
A simple plugin that, in general, creates a single file.
|
||||
|
||||
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).
|
||||
"""
|
||||
abstract type BasicPlugin <: Plugin end
|
||||
|
||||
# Compute the path to a default template file in this repository.
|
||||
"""
|
||||
default_file(paths::AbstractString...) -> String
|
||||
|
||||
Return a path relative to the default template file directory (`$(contractuser(DEFAULTS_DIR))`).
|
||||
"""
|
||||
default_file(paths::AbstractString...) = joinpath(DEFAULTS_DIR, paths...)
|
||||
|
||||
"""
|
||||
@ -38,9 +22,6 @@ For [`BasicPlugin`](@ref)s, this is used for both the plugin badges (see [`badge
|
||||
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.
|
||||
"""
|
||||
view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
|
||||
|
||||
@ -49,34 +30,34 @@ view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
|
||||
|
||||
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.
|
||||
"""
|
||||
user_view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
|
||||
|
||||
"""
|
||||
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 file creation or text templating (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
|
||||
Do not implement this function yourself!
|
||||
If you're implementing a plugin, you should implement [`view`](@ref).
|
||||
If you're customizing a plugin as a user, you should implement [`user_view`](@ref).
|
||||
"""
|
||||
function combined_view(p::Plugin, t::Template, pkg::AbstractString)
|
||||
return merge(view(p, t, pkg), user_view(p, t, pkg))
|
||||
end
|
||||
|
||||
"""
|
||||
tags(::Plugin) -> Tuple{String, String}
|
||||
|
||||
Return the tags used for Mustache templating.
|
||||
Return the delimiters used for text templating.
|
||||
See the [`Citation`](@ref) plugin for a rare case where changing the tags is necessary.
|
||||
|
||||
By default, the tags are `"{{"` and `"}}"`.
|
||||
"""
|
||||
tags(::Plugin) = ("{{", "}}")
|
||||
tags(::Plugin) = "{{", "}}"
|
||||
|
||||
"""
|
||||
gitignore(::Plugin) -> Vector{String}
|
||||
@ -117,7 +98,7 @@ This function **must** be implemented.
|
||||
function destination end
|
||||
|
||||
"""
|
||||
Badge(hover::AbstractString, image::AbstractString, link::AbstractString) -> Badge
|
||||
Badge(hover::AbstractString, image::AbstractString, link::AbstractString)
|
||||
|
||||
Container for Markdown badge data.
|
||||
Each argument can contain placeholders (which will be filled in with values from [`combined_view`](@ref)).
|
||||
@ -164,24 +145,9 @@ function gen_plugin(p::BasicPlugin, t::Template, pkg_dir::AbstractString)
|
||||
end
|
||||
|
||||
function render_plugin(p::BasicPlugin, t::Template, pkg::AbstractString)
|
||||
# TODO template rendering code
|
||||
return render_file(source(p), combined_view(p, t, pkg), tags(p))
|
||||
end
|
||||
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
function combined_view(p::Plugin, t::Template, pkg::AbstractString)
|
||||
return merge(view(p, t, pkg), user_view(p, t, pkg))
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
gen_file(file::AbstractString, text::AbstractString)
|
||||
|
||||
@ -194,12 +160,22 @@ function gen_file(file::AbstractString, text::AbstractString)
|
||||
write(file, text)
|
||||
end
|
||||
|
||||
# Render text from a file.
|
||||
"""
|
||||
render_file(file::AbstractString view::Dict{<:AbstractString}, tags) -> String
|
||||
|
||||
Render a template file with the data in `view`.
|
||||
`tags` should be a tuple of two strings, which are the opening and closing delimiters, or `nothing` to use the default delimiters.
|
||||
"""
|
||||
function render_file(file::AbstractString, view::Dict{<:AbstractString}, tags)
|
||||
render_text(read(file, String), view, tags)
|
||||
end
|
||||
|
||||
# Render text using Mustache's templating system. HTML escaping is disabled.
|
||||
"""
|
||||
render_text(text::AbstractString, view::Dict{<:AbstractString}, tags=nothing) -> String
|
||||
|
||||
Render some text with the data in `view`.
|
||||
`tags` should be a tuple of two strings, which are the opening and closing delimiters, or `nothing` to use the default delimiters.
|
||||
"""
|
||||
function render_text(text::AbstractString, view::Dict{<:AbstractString}, tags=nothing)
|
||||
saved = copy(entityMap)
|
||||
empty!(entityMap)
|
||||
|
@ -1,4 +1,9 @@
|
||||
# Strip everything but the major and minor release from a version number.
|
||||
"""
|
||||
format_version(v::Union{VersionNumber, AbstractString}) -> String
|
||||
|
||||
Strip everything but the major and minor release from a `VersionNumber`.
|
||||
Strings are left in their original form.
|
||||
"""
|
||||
format_version(v::VersionNumber) = "$(v.major).$(v.minor)"
|
||||
format_version(v::AbstractString) = string(v)
|
||||
|
||||
@ -6,11 +11,10 @@ const ALLOWED_FAILURES = ["1.3", "nightly"] # TODO: Update this list with new R
|
||||
const DEFAULT_CI_VERSIONS = map(format_version, [default_version(), VERSION, "nightly"])
|
||||
const EXTRA_VERSIONS_DOC = "- `extra_versions::Vector`: Extra Julia versions to test, as strings or `VersionNumber`s."
|
||||
|
||||
|
||||
"""
|
||||
collect_versions(t::Template, versions::Vector) -> Vector{String}
|
||||
|
||||
Combine the [`Template`](@ref)'s Julia version and some other versions, and format them as `major.minor`.
|
||||
Combine `t`'s Julia version with `versions`, and format them as `major.minor`.
|
||||
This is useful for creating lists of versions to be included in CI configurations.
|
||||
"""
|
||||
function collect_versions(t::Template, versions::Vector)
|
||||
@ -27,7 +31,7 @@ end
|
||||
x86=false,
|
||||
coverage=true,
|
||||
extra_versions=$DEFAULT_CI_VERSIONS,
|
||||
) -> TravisCI
|
||||
)
|
||||
|
||||
Integrates your packages with [Travis CI](https://travis-ci.com).
|
||||
|
||||
@ -99,7 +103,7 @@ end
|
||||
x86=false,
|
||||
coverage=true,
|
||||
extra_versions=$DEFAULT_CI_VERSIONS,
|
||||
) -> AppVeyor
|
||||
)
|
||||
|
||||
Integrates your packages with [AppVeyor](https://appveyor.com) via [AppVeyor.jl](https://github.com/JuliaCI/Appveyor.jl).
|
||||
|
||||
@ -149,7 +153,7 @@ end
|
||||
image="freebsd-12-0-release-amd64",
|
||||
coverage=true,
|
||||
extra_versions=$DEFAULT_CI_VERSIONS,
|
||||
) -> CirrusCI
|
||||
)
|
||||
|
||||
Integrates your packages with [Cirrus CI](https://cirrus-ci.org) via [CirrusCI.jl](https://github.com/ararslan/CirrusCI.jl).
|
||||
|
||||
@ -195,7 +199,7 @@ end
|
||||
file="$(contractuser(default_file("gitlab-ci.yml")))",
|
||||
coverage=true,
|
||||
extra_versions=$DEFAULT_CI_VERSIONS,
|
||||
) -> GitLabCI
|
||||
)
|
||||
|
||||
Integrates your packages with [GitLab CI](https://docs.gitlab.com/ce/ci/).
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
Citation(;
|
||||
file="$(contractuser(default_file("CITATION.bib")))",
|
||||
readme=false,
|
||||
) -> Citation
|
||||
)
|
||||
|
||||
Creates a `CITATION.bib` file for citing package repositories.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
const COVERAGE_GITIGNORE = ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
|
||||
|
||||
"""
|
||||
Codecov(; file=nothing) -> Codecov
|
||||
Codecov(; file=nothing)
|
||||
|
||||
Sets up code coverage submission from CI to [Codecov](https://codecov.io).
|
||||
|
||||
@ -22,7 +22,7 @@ badges(::Codecov) = Badge(
|
||||
)
|
||||
|
||||
"""
|
||||
Coveralls(; file=nothing) -> Coverallls
|
||||
Coveralls(; file=nothing)
|
||||
|
||||
Sets up code coverage submission from CI to [Coveralls](https://coveralls.io).
|
||||
|
||||
|
@ -14,12 +14,23 @@ const LICENSES = Dict(
|
||||
"EUPL-1.2+" => "European Union Public Licence, Version 1.2+",
|
||||
)
|
||||
|
||||
badge_order() = [
|
||||
Documenter{GitLabCI},
|
||||
Documenter{TravisCI},
|
||||
GitLabCI,
|
||||
TravisCI,
|
||||
AppVeyor,
|
||||
CirrusCI,
|
||||
Codecov,
|
||||
Coveralls,
|
||||
]
|
||||
|
||||
"""
|
||||
Readme(;
|
||||
file="$(contractuser(default_file("README.md")))",
|
||||
destination="README.md",
|
||||
inline_badges=false,
|
||||
) -> Readme,
|
||||
)
|
||||
|
||||
Creates a `README` file.
|
||||
By default, it includes badges for other included plugins
|
||||
@ -57,14 +68,14 @@ function view(p::Readme, t::Template, pkg::AbstractString)
|
||||
|
||||
return Dict(
|
||||
"BADGES" => strings,
|
||||
"HAS_CITATION" => hasplugin(t, Citation),
|
||||
"HAS_INLINE_BADGES" => !isempty(strings) && p.inline_badges,
|
||||
"HAS_CITATION" => hasplugin(t, Citation) && t.plugins[Citation].readme,
|
||||
"HAS_INLINE_BADGES" => !isempty(strings) && p.inline_badges,
|
||||
"PKG" => pkg,
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
License(; name="MIT", destination="LICENSE") -> License
|
||||
License(; name="MIT", destination="LICENSE")
|
||||
|
||||
Creates a license file.
|
||||
|
||||
@ -90,9 +101,6 @@ function license_path(license::AbstractString)
|
||||
return path
|
||||
end
|
||||
|
||||
# Read a license's text.
|
||||
read_license(license::AbstractString) = string(readchomp(license_path(license)))
|
||||
|
||||
function render_plugin(p::License, t::Template)
|
||||
date = year(today())
|
||||
authors = join(t.authors, ", ")
|
||||
@ -106,7 +114,7 @@ function gen_plugin(p::License, t::Template, pkg_dir::AbstractString)
|
||||
end
|
||||
|
||||
"""
|
||||
Gitignore(; ds_store=true, dev=true) -> Gitignore
|
||||
Gitignore(; ds_store=true, dev=true)
|
||||
|
||||
Creates a `.gitignore` file.
|
||||
|
||||
|
@ -7,7 +7,7 @@ const DOCUMENTER_UUID = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
|
||||
assets=String[],
|
||||
canonical_url=,
|
||||
makedocs_kwargs=Dict{Symbol, Any}(),
|
||||
) -> Documenter{T}
|
||||
)
|
||||
|
||||
Sets up documentation generation via [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl).
|
||||
Documentation deployment depends on `T`, where `T` is some supported CI plugin, or `Nothing` to only support local documentation builds.
|
||||
|
@ -10,7 +10,7 @@ function default_authors()
|
||||
end
|
||||
|
||||
"""
|
||||
Template(; kwargs...) -> Template
|
||||
Template(; kwargs...)
|
||||
|
||||
A configuration used to generate packages.
|
||||
|
||||
@ -25,13 +25,13 @@ A configuration used to generate packages.
|
||||
Like `user`, it takes its default value from the global Git config (`user.name` and `user.email`).
|
||||
|
||||
### Package Options
|
||||
- `host::AbstractString="github.com"`: URL to the code hosting service where packages will reside.
|
||||
- `dir::AbstractString="$(contractuser(Pkg.devdir()))"`: Directory to place packages in.
|
||||
- `julia_version::VersionNumber=$(repr(default_version()))`: Minimum allowed Julia version.
|
||||
- `develop::Bool=true`: Whether or not to `develop` new packages in the active environment.
|
||||
|
||||
### Git Options
|
||||
- `git::Bool=true`: Whether or not to create a Git repository for new packages.
|
||||
- `host::AbstractString="github.com"`: URL to the code hosting service where packages will reside.
|
||||
- `ssh::Bool=false`: Whether or not to use SSH for the Git remote.
|
||||
If left unset, HTTPS will be used.
|
||||
- `manifest::Bool=false`: Whether or not to commit the `Manifest.toml`.
|
||||
@ -44,6 +44,16 @@ A configuration used to generate packages.
|
||||
|
||||
### Interactive Usage
|
||||
- `interactive::Bool=false`: When set, the template is created interactively, filling unset keywords with user input.
|
||||
|
||||
---
|
||||
|
||||
To create a package from a `Template`, use the following syntax:
|
||||
|
||||
```julia
|
||||
julia> t = Template();
|
||||
|
||||
julia> t("PkgName")
|
||||
```
|
||||
"""
|
||||
struct Template
|
||||
authors::Vector{String}
|
||||
|
@ -21,6 +21,7 @@ PT.user_view(::BasicTest, ::Template, ::AbstractString) = Dict("X" => 1, "Z" =>
|
||||
with_pkg(t) do pkg
|
||||
pkg_dir = joinpath(t.dir, pkg)
|
||||
badge = string(PT.Badge("1", "2", "3"))
|
||||
@test occursin("a\naa\naaa", read(joinpath(pkg_dir, ".gitignore"), String))
|
||||
@test occursin(badge, read(joinpath(pkg_dir, "README.md"), String))
|
||||
@test read(joinpath(pkg_dir, "foo.txt"), String) == s
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user