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.
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.
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.
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.
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.
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
### 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.