Lots of documentation

Still WIP though.
This commit is contained in:
Chris de Graaf 2019-09-01 21:03:19 +07:00
parent 493c54a948
commit 65f5eff29b
No known key found for this signature in database
GPG Key ID: 150FFDD9B0073C7B
14 changed files with 369 additions and 54 deletions

View File

@ -27,11 +27,15 @@ matrix:
julia: 1.0
- stage: Documentation
julia: 1.0
script: julia --project=docs -e '
using Pkg;
Pkg.develop(PackageSpec(; path=pwd()));
Pkg.instantiate();
include("docs/make.jl");'
script:
- git config --global user.name Your-Name
- git config --global user.email your-email
- git config --global github.user your-username
- julia --project=docs -e '
using Pkg;
Pkg.develop(PackageSpec(; path=pwd()));
Pkg.instantiate();
include("docs/make.jl");'
after_success: skip
after_success: julia -e '
using Pkg;

View File

@ -1,14 +1,12 @@
# PkgTemplates
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://invenia.github.io/PkgTemplates.jl/stable)
[![Dev](https://img.shields.io/badge/docs-latest-blue.svg)](https://invenia.github.io/PkgTemplates.jl/dev)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://invenia.github.io/PkgTemplates.jl/dev)
[![Build Status](https://travis-ci.org/invenia/PkgTemplates.jl.svg?branch=master)](https://travis-ci.org/invenia/PkgTemplates.jl)
[![Codecov](https://codecov.io/gh/invenia/PkgTemplates.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/invenia/PkgTemplates.jl)
**PkgTemplates creates new Julia packages in an easy, repeatable, and customizable way.**
## Usage
Assuming you have the relatively standard Git options `user.name`, `user.email` and `github.user` set up globally with `git config --global`, creating a `Template` is as simple as:
```jl
@ -31,7 +29,7 @@ t = Template(;
)
```
Once you have a `Template`, yoy can createa packages with ease:
Once you have a template, you can create packages with ease:
```jl
t("MyPkg")

View File

@ -1,5 +1,5 @@
using Documenter
using PkgTemplates
using PkgTemplates: PkgTemplates
makedocs(;
modules=[PkgTemplates],
@ -11,7 +11,8 @@ makedocs(;
assets=String[],
),
pages=[
"Home" => "index.md",
"Home" => "user.md",
"Developer Guide" => "developer.md",
],
)

31
docs/src/developer.md Normal file
View File

@ -0,0 +1,31 @@
```@meta
CurrentModule = PkgTemplates
```
# PkgTemplates Developer Guide
PkgTemplates can be easily extended by adding new [`Plugin`](@ref)s.
## The `Plugin` Interface
```@docs
gen_plugin
gitignore
badges
Badge
view
user_view
combined_view
tags
```
## The `BasicPlugin` Interface
While subtyping [`Plugin`](@ref) gives you complete freedom, it's not always necessary.
For more constrained cases, a simpler API exists.
```@docs
BasicPlugin
source
destination
```

View File

@ -1,8 +0,0 @@
# PkgTemplates
```@index
```
```@autodocs
Modules = [PkgTemplates]
```

67
docs/src/user.md Normal file
View File

@ -0,0 +1,67 @@
```@meta
CurrentModule = PkgTemplates
```
# PkgTemplates User Guide
Using PkgTemplates is straightforward.
Just create a [`Template`](@ref), and call it on a package name to generate that package.
## Template
```@docs
Template
```
## Plugins
Plugins are PkgTemplates' source of customization and extensibility.
Add plugins to your templates to enable extra pieces of repository setup.
```@docs
Plugin
```
### Defaults
These plugins are included in [`Template`](@ref)s 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
Gitignore
License
Readme
Tests
```
### Continuous Integration (CI)
These plugins will create the configuration files of common CI services for you.
```@docs
AppVeyor
CirrusCI
GitLabCI
TravisCI
```
### Code Coverage
These plugins will enable code coverage reporting from CI.
```@docs
Codecov
Coveralls
```
### Documentation
```@docs
Documenter
```
### Miscellaneous
```@docs
Citation
```

View File

@ -35,6 +35,5 @@ abstract type Plugin end
include("template.jl")
include("generate.jl")
include("plugin.jl")
# include("interactive.jl")
end

View File

@ -12,10 +12,16 @@ badge_order() = [
]
"""
A simple plugin that, in general, manages a single file.
For example, most CI services reply on one configuration file.
A simple plugin that, in general, creates a single file.
TODO: Dev guide.
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
@ -25,16 +31,40 @@ default_file(paths::AbstractString...) = joinpath(DEFAULTS_DIR, paths...)
"""
view(::Plugin, ::Template, pkg::AbstractString) -> Dict{String, Any}
Return the string replacements to be made for this plugin.
Return the view to be passed to the text templating engine for this plugin.
`pkg` is the name of the package being generated.
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.
"""
view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
"""
user_view(::Plugin, ::Template, pkg::AbstractString) -> Dict{String, Any}
The same as [`view`](@ref), but for use only by package *users* for extension.
TODO better explanation
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}()
@ -42,6 +72,9 @@ user_view(::Plugin, ::Template, ::AbstractString) = Dict{String, Any}()
tags(::Plugin) -> Tuple{String, String}
Return the tags used for Mustache templating.
See the [`Citation`](@ref) plugin for a rare case where changing the tags is necessary.
By default, the tags are `"{{"` and `"}}"`.
"""
tags(::Plugin) = ("{{", "}}")
@ -49,6 +82,9 @@ tags(::Plugin) = ("{{", "}}")
gitignore(::Plugin) -> Vector{String}
Return patterns that should be added to `.gitignore`.
These are used by the [`Gitignore`](@ref) plugin.
By default, an empty list is returned.
"""
gitignore(::Plugin) = String[]
@ -56,13 +92,18 @@ gitignore(::Plugin) = String[]
badges(::Plugin) -> Union{Badge, Vector{Badge}}
Return a list of [`Badge`](@ref)s, or just one, to be added to `README.md`.
These are used by the [`Readme`](@ref) plugin to add badges to the README.
By default, an empty list is returned.
"""
badges(::Plugin) = Badge[]
"""
source(::BasicPlugin) -> Union{String, Nothing}
Return the path to a plugin's configuration file template, or `nothing` to indicate no file.
Return the path to a plugin's template file, or `nothing` to indicate no file.
By default, `nothing` is returned.
"""
source(::BasicPlugin) = nothing
@ -70,6 +111,8 @@ source(::BasicPlugin) = nothing
destination(::BasicPlugin) -> String
Return the destination, relative to the package root, of a plugin's configuration file.
This function **must** be implemented.
"""
function destination end
@ -77,7 +120,7 @@ function destination end
Badge(hover::AbstractString, image::AbstractString, link::AbstractString) -> Badge
Container for Markdown badge data.
Each argument can contain placeholders.
Each argument can contain placeholders (which will be filled in with values from [`combined_view`](@ref)).
## Arguments
* `hover::AbstractString`: Text to appear when the mouse is hovered over the badge.
@ -104,6 +147,11 @@ end
Perform any work associated with a plugin.
`pkg` is the name of the package being generated.
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.
"""
gen_plugin(::Plugin, ::Template, ::AbstractString) = nothing
@ -120,6 +168,15 @@ function render_plugin(p::BasicPlugin, t::Template, pkg::AbstractString)
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

View File

@ -1,15 +1,45 @@
const VersionsOrStrings = Vector{Union{VersionNumber, String}}
const ALLOWED_FAILURES = ["1.3", "nightly"] # TODO: Update this list with new RCs.
const DEFAULT_CI_VERSIONS = VersionsOrStrings([VERSION, default_version(), "nightly"])
# Strip everything but the major and minor release from a version number.
format_version(v::VersionNumber) = "$(v.major).$(v.minor)"
format_version(v::AbstractString) = string(v)
const ALLOWED_FAILURES = ["1.3", "nightly"] # TODO: Update this list with new RCs.
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`.
This is useful for creating lists of versions to be included in CI configurations.
"""
function collect_versions(t::Template, versions::Vector)
vs = map(format_version, [t.julia_version, versions...])
return sort(unique(vs))
end
"""
TravisCI(;
file="$(contractuser(default_file("travis.yml")))",
linux=true,
osx=true,
windows=true,
x86=false,
coverage=true,
extra_versions=$DEFAULT_CI_VERSIONS,
) -> TravisCI
Integrates your packages with [Travis CI](https://travis-ci.com).
## Keyword Arguments
- `file::AbstractString`: Template file for `.travis.yml`.
- `linux::Bool`: Whether or not to run builds on Linux.
- `osx::Bool`: Whether or not to run builds on OSX (MacOS).
- `windows::Bool`: Whether or not to run builds on Windows.
- `x86::Bool`: Whether or not to run builds on 32-bit systems, in addition to the default 64-bit builds.
- `coverage::Bool`: Whether or not to publish code coverage (another code coverage plugin such as [`Codecov`](@ref) must also be included).
$EXTRA_VERSIONS_DOC
"""
@with_kw struct TravisCI <: BasicPlugin
file::String = default_file("travis.yml")
linux::Bool = true
@ -17,7 +47,7 @@ end
windows::Bool = true
x86::Bool = false
coverage::Bool = true
extra_versions::VersionsOrStrings = DEFAULT_CI_VERSIONS
extra_versions::Vector = DEFAULT_CI_VERSIONS
end
source(p::TravisCI) = p.file
@ -35,7 +65,6 @@ function view(p::TravisCI, t::Template, pkg::AbstractString)
p.osx && push!(os, "osx")
p.windows && push!(os, "windows")
versions = collect_versions(t, p.extra_versions)
allow_failures = filter(in(versions), ALLOWED_FAILURES)
@ -64,11 +93,27 @@ function view(p::TravisCI, t::Template, pkg::AbstractString)
)
end
"""
AppVeyor(;
file="$(contractuser(default_file("appveyor.yml")))",
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).
## Keyword Arguments
- `file::AbstractString`: Template file for `.appveyor.yml`.
- `x86::Bool`: Whether or not to run builds on 32-bit systems, in addition to the default 64-bit builds.
- `coverage::Bool`: Whether or not to publish code coverage ([`Codecov`](@ref) must also be included).
$EXTRA_VERSIONS_DOC
"""
@with_kw struct AppVeyor <: BasicPlugin
file::String = default_file("appveyor.yml")
x86::Bool = false
coverage::Bool = true
extra_versions::VersionsOrStrings = DEFAULT_CI_VERSIONS
extra_versions::Vector = DEFAULT_CI_VERSIONS
end
source(p::AppVeyor) = p.file
@ -98,11 +143,30 @@ function view(p::AppVeyor, t::Template, pkg::AbstractString)
)
end
"""
CirrusCI(;
file="$(contractuser(default_file("cirrus.yml")))",
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).
## Keyword Arguments
- `file::AbstractString`: Template file for `.cirrus.yml`.
- `image::AbstractString`: The FreeBSD image to be used.
- `coverage::Bool`: Whether or not to publish code coverage ([`Codecov`](@ref) must also be included).
$EXTRA_VERSIONS_DOC
!!! note
Code coverage submission from Cirrus CI is not yet supported by [Coverage.jl](https://github.com/JuliaCI/Coverage.jl).
"""
@with_kw struct CirrusCI <: BasicPlugin
file::String = default_file("cirrus.yml")
image::String = "freebsd-12-0-release-amd64"
coverage::Bool = true
extra_versions::VersionsOrStrings = DEFAULT_CI_VERSIONS
extra_versions::Vector = DEFAULT_CI_VERSIONS
end
source(p::CirrusCI) = p.file
@ -126,11 +190,32 @@ function view(p::CirrusCI, t::Template, pkg::AbstractString)
)
end
"""
GitLabCI(;
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/).
## Keyword Arguments
- `file::AbstractString`: Template file for `.gitlab-ci.yml`.
- `coverage::Bool`: Whether or not to compute code coverage.
$EXTRA_VERSIONS_DOC
## GitLab Pages
Documentation can be generated by including a `Documenter{GitLabCI}` plugin.
See [`Documenter`](@ref) for more information.
!!! note
Nightly Julia is not supported.
"""
@with_kw struct GitLabCI <: BasicPlugin
file::String = default_file("gitlab-ci.yml")
coverage::Bool = true
# Nightly has no Docker image.
extra_versions::VersionsOrStrings = [VERSION, default_version()]
extra_versions::Vector = map(format_version, [default_version(), VERSION])
end
gitignore(p::GitLabCI) = p.coverage ? COVERAGE_GITIGNORE : String[]
@ -163,5 +248,12 @@ function view(p::GitLabCI, t::Template, pkg::AbstractString)
)
end
"""
is_ci(::Type{T}) -> Bool
Determine whether or not `T` 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

View File

@ -1,8 +1,14 @@
"""
Citation(; readme_section::Bool=false) -> Citation
Citation(;
file="$(contractuser(default_file("CITATION.bib")))",
readme=false,
) -> Citation
Add `Citation` to a [`Template`](@ref)'s plugin list to generate a `CITATION.bib` file.
If `readme` is set, then `README.md` will contain a section about citing.
Creates a `CITATION.bib` file for citing package repositories.
## Keyword Arguments
- `file::AbstractString`: Template file for `CITATION.bib`.
- `readme::Bool`: Whether or not to include a section about citing in the README.
"""
@with_kw struct Citation <: BasicPlugin
file::String = default_file("CITATION.bib")

View File

@ -1,5 +1,13 @@
const COVERAGE_GITIGNORE = ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
"""
Codecov(; file=nothing) -> Codecov
Sets up code coverage submission from CI to [Codecov](https://codecov.io).
## Keyword Arguments
- `file::Union{AbstractString, Nothing}`: Template file for `.codecov.yml`, or `nothing` to create no file.
"""
@with_kw struct Codecov <: BasicPlugin
file::Union{String, Nothing} = nothing
end
@ -13,6 +21,14 @@ badges(::Codecov) = Badge(
"https://codecov.io/gh/{{USER}}/{{PKG}}.jl",
)
"""
Coveralls(; file=nothing) -> Coverallls
Sets up code coverage submission from CI to [Coveralls](https://coveralls.io).
## Keyword Arguments
- `file::Union{AbstractString, Nothing}`: Template file for `.coveralls.yml`, or `nothing` to create no file.
"""
@with_kw struct Coveralls <: BasicPlugin
file::Union{String, Nothing} = nothing
end
@ -28,5 +44,11 @@ badges(::Coveralls) = Badge(
gitignore(::Union{Codecov, Coveralls}) = COVERAGE_GITIGNORE
"""
is_coverage(::Type{T}) -> Bool
Determine whether or not `T` 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

View File

@ -14,6 +14,22 @@ const LICENSES = Dict(
"EUPL-1.2+" => "European Union Public Licence, Version 1.2+",
)
"""
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
## Keyword Arguments
- `file::AbstractString`: Template file for the `README`.
- `destination::AbstractString`: File destination, relative to the repository root.
For example, values of `"README"` or `"README.rst"` might be desired.
- `inline_badges::Bool`: Whether or not to put the badges on the same line as the package name.
"""
@with_kw struct Readme <: BasicPlugin
file::String = default_file("README.md")
destination::String = "README.md"
@ -47,6 +63,17 @@ function view(p::Readme, t::Template, pkg::AbstractString)
)
end
"""
License(; name="MIT", destination="LICENSE") -> License
Creates a license file.
## Keyword Arguments
- `name::AbstractString`: Name of the desired license.
Available licenses can be seen [here](https://github.com/invenia/PkgTemplates.jl/tree/master/licenses).
- `destination::AbstractString`: File destination, relative to the repository root.
For example, `"LICENSE.md"` might be desired.
"""
struct License <: Plugin
path::String
destination::String
@ -56,12 +83,14 @@ struct License <: Plugin
end
end
# Look up a license and throw an error if it doesn't exist.
function license_path(license::AbstractString)
path = joinpath(LICENSE_DIR, license)
isfile(path) || throw(ArgumentError("License '$license' is not available"))
return path
end
# Read a license's text.
read_license(license::AbstractString) = string(readchomp(license_path(license)))
function render_plugin(p::License, t::Template)
@ -76,6 +105,15 @@ function gen_plugin(p::License, t::Template, pkg_dir::AbstractString)
gen_file(joinpath(pkg_dir, p.destination), render_plugin(p, t))
end
"""
Gitignore(; ds_store=true, dev=true) -> Gitignore
Creates a `.gitignore` file.
## Keyword Arguments
- `ds_store::Bool`: Whether or not to ignore MacOS's `.DS_Store` files.
- `dev::Bool`: Whether or not to ignore the directory of locally-developed packages.
"""
@with_kw struct Gitignore <: Plugin
ds_store::Bool = true
dev::Bool = true
@ -96,6 +134,14 @@ function gen_plugin(p::Gitignore, t::Template, pkg_dir::AbstractString)
t.git && gen_file(joinpath(pkg_dir, ".gitignore"), render_plugin(p, t))
end
"""
Tests(; file="$(contractuser(default_file("runtests.jl")))" -> Tests
Sets up testing for packages.
## Keyword Arguments
- `file::AbstractString`: Template file for the `runtests.jl`.
"""
@with_kw struct Tests <: BasicPlugin
file::String = default_file("runtests.jl")
end

View File

@ -2,23 +2,23 @@ const DOCUMENTER_UUID = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
"""
Documenter{T<:Union{TravisCI, GitLabCI, Nothing}}(;
assets::Vector{<:AbstractString}=String[],
makedocs_kwargs::Dict{Symbol}=Dict(),
canonical_url::Union{Function, Nothing}=nothing,
make_jl::AbstractString="$(contractuser(default_file("make.jl")))",
index_md::AbstractString="$(contractuser(default_file("index.md")))",
make_jl="$(contractuser(default_file("make.jl")))",
index_md="$(contractuser(default_file("index.md")))",
assets=String[],
canonical_url=,
makedocs_kwargs=Dict{Symbol, Any}(),
) -> Documenter{T}
The `Documenter` plugin adds support for documentation generation via [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl).
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.
## Keyword Arguments
TODO
- `assets::Vector{<:AbstractString}=String[]`:
- `makedocs_kwargs::Dict{Symbol}=Dict{Symbol, Any}()`:
- `canonical_url::Union{Function, Nothing}=nothing`:
- `index_md::AbstractString`
- `make_jl::AbstractString`
- `make_jl::AbstractString`: Template file for `make.jl`.
- `index_md::AbstractString`: Template file for `index.md`.
- `assets::Vector{<:AbstractString}`: Extra assets for the generated site.
- `canonical_url::Union{Function, Nothing}`: A function to generate the documentation site's canonical URL.
The default value will compute GitHub Pages and GitLab Pages URLs for [`TravisCI`](@ref) and [`GitLabCI`](@ref), respectively.
- `makedocs_kwargs::Dict{Symbol}`: Extra keyword arguments to be inserted into `makedocs`.
!!! note
If deploying documentation with Travis CI, don't forget to complete the required configuration.

View File

@ -10,9 +10,9 @@ function default_authors()
end
"""
Template(; interactive::Bool=false, kwargs...) -> Template
Template(; kwargs...) -> Template
Records common information used to generate a package.
A configuration used to generate packages.
## Keyword Arguments