Remove interactive stuff (for now)
This commit is contained in:
parent
cce0f5a750
commit
5e9ff16cbe
@ -5,17 +5,15 @@ version = "0.7.0"
|
||||
|
||||
[deps]
|
||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
||||
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||||
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
|
||||
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
|
||||
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||||
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
||||
[compat]
|
||||
julia = "1"
|
||||
Mustache = ">= 0.5.13"
|
||||
julia = "1"
|
||||
|
||||
[extras]
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
|
@ -47,16 +47,10 @@ t = Template(;
|
||||
Codecov(),
|
||||
TravisCI(; x86=true),
|
||||
Documenter{TravisCI}(),
|
||||
o ],
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
You can also create a `Template` interactively by following a set of prompts:
|
||||
|
||||
```jl
|
||||
julia> t = Template(; interactive=true)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
For a much more detailled overview, please see the documentation.
|
||||
|
@ -19,7 +19,6 @@ BasicPlugin
|
||||
|
||||
## Template + Package Creation Pipeline
|
||||
|
||||
|
||||
The [`Template`](@ref) constructor basically does this:
|
||||
|
||||
```
|
||||
@ -76,7 +75,7 @@ To understand how they're implemented, let's look at simplified versions of two
|
||||
### Example: `Documenter`
|
||||
|
||||
```julia
|
||||
@with_defaults struct Documenter <: Plugin
|
||||
@with_kw_noshow struct Documenter <: Plugin
|
||||
make_jl::String = default_file("docs", "make.jl") <- "Path to make.jl template"
|
||||
index_md::String = default_file("docs", "src", "index.md") <- "Path to index.md template"
|
||||
end
|
||||
@ -118,14 +117,8 @@ function hook(p::Documenter, t::Template, pkg_dir::AbstractString)
|
||||
end
|
||||
```
|
||||
|
||||
The first thing you'll notice is the strange struct definition with [`@with_defaults`](@ref).
|
||||
|
||||
```@docs
|
||||
@with_defaults
|
||||
interactive
|
||||
```
|
||||
|
||||
Inside of our struct definition we're using [`default_file`](@ref) to refer to files in this repository.
|
||||
The `@with_kw_noshow` macro defines keyword constructors for us.
|
||||
Inside of our struct definition, we're using [`default_file`](@ref) to refer to files in this repository.
|
||||
|
||||
```@docs
|
||||
default_file
|
||||
|
@ -43,16 +43,11 @@ One less name to remember!
|
||||
|
||||
## Interactive Templates
|
||||
|
||||
Two less names to remember!
|
||||
|
||||
| Old | New |
|
||||
| :--------------------: | :---------------------------------: |
|
||||
| `interactive_template` | `Template(; interactive=true)` |
|
||||
| `generate_interactive` | `Template(; interactive=true)(pkg)` |
|
||||
Currently not implemented, but will be in the future.
|
||||
|
||||
## Other Functions
|
||||
|
||||
Another two less names to remember!
|
||||
Two less names to remember!
|
||||
Although it's unlikely that anyone used these.
|
||||
|
||||
| Old | New |
|
||||
|
@ -4,14 +4,12 @@ using Base: active_project
|
||||
using Base.Filesystem: contractuser
|
||||
|
||||
using Dates: month, today, year
|
||||
using InteractiveUtils: subtypes
|
||||
using LibGit2: LibGit2, GitRemote, GitRepo
|
||||
using Pkg: Pkg, TOML, PackageSpec
|
||||
using REPL.TerminalMenus: MultiSelectMenu, RadioMenu, request
|
||||
using UUIDs: uuid4
|
||||
|
||||
using Mustache: render
|
||||
using Parameters: with_kw
|
||||
using Parameters: @with_kw_noshow
|
||||
|
||||
export
|
||||
Template,
|
||||
@ -43,7 +41,6 @@ abstract type Plugin end
|
||||
include("template.jl")
|
||||
include("plugin.jl")
|
||||
include("show.jl")
|
||||
include("interactive.jl")
|
||||
|
||||
# Run some function with a project activated at the given path.
|
||||
function with_project(f::Function, path::AbstractString)
|
||||
|
@ -1,172 +0,0 @@
|
||||
"""
|
||||
interactive(::Type{T<:Plugin}) -> T
|
||||
|
||||
Create a [`Plugin`](@ref) of type `T` interactively from user input.
|
||||
"""
|
||||
function interactive(::Type{T}) where T <: Plugin
|
||||
kwargs = Dict{Symbol, Any}()
|
||||
|
||||
foreach(fieldnames(T)) do name
|
||||
F = fieldtype(T, name)
|
||||
v = Val(name)
|
||||
required = !applicable(defaultkw, T, v)
|
||||
default = required ? defaultkw(F) : defaultkw(T, v)
|
||||
kwargs[name] = if applicable(prompt, T, v)
|
||||
prompt(F, "$T: $(prompt(T, v))", default, required=required)
|
||||
elseif required
|
||||
prompt(F, "$T: Value for field '$name' ($F)", default; required=required)
|
||||
else
|
||||
default
|
||||
end
|
||||
end
|
||||
|
||||
return T(; kwargs...)
|
||||
end
|
||||
|
||||
leaves(T::Type) = isconcretetype(T) ? [T] : vcat(map(leaves, subtypes(T))...)
|
||||
|
||||
function plugin_types()
|
||||
Ts = leaves(Plugin)
|
||||
# Hack both Documenter types into the list.
|
||||
# Unfortunately there's no way to do this automatically,
|
||||
# but it's unlikely for more parametric plugin types to exist.
|
||||
push!(Ts, Documenter{TravisCI}, Documenter{GitLabCI})
|
||||
return Ts
|
||||
end
|
||||
|
||||
function Template(::Val{true}; kwargs...)
|
||||
opts = Dict{Symbol, Any}(kwargs)
|
||||
|
||||
if !haskey(opts, :user)
|
||||
default = defaultkw(Template, :user)
|
||||
opts[:user] = prompt(String, "Git hosting service username", default)
|
||||
end
|
||||
|
||||
if !haskey(opts, :host)
|
||||
default = defaultkw(Template, :host)
|
||||
opts[:host] = prompt(String, "Git hosting service URL", default)
|
||||
end
|
||||
|
||||
if !haskey(opts, :authors)
|
||||
default = defaultkw(Template, :authors)
|
||||
opts[:authors] = prompt(String, "Package author(s)", default)
|
||||
end
|
||||
|
||||
if !haskey(opts, :dir)
|
||||
default = defaultkw(Template, :dir)
|
||||
opts[:dir] = prompt(String, "Path to package parent directory", default)
|
||||
end
|
||||
|
||||
if !haskey(opts, :julia)
|
||||
default = defaultkw(Template, :julia)
|
||||
opts[:julia] = prompt(VersionNumber, "Supported Julia version", default)
|
||||
end
|
||||
|
||||
if !haskey(opts, :disable_defaults)
|
||||
available = map(typeof, default_plugins())
|
||||
initial = defaultkw(Template, :disable_defaults)
|
||||
opts[:disable_defaults] = select("Select defaults to disable:", available, initial)
|
||||
end
|
||||
|
||||
if !haskey(opts, :plugins)
|
||||
# Don't offer any disabled plugins as options.
|
||||
available = setdiff(sort(plugin_types(); by=string), opts[:disable_defaults])
|
||||
initial = setdiff(map(typeof, default_plugins()), opts[:disable_defaults])
|
||||
chosen = select("Select plugins", available, initial)
|
||||
opts[:plugins] = map(interactive, chosen)
|
||||
end
|
||||
|
||||
return Template(Val(false); opts...)
|
||||
end
|
||||
|
||||
defaultkw(::Type{String}) = ""
|
||||
defaultkw(::Type{Union{T, Nothing}}) where T = nothing
|
||||
defaultkw(::Type{T}) where T <: Number = zero(T)
|
||||
defaultkw(::Type{Vector{T}}) where T = T[]
|
||||
|
||||
function prompt(
|
||||
::Type{<:Union{String, Nothing}}, s::AbstractString, default;
|
||||
required::Bool=false,
|
||||
)
|
||||
default isa AbstractString && (default = contractuser(default))
|
||||
default_display = if required
|
||||
"REQUIRED"
|
||||
elseif default === nothing
|
||||
"None"
|
||||
else
|
||||
repr(default)
|
||||
end
|
||||
|
||||
print("$s [$default_display]: ")
|
||||
input = strip(readline())
|
||||
|
||||
return if isempty(input) && required
|
||||
println("This option is required")
|
||||
prompt(String, s, default; required=required)
|
||||
elseif isempty(input)
|
||||
default
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
function prompt(
|
||||
::Type{VersionNumber}, s::AbstractString, default::VersionNumber;
|
||||
required::Bool=false,
|
||||
)
|
||||
v = prompt(String, s, default; required=required)
|
||||
return if v isa VersionNumber
|
||||
v
|
||||
else
|
||||
startswith(v, "v") && (v = v[2:end])
|
||||
v = replace(v, "\"" => "")
|
||||
VersionNumber(v)
|
||||
end
|
||||
end
|
||||
|
||||
function prompt(::Type{Bool}, s::AbstractString, default::Bool; required::Bool=false)
|
||||
b = prompt(String, s, default; required=required)
|
||||
return b === default ? default : uppercase(b) in ("Y", "YES", "T", "TRUE")
|
||||
end
|
||||
|
||||
function prompt(::Type{Vector}, s::AbstractString, default::Vector; required::Bool=false)
|
||||
return prompt(Vector{String}, s, default; required=required)
|
||||
end
|
||||
|
||||
function prompt(
|
||||
::Type{Vector{String}}, s::AbstractString, default::Vector{<:AbstractString};
|
||||
required::Bool=false,
|
||||
)
|
||||
s = prompt(String, "$s (comma-delimited)", join(default, ", "); required=required)
|
||||
return convert(Vector{String}, map(strip, split(s, ","; keepempty=false)))
|
||||
end
|
||||
|
||||
function prompt(::Type{<:Dict}, s::AbstractString, default::Dict, required::Bool=false)
|
||||
default_display = join(map(p -> "$(p.first)=$(p.second)", collect(default)), ", ")
|
||||
s = prompt(String, "$s (k=v, comma-delimited)", default_display; required=required)
|
||||
return if isempty(s)
|
||||
Dict{String, String}()
|
||||
else
|
||||
Dict{String, String}(Pair(split(strip(kv), "=")...) for kv in split(s, ","))
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: These can be made simpler when this is merged:
|
||||
# https://github.com/JuliaLang/julia/pull/30043
|
||||
|
||||
select(s::AbstractString, xs::Vector, initial) = select(string, s, xs, initial)
|
||||
|
||||
# Select any number of elements from a collection.
|
||||
function select(f::Function, s::AbstractString, xs::Vector, initial::Vector)
|
||||
m = MultiSelectMenu(map(f, xs); pagesize=length(xs))
|
||||
foreach(x -> push!(m.selected, findfirst(==(x), xs)), initial)
|
||||
selection = request("$s:", m)
|
||||
return map(i -> xs[i], collect(selection))
|
||||
end
|
||||
|
||||
# Select one item frm oa collection.
|
||||
function select(f::Function, s::AbstractString, xs::Vector, initial)
|
||||
print(stdin.buffer, repeat("\e[B", findfirst(==(initial), xs) - 1))
|
||||
selection = request("$s:", RadioMenu(map(f, xs); pagesize=length(xs)))
|
||||
return xs[selection]
|
||||
end
|
@ -1,47 +1,6 @@
|
||||
const TEMPLATES_DIR = normpath(joinpath(@__DIR__, "..", "templates"))
|
||||
const DEFAULT_PRIORITY = 1000
|
||||
|
||||
"""
|
||||
@with_defaults struct T #= ... =# end
|
||||
|
||||
Creates keyword constructors and generates methods needed to interactively create instances with [`interactive`](@ref).
|
||||
|
||||
## Example
|
||||
|
||||
```julia
|
||||
struct Foo <: Plugin
|
||||
file::String = "/the/default/value" <- "This is the interactive prompt"
|
||||
n::Int <- "This one has no default, so it's a required keyword"
|
||||
abc::String = "No prompt, so the default is always taken in interactive mode"
|
||||
xyz::String # Required keyword, with a generic interactive prompt.
|
||||
end
|
||||
```
|
||||
"""
|
||||
macro with_defaults(ex::Expr)
|
||||
T = esc(ex.args[2].args[1]) # This assumes T <: U.
|
||||
|
||||
# This is a bit nasty.
|
||||
funcs = Expr[]
|
||||
foreach(filter(arg -> arg isa Expr, ex.args[3].args)) do arg
|
||||
if iscall(arg, :<) && iscall(arg.args[3], :-) # x::T <- "prompt"
|
||||
name = QuoteNode(arg.args[2].args[1])
|
||||
prompt = arg.args[2]
|
||||
push!(funcs, :(PkgTemplates.prompt(::Type{$T}, ::Val{$name}) = $(esc(prompt))))
|
||||
elseif arg.head === :(=)
|
||||
rhs = arg.args[2]
|
||||
name = QuoteNode(arg.args[1].args[1])
|
||||
if iscall(rhs, :<) && iscall(rhs.args[3], :-) # x::T = "foo" <- "prompt"
|
||||
prompt = rhs.args[3].args[2]
|
||||
push!(funcs, :(PkgTemplates.prompt(::Type{$T}, ::Val{$name}) = $(esc(prompt))))
|
||||
end
|
||||
default = arg.args[2] = rhs.args[2]
|
||||
push!(funcs, :(PkgTemplates.defaultkw(::Type{$T}, ::Val{$name}) = $(esc(default))))
|
||||
end
|
||||
end
|
||||
|
||||
return Expr(:block, esc(with_kw(ex, __module__, false)), funcs...)
|
||||
end
|
||||
|
||||
"""
|
||||
A simple plugin that, in general, creates a single file.
|
||||
"""
|
||||
@ -276,11 +235,6 @@ If you are implementing a plugin that uses the `user` field of a [`Template`](@r
|
||||
"""
|
||||
needs_username(::Plugin) = false
|
||||
|
||||
function prompt end
|
||||
|
||||
iscall(x, ::Symbol) = false
|
||||
iscall(ex::Expr, s::Symbol) = ex.head === :call && ex.args[1] === s
|
||||
|
||||
include(joinpath("plugins", "project_file.jl"))
|
||||
include(joinpath("plugins", "src_dir.jl"))
|
||||
include(joinpath("plugins", "tests.jl"))
|
||||
|
@ -9,6 +9,7 @@ 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 DEFAULT_CI_VERSIONS_NO_NIGHTLY = map(format_version, [default_version(), VERSION])
|
||||
const EXTRA_VERSIONS_DOC = "- `extra_versions::Vector`: Extra Julia versions to test, as strings or `VersionNumber`s."
|
||||
|
||||
"""
|
||||
@ -44,14 +45,14 @@ Integrates your packages with [Travis CI](https://travis-ci.com).
|
||||
- `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_defaults struct TravisCI <: BasicPlugin
|
||||
file::String = default_file("travis.yml") <- "Path to .travis.yml template"
|
||||
linux::Bool = true <- "Enable Linux bulds"
|
||||
osx::Bool = true <- "Enable OSX builds"
|
||||
windows::Bool = true <- "Enable Windows builds"
|
||||
x86::Bool = false <- "Enable 32-bit builds"
|
||||
coverage::Bool = true <- "Enable code coverage submission"
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS <- "Extra Julia versions to test"
|
||||
@with_kw_noshow struct TravisCI <: BasicPlugin
|
||||
file::String = default_file("travis.yml")
|
||||
linux::Bool = true
|
||||
osx::Bool = true
|
||||
windows::Bool = true
|
||||
x86::Bool = false
|
||||
coverage::Bool = true
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS
|
||||
end
|
||||
|
||||
source(p::TravisCI) = p.file
|
||||
@ -113,11 +114,11 @@ Integrates your packages with [AppVeyor](https://appveyor.com) via [AppVeyor.jl]
|
||||
- `coverage::Bool`: Whether or not to publish code coverage ([`Codecov`](@ref) must also be included).
|
||||
$EXTRA_VERSIONS_DOC
|
||||
"""
|
||||
@with_defaults struct AppVeyor <: BasicPlugin
|
||||
file::String = default_file("appveyor.yml") <- "Path to .appveyor.yml template"
|
||||
x86::Bool = false <- "Enable 32-bit builds"
|
||||
coverage::Bool = true <- "Enable code coverage submission"
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS <- "Extra Julia versions to test"
|
||||
@with_kw_noshow struct AppVeyor <: BasicPlugin
|
||||
file::String = default_file("appveyor.yml")
|
||||
x86::Bool = false
|
||||
coverage::Bool = true
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS
|
||||
end
|
||||
|
||||
source(p::AppVeyor) = p.file
|
||||
@ -166,11 +167,11 @@ $EXTRA_VERSIONS_DOC
|
||||
!!! note
|
||||
Code coverage submission from Cirrus CI is not yet supported by [Coverage.jl](https://github.com/JuliaCI/Coverage.jl).
|
||||
"""
|
||||
@with_defaults struct CirrusCI <: BasicPlugin
|
||||
file::String = default_file("cirrus.yml") <- "Path to .cirrus.yml template"
|
||||
image::String = "freebsd-12-0-release-amd64" <- "FreeBSD image"
|
||||
coverage::Bool = true <- "Enable code coverage submission"
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS <- "Extra Julia versions to test"
|
||||
@with_kw_noshow struct CirrusCI <: BasicPlugin
|
||||
file::String = default_file("cirrus.yml")
|
||||
image::String = "freebsd-12-0-release-amd64"
|
||||
coverage::Bool = true
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS
|
||||
end
|
||||
|
||||
source(p::CirrusCI) = p.file
|
||||
@ -198,7 +199,7 @@ end
|
||||
GitLabCI(;
|
||||
file="$(contractuser(default_file("gitlab-ci.yml")))",
|
||||
coverage=true,
|
||||
extra_versions=$(map(format_version, [default_version(), VERSION])),
|
||||
extra_versions=$DEFAULT_CI_VERSIONS_NO_NIGHTLY,
|
||||
)
|
||||
|
||||
Integrates your packages with [GitLab CI](https://docs.gitlab.com/ce/ci/).
|
||||
@ -215,11 +216,11 @@ See [`Documenter`](@ref) for more information.
|
||||
!!! note
|
||||
Nightly Julia is not supported.
|
||||
"""
|
||||
@with_defaults struct GitLabCI <: BasicPlugin
|
||||
file::String = default_file("gitlab-ci.yml") <- "Path to .gitlab-ci.yml template"
|
||||
coverage::Bool = true <- "Enable code coverage submission"
|
||||
@with_kw_noshow struct GitLabCI <: BasicPlugin
|
||||
file::String = default_file("gitlab-ci.yml")
|
||||
coverage::Bool = true
|
||||
# Nightly has no Docker image.
|
||||
extra_versions::Vector = map(format_version, [default_version(), VERSION]) <- "Extra Julia versions to test"
|
||||
extra_versions::Vector = DEFAULT_CI_VERSIONS_NO_NIGHTLY
|
||||
end
|
||||
|
||||
gitignore(p::GitLabCI) = p.coverage ? COVERAGE_GITIGNORE : String[]
|
||||
@ -252,7 +253,6 @@ function view(p::GitLabCI, t::Template, pkg::AbstractString)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
is_ci(::Plugin) -> Bool
|
||||
|
||||
|
@ -7,9 +7,9 @@ Creates a `CITATION.bib` file for citing package repositories.
|
||||
- `file::AbstractString`: Template file for `CITATION.bib`.
|
||||
- `readme::Bool`: Whether or not to include a section about citing in the README.
|
||||
"""
|
||||
@with_defaults struct Citation <: BasicPlugin
|
||||
file::String = default_file("CITATION.bib") <- "Path to CITATION.bib template"
|
||||
readme::Bool = false <- """Enable "Citing" README section"""
|
||||
@with_kw_noshow struct Citation <: BasicPlugin
|
||||
file::String = default_file("CITATION.bib")
|
||||
readme::Bool = false
|
||||
end
|
||||
|
||||
tags(::Citation) = "<<", ">>"
|
||||
|
@ -8,8 +8,8 @@ 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_defaults struct Codecov <: BasicPlugin
|
||||
file::Union{String, Nothing} = nothing <- "Path to .codecov.yml template"
|
||||
@with_kw_noshow struct Codecov <: BasicPlugin
|
||||
file::Union{String, Nothing} = nothing
|
||||
end
|
||||
|
||||
source(p::Codecov) = p.file
|
||||
@ -29,8 +29,8 @@ 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_defaults struct Coveralls <: BasicPlugin
|
||||
file::Union{String, Nothing} = nothing <- "Path to .coveralls.yml template"
|
||||
@with_kw_noshow struct Coveralls <: BasicPlugin
|
||||
file::Union{String, Nothing} = nothing
|
||||
end
|
||||
|
||||
source(p::Coveralls) = p.file
|
||||
|
@ -38,7 +38,7 @@ struct Documenter{T<:Union{TravisCI, GitLabCI, Nothing}} <: Plugin
|
||||
make_jl::String
|
||||
index_md::String
|
||||
|
||||
# Can't use @with_defaults due to some weird precompilation issues.
|
||||
# Can't use @with_kw_noshow due to some weird precompilation issues.
|
||||
function Documenter{T}(;
|
||||
assets::Vector{<:AbstractString}=String[],
|
||||
makedocs_kwargs::Dict{Symbol}=Dict{Symbol, Any}(),
|
||||
@ -52,28 +52,6 @@ end
|
||||
|
||||
Documenter(; kwargs...) = Documenter{Nothing}(; kwargs...)
|
||||
|
||||
function interactive(::Type{Documenter})
|
||||
kwargs = Dict{Symbol, Any}()
|
||||
|
||||
default = default_file("docs", "make.jl")
|
||||
kwargs[:make_jl] = prompt(String, "Documenter: Path to make.jl template", default)
|
||||
|
||||
default = default_file("docs", "src", "index.md")
|
||||
kwargs[:index_md] = prompt(String, "Documenter: Path to make.jl template", default)
|
||||
|
||||
kwargs[:assets] = prompt(Vector{String}, "Documenter: Extra asset files", String[])
|
||||
|
||||
md_kw = prompt(Dict{String, String}, "Documenter: makedocs keyword arguments", Dict())
|
||||
parsed = Dict{Symbol, Any}(Symbol(p.first) => eval(Meta.parse(p.second)) for p in md_kw)
|
||||
kwargs[:makedocs_kwargs] = parsed
|
||||
|
||||
available = [Nothing, TravisCI, GitLabCI]
|
||||
f = T -> string(nameof(T))
|
||||
T = select(f, "Documenter: Documentation deployment strategy", available, Nothing)
|
||||
|
||||
return Documenter{T}(; kwargs...)
|
||||
end
|
||||
|
||||
gitignore(::Documenter) = ["/docs/build/"]
|
||||
|
||||
badges(::Documenter) = Badge[]
|
||||
|
@ -1,45 +0,0 @@
|
||||
"""
|
||||
DroneCI(; config_file::Union{AbstractString, Nothing}="") -> DroneCI
|
||||
|
||||
Add `DroneCI` to a template's plugins to add a `.drone.yml` configuration file to
|
||||
generated repositories, and an appropriate badge to the README. The default configuration
|
||||
file supports Linux on ARM32 and ARM64.
|
||||
|
||||
# Keyword Arguments
|
||||
* `config_file::Union{AbstractString, Nothing}=""`: Path to a custom `.drone.yml`.
|
||||
If `nothing` is supplied, no file will be generated.
|
||||
"""
|
||||
struct DroneCI <: GenericPlugin
|
||||
gitignore::Vector{String}
|
||||
src::Union{String, Nothing}
|
||||
dest::String
|
||||
badges::Vector{Badge}
|
||||
view::Dict{String, Any}
|
||||
|
||||
function DroneCI(; config_file::Union{AbstractString, Nothing}="")
|
||||
if config_file !== nothing
|
||||
config_file = if isempty(config_file)
|
||||
joinpath(DEFAULTS_DIR, "drone.yml")
|
||||
elseif isfile(config_file)
|
||||
abspath(config_file)
|
||||
else
|
||||
throw(ArgumentError("File $(abspath(config_file)) does not exist"))
|
||||
end
|
||||
end
|
||||
return new(
|
||||
[],
|
||||
config_file,
|
||||
".drone.yml",
|
||||
[
|
||||
Badge(
|
||||
"Build Status",
|
||||
"https://cloud.drone.io/api/badges/{{USER}}/{{PKGNAME}}.jl/status.svg",
|
||||
"https://cloud.drone.io/{{USER}}/{{PKGNAME}}.jl",
|
||||
),
|
||||
],
|
||||
Dict{String, Any}(),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
interactive(::Type{DroneCI}) = interactive(DroneCI; file="drone.yml")
|
@ -12,11 +12,11 @@ Creates a Git repository and a `.gitignore` file.
|
||||
- `gpgsign::Bool`: Whether or not to sign commits with your GPG key.
|
||||
This option requires that the Git CLI is installed, and for you to have a GPG key associated with your committer identity.
|
||||
"""
|
||||
@with_defaults struct Git <: Plugin
|
||||
ignore::Vector{String} = String[] <- "Gitignore entries"
|
||||
ssh::Bool = false <- "Enable SSH Git remote"
|
||||
manifest::Bool = false <- "Commit Manifest.toml"
|
||||
gpgsign::Bool = false <- "GPG-sign commits"
|
||||
@with_kw_noshow struct Git <: Plugin
|
||||
ignore::Vector{String} = String[]
|
||||
ssh::Bool = false
|
||||
manifest::Bool = false
|
||||
gpgsign::Bool = false
|
||||
end
|
||||
|
||||
# Try to make sure that no files are created after we commit.
|
||||
|
@ -34,15 +34,3 @@ view(::License, t::Template, ::AbstractString) = Dict(
|
||||
"AUTHORS" => join(t.authors, ", "),
|
||||
"YEAR" => year(today()),
|
||||
)
|
||||
|
||||
function interactive(::Type{License})
|
||||
destination = prompt(String, "License: License file destination", "LICENSE")
|
||||
return if prompt(Bool, "License: Use custom license file", false)
|
||||
path = prompt(String, "License: Path to custom license file", ""; required=true)
|
||||
License(; path=path, destination=destination)
|
||||
else
|
||||
available = sort(readdir(joinpath(TEMPLATES_DIR, "licenses")))
|
||||
name = select("License: Select a license", available, "MIT")
|
||||
License(; name=name, destination=destination)
|
||||
end
|
||||
end
|
||||
|
@ -5,8 +5,7 @@
|
||||
inline_badges=false,
|
||||
)
|
||||
|
||||
Creates a `README` file.
|
||||
By default, it includes badges for other included plugins
|
||||
Creates a `README` file that contains badges for other included plugins.
|
||||
|
||||
## Keyword Arguments
|
||||
- `file::AbstractString`: Template file for the `README`.
|
||||
@ -14,10 +13,10 @@ By default, it includes badges for other included plugins
|
||||
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_defaults struct Readme <: BasicPlugin
|
||||
file::String = default_file("README.md") <- "Path to README.md template"
|
||||
destination::String = "README.md" <- "README file destination"
|
||||
inline_badges::Bool = false <- "Enable inline badges"
|
||||
@with_kw_noshow struct Readme <: BasicPlugin
|
||||
file::String = default_file("README.md")
|
||||
destination::String = "README.md"
|
||||
inline_badges::Bool = false
|
||||
end
|
||||
|
||||
source(p::Readme) = p.file
|
||||
|
@ -6,9 +6,9 @@ Creates a module entrypoint.
|
||||
## Keyword Arguments
|
||||
- `file::AbstractString`: Template file for `src/<module>.jl`.
|
||||
"""
|
||||
@with_defaults mutable struct SrcDir <: BasicPlugin
|
||||
file::String = default_file("src", "module.jl") <- "Path to <module>.jl template"
|
||||
destination::String = joinpath("src", "<module>.jl")
|
||||
@with_kw_noshow mutable struct SrcDir <: BasicPlugin
|
||||
file::String = default_file("src", "module.jl")
|
||||
destination::String = ""
|
||||
end
|
||||
|
||||
Base.:(==)(a::SrcDir, b::SrcDir) = a.file == b.file
|
||||
|
@ -14,9 +14,9 @@ Sets up testing for packages.
|
||||
!!! note
|
||||
Managing test dependencies with `test/Project.toml` is only supported in Julia 1.2 and later.
|
||||
"""
|
||||
@with_defaults struct Tests <: BasicPlugin
|
||||
file::String = default_file("test", "runtests.jl") <- "Path to runtests.jl template"
|
||||
project::Bool = false <- "Enable test/Project.toml"
|
||||
@with_kw_noshow struct Tests <: BasicPlugin
|
||||
file::String = default_file("test", "runtests.jl")
|
||||
project::Bool = false
|
||||
end
|
||||
|
||||
source(p::Tests) = p.file
|
||||
|
@ -34,9 +34,6 @@ A configuration used to generate packages.
|
||||
The default plugins are [`ProjectFile`](@ref), [`SrcDir`](@ref), [`Tests`](@ref), [`Readme`](@ref), [`License`](@ref), and [`Git`](@ref).
|
||||
To override a default plugin instead of disabling it altogether, supply it via `plugins`.
|
||||
|
||||
### 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:
|
||||
@ -56,7 +53,7 @@ struct Template
|
||||
user::String
|
||||
end
|
||||
|
||||
Template(; interactive::Bool=false, kwargs...) = Template(Val(interactive); kwargs...)
|
||||
Template(; kwargs...) = Template(Val(false); kwargs...)
|
||||
|
||||
# Non-interactive constructor.
|
||||
function Template(::Val{false}; kwargs...)
|
||||
|
29
test/fixtures/AllPlugins/drone.yml
vendored
29
test/fixtures/AllPlugins/drone.yml
vendored
@ -1,29 +0,0 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: linux - arm - Julia {{VERSION}}
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: julia:{{VERSION}}
|
||||
commands:
|
||||
- "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: linux - arm64 - Julia {{VERSION}}
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: julia:{{VERSION}}
|
||||
commands:
|
||||
- "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"
|
||||
|
||||
...
|
@ -1,41 +0,0 @@
|
||||
t = Template(; user=me)
|
||||
pkg_dir = joinpath(t.dir, test_pkg)
|
||||
|
||||
@testset "DroneCI" begin
|
||||
@testset "Plugin creation" begin
|
||||
p = DroneCI()
|
||||
@test isempty(p.gitignore)
|
||||
@test p.src == joinpath(DEFAULTS_DIR, "drone.yml")
|
||||
@test p.dest == ".drone.yml"
|
||||
@test p.badges == [
|
||||
Badge(
|
||||
"Build Status",
|
||||
"https://cloud.drone.io/api/badges/{{USER}}/{{PKGNAME}}.jl/status.svg",
|
||||
"https://cloud.drone.io/{{USER}}/{{PKGNAME}}.jl",
|
||||
),
|
||||
]
|
||||
@test isempty(p.view)
|
||||
p = DroneCI(; config_file=nothing)
|
||||
@test p.src === nothing
|
||||
p = DroneCI(; config_file=test_file)
|
||||
@test p.src == test_file
|
||||
@test_throws ArgumentError DroneCI(; config_file=fake_path)
|
||||
end
|
||||
|
||||
@testset "Badge generation" begin
|
||||
p = DroneCI()
|
||||
@test badges(p, me, test_pkg) == ["[](https://cloud.drone.io/$me/$test_pkg.jl)"]
|
||||
end
|
||||
|
||||
@testset "File generation" begin
|
||||
# Without a coverage plugin in the template, there should be no coverage step.
|
||||
p = DroneCI()
|
||||
@test gen_plugin(p, t, test_pkg) == [".drone.yml"]
|
||||
@test isfile(joinpath(pkg_dir, ".drone.yml"))
|
||||
drone = read(joinpath(pkg_dir, ".drone.yml"), String)
|
||||
@test !occursin("coverage_script", drone)
|
||||
rm(joinpath(pkg_dir, ".drone.yml"))
|
||||
end
|
||||
end
|
||||
|
||||
rm(pkg_dir; recursive=true)
|
@ -6,7 +6,7 @@
|
||||
@test isempty(Template(; disable_defaults=[Git]).user)
|
||||
end
|
||||
mock(PT.default_user => () -> "username") do _du
|
||||
@test Template().user == PT.default_user()
|
||||
@test Template().user == "username"
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user