Lots of documentation changes

This commit is contained in:
Chris de Graaf 2019-09-18 21:22:04 +07:00
parent 2d7c851fca
commit 7a2a43f3f4
No known key found for this signature in database
GPG Key ID: 150FFDD9B0073C7B
15 changed files with 451 additions and 110 deletions

View File

@ -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()));

View File

@ -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",
],
)

View File

@ -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
View 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
```

View File

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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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/).

View File

@ -2,7 +2,7 @@
Citation(;
file="$(contractuser(default_file("CITATION.bib")))",
readme=false,
) -> Citation
)
Creates a `CITATION.bib` file for citing package repositories.

View File

@ -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).

View File

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

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

View File

@ -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}

View File

@ -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