More docs!

This commit is contained in:
Chris de Graaf 2019-09-24 15:34:24 +07:00
parent 6d95bf78a0
commit d53fb0b119
No known key found for this signature in database
GPG Key ID: 150FFDD9B0073C7B
3 changed files with 98 additions and 21 deletions

View File

@ -17,10 +17,47 @@ Plugin
BasicPlugin
```
## Package Generation Pipeline
The package generation process looks basically like this:
```
- create directory for the package
- for each plugin, ordered by priority:
- run plugin prehook
- for each plugin, ordered by priority:
- run plugin hook
- for each plugin, ordered by priority:
- run plugin posthook
```
That's it!
As you can tell, plugins play a central role in setting up a package.
The three main entrypoints for plugins to do work are the [`prehook`](@ref), the [`hook`](@ref), and the [`posthook`](@ref).
As the names might imply, they basically mean "before the main stage", "the main stage", and "after the main stage", respectively.
Each stage is basically identical, since the functions take the exact same arguments.
However, the multiple stages allow us to depend on artifacts of the previous stages.
For example, the [`Git`](@ref) plugin uses [`posthook`](@ref) to commit all generated files, but it wouldn't make sense to do that before the files are generated.
But what about dependencies within the same stage?
In this case, we have [`priority`](@ref) to define which plugins go when.
The [`Git`](@ref) plugin also uses this function to lower its priority, so that even if other plugins generate files in their posthooks, they still get committed.
```@docs
prehook
hook
posthook
priority
```
## `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):
To understand how they're implemented, let's look at simplified versions of two plugins: [`Documenter`](@ref) to explore templating, and [`Git`](@ref) to further clarify the multi-stage pipeline.
### Example: `Documenter`
```julia
@with_kw_noshow struct Documenter <: Plugin
@ -85,6 +122,9 @@ badges
Badge
```
These two functions, [`gitignore`](@ref) and [`badges`](@ref), are currently the only "special" functions for cross-plugin interactions.
In other cases, you can still access the [`Template`](@ref)'s plugins to depend on the presence/properties of other plugins, although that's less powerful.
Third, we implement [`view`](@ref), which is used to fill placeholders in badges and rendered files.
```@docs
@ -92,17 +132,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
hook
posthook
```
Inside of this function, we call a few more functions, which help us with text templating.
Inside of this function, we generate a couple of files with the help of a few more text templating functions.
```@docs
render_file
@ -112,10 +142,51 @@ combined_view
tags
```
TODO more
For more information on text templating, see the [`BasicPlugin` Walkthrough](@ref) and the section on [Custom Template Files](@ref).
### Example: `Git`
```
struct Git <: Plugin end
priority(::Git, ::typeof(posthook)) = 5
function prehook(::Git, t::Template, pkg_dir::AbstractString)
LibGit2.with(LibGit2.init(pkg_dir)) do repo
LibGit2.commit(repo, "Initial commit")
pkg = basename(pkg_dir)
url = "https://$(t.host)/$(t.user)/$pkg.jl"
close(GitRemote(repo, "origin", url))
end
end
function hook(::Git, t::Template, pkg_dir::AbstractString)
ignore = mapreduce(gitignore, append!, t.plugins)
unique!(sort!(ignore))
gen_file(joinpath(pkg_dir, ".gitignore"), join(ignore, "\n"))
end
function posthook(::Git, ::Template, pkg_dir::AbstractString)
LibGit2.with(GitRepo(pkg_dir)) do repo
LibGit2.add!(repo, ".")
LibGit2.commit(repo, "Files generated by PkgTemplates")
end
end
```
As previously mentioned, we use [`priority`](@ref) to make sure that we commit all generated files.
Then, all three hooks are implemented:
- [`prehook`](@ref) creates the Git repository for the package
- [`hook`](@ref) generates the `.gitignore` file, using the special [`gitignore`](@ref) function
- [`posthook`](@ref) adds and commits all generated files
Hopefully, this demonstrates the level of control you have over the package generation process when developing plugins.
## `BasicPlugin` Walkthrough
Most of the time, you don't really need all of the control that we showed off above.
Plugins that subtype [`BasicPlugin`](@ref) perform a much more limited task.
In general, they just generate one templated file.
@ -156,13 +227,13 @@ We briefly saw this function earlier, but in this case it's necessary to change
To see why, it might help to see the template file in its entirety:
```
@misc{<<PKG>>.jl,
author = {<<AUTHORS>>},
title = {<<PKG>>.jl},
url = {<<URL>>},
@misc{<<&PKG>>.jl,
author = {<<&AUTHORS>>},
title = {<<&PKG>>.jl},
url = {<<&URL>>},
version = {v0.1.0},
year = {<<YEAR>>},
month = {<<MONTH>>}
year = {<<&YEAR>>},
month = {<<&MONTH>>}
}
```
@ -215,6 +286,9 @@ function hook(p::Tests, t::Template, pkg_dir::AbstractString)
end
```
There is also a default [`prehook`](@ref) implementation for [`BasicPlugin`](@ref)s, which checks that the plugin's [`source`](@ref) file exists, and throws an `ArgumentError` otherwise.
If you want to extend the prehook but keep the file existence check, use the `invoke` method as described above.
For more examples, see the plugins in the [Continuous Integration (CI)](@ref) and [Code Coverage](@ref) sections.
## Miscellaneous Tips

View File

@ -13,6 +13,8 @@ But it also refers to "template files" and "text templating", which are plaintex
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)).
Please keep the difference between these two things in mind when reading this documentation!
### Documentation
If you're looking to **create new packages**, see the [User Guide](user.md).

View File

@ -59,8 +59,8 @@ function hook(p::Git, t::Template, pkg_dir::AbstractString)
gen_file(joinpath(pkg_dir, ".gitignore"), join(ignore, "\n"))
end
# Commit the files
function posthook(p::Git, t::Template, pkg_dir::AbstractString)
# Commit the files.
function posthook(p::Git, ::Template, pkg_dir::AbstractString)
# Ensure that the manifest exists if it's going to be committed.
manifest = joinpath(pkg_dir, "Manifest.toml")
if p.manifest && !isfile(manifest)
@ -71,6 +71,7 @@ function posthook(p::Git, t::Template, pkg_dir::AbstractString)
LibGit2.with(GitRepo(pkg_dir)) do repo
LibGit2.add!(repo, ".")
msg = "Files generated by PkgTemplates"
# TODO: Newer versions of Julia will not have Pkg.installed.
installed = Pkg.installed()
if haskey(installed, "PkgTemplates")
ver = string(installed["PkgTemplates"])