Merge pull request #19 from invenia/cdg/1.0ify

Make PkgTemplates work on 1.0
This commit is contained in:
Eric Davies 2018-09-26 16:54:04 -05:00 committed by GitHub
commit db1830daa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 548 additions and 366 deletions

View File

@ -1,38 +1,30 @@
environment: environment:
matrix: matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - julia_version: 0.7
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" - julia_version: 1.0
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - julia_version: nightly
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" platform:
- x86
- x64
matrix: matrix:
allow_failures: allow_failures:
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - julia_version: nightly
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
notifications: notifications:
- provider: Email - provider: Email
on_build_success: false on_build_success: false
on_build_failure: false on_build_failure: false
on_build_status_changed: false on_build_status_changed: false
install: install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12" - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$env:JULIA_URL,
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
build_script: build_script:
# Need to convert from shallow to complete for Pkg.clone to work - echo "%JL_BUILD_SCRIPT%"
- IF EXIST .git\shallow (git fetch --unshallow) - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
- C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"PkgTemplates\")"
test_script: test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"PkgTemplates\"; coverage=true)" # Git configuration is required to make commits in generated packages.
- git config --global user.name "AppVeyor"
after_test: - git config --global user.email "appveyor@example.com"
- C:\projects\julia\bin\julia -e "VERSION > v\"0.6.2\" && exit(); cd(Pkg.dir(\"PkgTemplates\")); Pkg.add(\"Coverage\"); using Coverage; Codecov.submit(process_folder())" - echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
on_success:
- echo "%JL_CODECOV_SCRIPT%"
- C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"

View File

@ -3,7 +3,8 @@ os:
- linux - linux
- osx - osx
julia: julia:
- 0.6 - 0.7
- 1.0
- nightly - nightly
matrix: matrix:
allow_failures: allow_failures:
@ -11,9 +12,11 @@ matrix:
fast_finish: true fast_finish: true
notifications: notifications:
email: false email: false
script: before_script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi # Git configuration is required to make commits in generated packages.
- julia -e 'Pkg.clone(pwd()); Pkg.test("PkgTemplates"; coverage=true)' - git config --global user.name "Travis"
- git config --global user.email "travis@example.com"
after_success: after_success:
- julia -e 'VERSION > v"0.6.2" && exit(); cd(Pkg.dir("PkgTemplates")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())' - julia -e 'using Pkg; Pkg.add("Coverage")'
- julia -e 'Pkg.add("Documenter"); cd(Pkg.dir("PkgTemplates")); include(joinpath("docs", "make.jl"))' - julia -e 'using Coverage; CodeCov.submit(process_folder())'
- julia -e 'using Pkg; Pkg.add("Documenter"); include(joinpath("docs", "make.jl"))'

View File

@ -1,4 +1,4 @@
Copyright (c) 2017 Chris de Graaf, Invenia Technical Computing Corporation Copyright (c) 2017-2018 Chris de Graaf, Invenia Technical Computing Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

84
Manifest.toml Normal file
View File

@ -0,0 +1,84 @@
[[AutoHashEquals]]
git-tree-sha1 = "45bb6705d93be619b81451bb2006b7ee5d4e4453"
uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
version = "0.2.0"
[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
[[Distributed]]
deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
[[InteractiveUtils]]
deps = ["LinearAlgebra", "Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
[[LibGit2]]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
[[Mustache]]
deps = ["Pkg", "Test"]
git-tree-sha1 = "fb4b57a278d18434eff78bdc2c06238f6ee3c9e7"
uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
version = "0.5.1"
[[Pkg]]
deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
[[Test]]
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[[URIParser]]
deps = ["Test", "Unicode"]
git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69"
uuid = "30578b45-9adc-5946-b283-645ec420af67"
version = "0.4.0"
[[UUIDs]]
deps = ["Random"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

15
Project.toml Normal file
View File

@ -0,0 +1,15 @@
name = "PkgTemplates"
uuid = "19f0ff7e-bab4-11e8-074b-97459630f98a"
authors = ["Chris de Graaf <chrisadegraaf@gmail.com>"]
version = "0.1.0"
[deps]
AutoHashEquals = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
URIParser = "30578b45-9adc-5946-b283-645ec420af67"

View File

@ -1,5 +1,4 @@
julia 0.6 julia 0.7
AutoHashEquals AutoHashEquals
Mustache Mustache
TerminalMenus
URIParser URIParser

View File

@ -36,8 +36,14 @@ build_script:
- C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"{{PKGNAME}}\"); Pkg.build(\"{{PKGNAME}}\")" - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"{{PKGNAME}}\"); Pkg.build(\"{{PKGNAME}}\")"
test_script: test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"{{PKGNAME}}\"{{#AFTER}}; coverage=true{{/AFTER}})"{{#AFTER}} - C:\projects\julia\bin\julia -e "Pkg.test(\"{{PKGNAME}}\"{{#AFTER}}; coverage=true{{/AFTER}})"
{{#AFTER}}
after_test:{{#CODECOV}} after_test:
- C:\projects\julia\bin\julia -e "cd(Pkg.dir(\"{{PKGNAME}}\")); Pkg.add(\"Coverage\"); using Coverage; Codecov.submit(process_folder())"{{/CODECOV}}{{#COVERALLS}} {{#CODECOV}}
- C:\projects\julia\bin\julia -e "cd(Pkg.dir(\"{{PKGNAME}}\")); Pkg.add(\"Coverage\"); using Coverage; Coveralls.submit(process_folder())"{{/COVERALLS}}{{/AFTER}} - C:\projects\julia\bin\julia -e "cd(Pkg.dir(\"{{PKGNAME}}\")); Pkg.add(\"Coverage\"); using Coverage; Codecov.submit(process_folder())"
{{/CODECOV}}
{{#COVERALLS}}
- C:\projects\julia\bin\julia -e "cd(Pkg.dir(\"{{PKGNAME}}\")); Pkg.add(\"Coverage\"); using Coverage; Coveralls.submit(process_folder())"
{{/COVERALLS}}
{{/AFTER}}

View File

@ -1,19 +1,25 @@
{{#GITLABCOVERAGE}}stages: {{#GITLABCOVERAGE}}
stages:
- test - test
- coverage - coverage
{{/GITLABCOVERAGE}}.test_template: &test_template {{/GITLABCOVERAGE}}
stage: test{{#GITLABCOVERAGE}} .test_template: &test_template
stage: test
{{#GITLABCOVERAGE}}
artifacts: artifacts:
name: coverage name: coverage
expire_in: 2 hours expire_in: 2 hours
paths: paths:
- coverage/{{/GITLABCOVERAGE}} - coverage/
{{/GITLABCOVERAGE}}
tags: tags:
- docker - docker
script: script:
- julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#GITLABCOVERAGE}}; coverage=true{{/GITLABCOVERAGE}})'{{#GITLABCOVERAGE}} - julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#GITLABCOVERAGE}}; coverage=true{{/GITLABCOVERAGE}})'
- cp -r $(julia -e 'print(Pkg.dir("{{PKGNAME}}", "src"))') coverage{{/GITLABCOVERAGE}} {{#GITLABCOVERAGE}}
- cp -r $(julia -e 'print(Pkg.dir("{{PKGNAME}}", "src"))') coverage
{{/GITLABCOVERAGE}}
Julia {{VERSION}}: Julia {{VERSION}}:
image: julia:{{VERSION}} image: julia:{{VERSION}}
@ -22,7 +28,8 @@ Julia {{VERSION}}:
Julia nightly: Julia nightly:
image: staticfloat/julia:nightly-x64 image: staticfloat/julia:nightly-x64
allow_failure: true allow_failure: true
<<: *test_template{{#GITLABCOVERAGE}} <<: *test_template
{{#GITLABCOVERAGE}}
"Coverage": "Coverage":
stage: coverage stage: coverage
@ -34,4 +41,5 @@ Julia nightly:
- apt-get update && apt-get -y install git make unzip gcc bzip2 - apt-get update && apt-get -y install git make unzip gcc bzip2
script: script:
- rm -rf src && mv coverage src - rm -rf src && mv coverage src
- julia -e 'Pkg.add("Coverage"); using Coverage; c, t = get_summary(process_folder()); @printf("Test Coverage %.2f%%\n", 100c/t)'{{/GITLABCOVERAGE}} - julia -e 'Pkg.add("Coverage"); using Coverage; c, t = get_summary(process_folder()); @printf("Test Coverage %.2f%%\n", 100c/t)'
{{/GITLABCOVERAGE}}

View File

@ -14,8 +14,16 @@ notifications:
email: false email: false
script: script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#AFTER}}; coverage=true{{/AFTER}})'{{#AFTER}} - julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#AFTER}}; coverage=true{{/AFTER}})'
after_success:{{#CODECOV}} {{#AFTER}}
- julia -e 'cd(Pkg.dir("{{PKGNAME}}")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'{{/CODECOV}}{{#COVERALLS}} after_success:
- julia -e 'cd(Pkg.dir("{{PKGNAME}}")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'{{/COVERALLS}}{{#DOCUMENTER}} {{#CODECOV}}
- julia -e 'Pkg.add("Documenter"); cd(Pkg.dir("{{PKGNAME}}")); include(joinpath("docs", "make.jl"))'{{/DOCUMENTER}}{{/AFTER}} - julia -e 'cd(Pkg.dir("{{PKGNAME}}")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
{{/CODECOV}}
{{#COVERALLS}}
- julia -e 'cd(Pkg.dir("{{PKGNAME}}")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
{{/COVERALLS}}
{{#DOCUMENTER}}
- julia -e 'Pkg.add("Documenter"); cd(Pkg.dir("{{PKGNAME}}")); include(joinpath("docs", "make.jl"))'
{{/DOCUMENTER}}
{{/AFTER}}

View File

@ -4,7 +4,7 @@ CurrentModule = PkgTemplates
# Plugins # Plugins
Plugins are the secret sauce behing `PkgTemplates`'s customization and extension. This page Plugins are the secret sauce behind `PkgTemplates`'s customization and extension. This page
describes plugins that already exist; for information on writing your own plugins, see describes plugins that already exist; for information on writing your own plugins, see
[Plugin Development](@ref). [Plugin Development](@ref).

View File

@ -2,8 +2,12 @@ __precompile__()
module PkgTemplates module PkgTemplates
using AutoHashEquals using AutoHashEquals
using Dates
using Distributed
using InteractiveUtils
using LibGit2
using Mustache using Mustache
using TerminalMenus using REPL.TerminalMenus
using URIParser using URIParser
export export

View File

@ -5,7 +5,7 @@
force::Bool=false, force::Bool=false,
ssh::Bool=false, ssh::Bool=false,
backup_dir::AbstractString="", backup_dir::AbstractString="",
) -> Void ) -> Nothing
Generate a package named `pkg_name` from `template`. Generate a package named `pkg_name` from `template`.
@ -42,7 +42,7 @@ function generate(
ssh::Bool=false, ssh::Bool=false,
backup_dir::AbstractString="", backup_dir::AbstractString="",
) )
pkg_name = Pkg.splitjl(pkg_name) pkg_name = splitjl(pkg_name)
pkg_dir = joinpath(t.dir, pkg_name) pkg_dir = joinpath(t.dir, pkg_name)
temp_pkg_dir = joinpath(dir, pkg_name) temp_pkg_dir = joinpath(dir, pkg_name)
@ -54,15 +54,15 @@ function generate(
# Initialize the repo and configure it. # Initialize the repo and configure it.
repo = LibGit2.init(temp_pkg_dir) repo = LibGit2.init(temp_pkg_dir)
info("Initialized git repo at $temp_pkg_dir") @info "Initialized git repo at $temp_pkg_dir"
LibGit2.with(LibGit2.GitConfig, repo) do cfg LibGit2.with(LibGit2.GitConfig, repo) do cfg
for (key, val) in t.gitconfig for (key, val) in t.gitconfig
LibGit2.set!(cfg, key, val) LibGit2.set!(cfg, key, val)
end end
end end
!isempty(t.gitconfig) && info("Applied git configuration") !isempty(t.gitconfig) && @info "Applied git configuration"
LibGit2.commit(repo, "Initial commit") LibGit2.commit(repo, "Initial commit")
info("Made empty initial commit") @info "Made empty initial commit"
rmt = if ssh rmt = if ssh
"git@$(t.host):$(t.user)/$pkg_name.jl.git" "git@$(t.host):$(t.user)/$pkg_name.jl.git"
else else
@ -70,13 +70,13 @@ function generate(
end end
# We need to set the remote in a strange way, see #8. # We need to set the remote in a strange way, see #8.
close(LibGit2.GitRemote(repo, "origin", rmt)) close(LibGit2.GitRemote(repo, "origin", rmt))
info("Set remote origin to $rmt") @info "Set remote origin to $rmt"
# Create the gh-pages branch if necessary. # Create the gh-pages branch if necessary.
if haskey(t.plugins, GitHubPages) if haskey(t.plugins, GitHubPages)
LibGit2.branch!(repo, "gh-pages") LibGit2.branch!(repo, "gh-pages")
LibGit2.commit(repo, "Empty initial commit") LibGit2.commit(repo, "Empty initial commit")
info("Created empty gh-pages branch") @info "Created empty gh-pages branch"
LibGit2.branch!(repo, "master") LibGit2.branch!(repo, "master")
end end
@ -92,14 +92,14 @@ function generate(
) )
LibGit2.add!(repo, files...) LibGit2.add!(repo, files...)
info("Staged $(length(files)) files/directories: $(join(files, ", "))") @info "Staged $(length(files)) files/directories: $(join(files, ", "))"
LibGit2.commit(repo, "Files generated by PkgTemplates") LibGit2.commit(repo, "Files generated by PkgTemplates")
info("Committed files generated by PkgTemplates") @info "Committed files generated by PkgTemplates"
multiple_branches = length(collect(LibGit2.GitBranchIter(repo))) > 1 multiple_branches = length(collect(LibGit2.GitBranchIter(repo))) > 1
try try
mkpath(dirname(pkg_dir)) mkpath(dirname(pkg_dir))
mv(temp_pkg_dir, pkg_dir; remove_destination=force) mv(temp_pkg_dir, pkg_dir; force=force)
info("Moved temporary package directory into $(t.dir)/") @info "Moved temporary package directory into $(t.dir)/"
catch # Likely cause is that t.dir can't be created (is a file, etc.). catch # Likely cause is that t.dir can't be created (is a file, etc.).
# We're just going to trust that backup_dir is a valid directory. # We're just going to trust that backup_dir is a valid directory.
backup_dir = if isempty(backup_dir) backup_dir = if isempty(backup_dir)
@ -109,12 +109,12 @@ function generate(
end end
mkpath(backup_dir) mkpath(backup_dir)
mv(temp_pkg_dir, joinpath(backup_dir, pkg_name)) mv(temp_pkg_dir, joinpath(backup_dir, pkg_name))
warn("$pkg_name couldn't be moved into $pkg_dir, left package in $backup_dir") @warn "$pkg_name couldn't be moved into $pkg_dir, left package in $backup_dir"
end end
info("Finished") @info "Finished"
if multiple_branches if multiple_branches
warn("Remember to push all created branches to your remote: git push --all") @info "Remember to push all created branches to your remote: git push --all"
end end
end end
@ -135,7 +135,7 @@ end
ssh::Bool=false, ssh::Bool=false,
backup_dir::AbstractString="", backup_dir::AbstractString="",
fast::Bool=false, fast::Bool=false,
) -> Void ) -> Nothing
Interactively create a template, and then generate a package with it. Arguments and Interactively create a template, and then generate a package with it. Arguments and
keywords are used in the same way as in [`generate`](@ref) and keywords are used in the same way as in [`generate`](@ref) and
@ -426,3 +426,10 @@ function substitute(
d["AFTER"] = d["DOCUMENTER"] || d["CODECOV"] || d["COVERALLS"] d["AFTER"] = d["DOCUMENTER"] || d["CODECOV"] || d["COVERALLS"]
return substitute(template, merge(d, view)) return substitute(template, merge(d, view))
end end
"""
splitjl(pkg::AbstractString) -> AbstractString
Remove ".jl" from the end of a package name if it is present.
"""
splitjl(pkg::AbstractString) = endswith(pkg, ".jl") ? pkg[1:end-3] : pkg

View File

@ -8,24 +8,24 @@ const LICENSES = Dict(
"GPL-2.0+" => "GNU Public License, Version 2.0+", "GPL-2.0+" => "GNU Public License, Version 2.0+",
"GPL-3.0+" => "GNU Public License, Version 3.0+", "GPL-3.0+" => "GNU Public License, Version 3.0+",
"LGPL-2.1+" => "Lesser GNU Public License, Version 2.1+", "LGPL-2.1+" => "Lesser GNU Public License, Version 2.1+",
"LGPL-3.0+" => "Lesser GNU Public License, Version 3.0+" "LGPL-3.0+" => "Lesser GNU Public License, Version 3.0+",
) )
""" """
available_licenses([io::IO]) -> Void available_licenses([io::IO]) -> Nothing
Print the names of all available licenses. Print the names of all available licenses.
""" """
available_licenses(io::IO) = println(io, join(("$k: $v" for (k, v) in LICENSES), "\n")) available_licenses(io::IO) = print(io, join(("$k: $v" for (k, v) in LICENSES), "\n"))
available_licenses() = available_licenses(STDOUT) available_licenses() = available_licenses(stdout)
""" """
show_license([io::IO], license::AbstractString) -> Void show_license([io::IO], license::AbstractString) -> Nothing
Print the text of `license`. Errors if the license is not found. Print the text of `license`. Errors if the license is not found.
""" """
show_license(io::IO, license::AbstractString) = println(io, read_license(license)) show_license(io::IO, license::AbstractString) = print(io, read_license(license))
show_license(license::AbstractString) = show_license(STDOUT, license) show_license(license::AbstractString) = show_license(stdout, license)
""" """
read_license(license::AbstractString) -> String read_license(license::AbstractString) -> String

View File

@ -1,5 +1,3 @@
import Base.show
""" """
Generic plugins are plugins that add any number of patterns to the generated package's Generic plugins are plugins that add any number of patterns to the generated package's
`.gitignore`, and have at most one associated file to generate. `.gitignore`, and have at most one associated file to generate.
@ -7,7 +5,7 @@ Generic plugins are plugins that add any number of patterns to the generated pac
# Attributes # Attributes
* `gitignore::Vector{AbstractString}`: Array of patterns to be added to the `.gitignore` of * `gitignore::Vector{AbstractString}`: Array of patterns to be added to the `.gitignore` of
generated packages that use this plugin. generated packages that use this plugin.
* `src::Nullable{AbstractString}`: Path to the file that will be copied into the generated * `src::Union{AbstractString, Nothing}`: Path to the file that will be copied into the generated
package repository. If set to `nothing`, no file will be generated. When this defaults package repository. If set to `nothing`, no file will be generated. When this defaults
to an empty string, there should be a default file in `defaults` that will be copied. to an empty string, there should be a default file in `defaults` that will be copied.
That file's name is usually the same as the plugin's name, except in all lowercase and That file's name is usually the same as the plugin's name, except in all lowercase and
@ -25,12 +23,12 @@ Generic plugins are plugins that add any number of patterns to the generated pac
```julia ```julia
@auto_hash_equals struct MyPlugin <: GenericPlugin @auto_hash_equals struct MyPlugin <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
function MyPlugin(; config_file::Union{AbstractString, Void}="") function MyPlugin(; config_file::Union{AbstractString, Nothing}="")
if config_file != nothing if config_file != nothing
config_file = if isempty(config_file) config_file = if isempty(config_file)
joinpath(DEFAULTS_DIR, "my-plugin.toml") joinpath(DEFAULTS_DIR, "my-plugin.toml")
@ -69,14 +67,14 @@ config template file doesn't follow the generic naming convention, we added anot
""" """
abstract type GenericPlugin <: Plugin end abstract type GenericPlugin <: Plugin end
function show(io::IO, p::GenericPlugin) function Base.show(io::IO, p::GenericPlugin)
spc = " " spc = " "
println(io, "$(Base.datatype_name(typeof(p))):") println(io, "$(nameof(typeof(p))):")
cfg = if isnull(p.src) cfg = if p.src === nothing
"None" "None"
else else
dirname(get(p.src)) == DEFAULTS_DIR ? "Default" : get(p.src) dirname(p.src) == DEFAULTS_DIR ? "Default" : p.src
end end
println(io, "$spc→ Config file: $cfg") println(io, "$spc→ Config file: $cfg")
@ -213,13 +211,11 @@ function gen_plugin(
dir::AbstractString, dir::AbstractString,
pkg_name::AbstractString, pkg_name::AbstractString,
) )
src = try if plugin.src === nothing
get(plugin.src)
catch
return String[] return String[]
end end
text = substitute( text = substitute(
readstring(src), read(plugin.src, String),
template; template;
view=merge(Dict("PKGNAME" => pkg_name), plugin.view), view=merge(Dict("PKGNAME" => pkg_name), plugin.view),
) )
@ -250,7 +246,7 @@ end
""" """
interactive( interactive(
plugin_type::Type{<:Plugin}; plugin_type::Type{<:Plugin};
file::Union{AbstractString, Void}="", file::Union{AbstractString, Nothing}="",
) -> Plugin ) -> Plugin
Interactively create a plugin of type `plugin_type`, where `file` is the plugin type's Interactively create a plugin of type `plugin_type`, where `file` is the plugin type's
@ -259,7 +255,7 @@ default config template with a non-standard name (for `MyPlugin`, this is anythi
""" """
function interactive( function interactive(
plugin_type::Type{<:GenericPlugin}; plugin_type::Type{<:GenericPlugin};
file::Union{AbstractString, Void}="", file::Union{AbstractString, Nothing}="",
) )
plugin_name = String(split(string(plugin_type), ".")[end]) plugin_name = String(split(string(plugin_type), ".")[end])
# By default, we expect the default plugin file template for a plugin called # By default, we expect the default plugin file template for a plugin called
@ -270,7 +266,7 @@ function interactive(
if default_config_file == nothing if default_config_file == nothing
print("[None]: ") print("[None]: ")
else else
print("[$(replace(default_config_file, homedir(), "~"))]: ") print("[$(replace(default_config_file, homedir() => "~"))]: ")
end end
config_file = readline() config_file = readline()
config_file = if uppercase(config_file) == "NONE" config_file = if uppercase(config_file) == "NONE"

View File

@ -1,21 +1,21 @@
""" """
AppVeyor(; config_file::Union{AbstractString, Void}="") -> AppVeyor AppVeyor(; config_file::Union{AbstractString, Nothing}="") -> AppVeyor
Add `AppVeyor` to a template's plugins to add a `.appveyor.yml` configuration file to Add `AppVeyor` to a template's plugins to add a `.appveyor.yml` configuration file to
generated repositories, and an appropriate badge to the README. generated repositories, and an appropriate badge to the README.
# Keyword Arguments # Keyword Arguments
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.appveyor.yml`. * `config_file::Union{AbstractString, Nothing}=""`: Path to a custom `.appveyor.yml`.
If `nothing` is supplied, no file will be generated. If `nothing` is supplied, no file will be generated.
""" """
@auto_hash_equals struct AppVeyor <: GenericPlugin @auto_hash_equals struct AppVeyor <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
function AppVeyor(; config_file::Union{AbstractString, Void}="") function AppVeyor(; config_file::Union{AbstractString, Nothing}="")
if config_file != nothing if config_file != nothing
config_file = if isempty(config_file) config_file = if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "appveyor.yml") config_file = joinpath(DEFAULTS_DIR, "appveyor.yml")

View File

@ -1,22 +1,22 @@
""" """
CodeCov(; config_file::Union{AbstractString, Void}=nothing) -> CodeCov CodeCov(; config_file::Union{AbstractString, Nothing}=nothing) -> CodeCov
Add `CodeCov` to a template's plugins to optionally add a `.codecov.yml` configuration file Add `CodeCov` to a template's plugins to optionally add a `.codecov.yml` configuration file
to generated repositories, and an appropriate badge to the README. Also updates the to generated repositories, and an appropriate badge to the README. Also updates the
`.gitignore` accordingly. `.gitignore` accordingly.
# Keyword Arguments: # Keyword Arguments:
* `config_file::Union{AbstractString, Void}=nothing`: Path to a custom `.codecov.yml`. * `config_file::Union{AbstractString, Nothing}=nothing`: Path to a custom `.codecov.yml`.
If left unset, no file will be generated. If left unset, no file will be generated.
""" """
@auto_hash_equals struct CodeCov <: GenericPlugin @auto_hash_equals struct CodeCov <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
function CodeCov(; config_file::Union{AbstractString, Void}=nothing) function CodeCov(; config_file::Union{AbstractString, Nothing}=nothing)
if config_file != nothing if config_file != nothing
config_file = if isfile(config_file) config_file = if isfile(config_file)
abspath(config_file) abspath(config_file)

View File

@ -1,22 +1,22 @@
""" """
Coveralls(; config_file::Union{AbstractString, Void}=nothing) -> Coveralls Coveralls(; config_file::Union{AbstractString, Nothing}=nothing) -> Coveralls
Add `Coveralls` to a template's plugins to optionally add a `.coveralls.yml` configuration Add `Coveralls` to a template's plugins to optionally add a `.coveralls.yml` configuration
file to generated repositories, and an appropriate badge to the README. Also updates the file to generated repositories, and an appropriate badge to the README. Also updates the
`.gitignore` accordingly. `.gitignore` accordingly.
# Keyword Arguments: # Keyword Arguments:
* `config_file::Union{AbstractString, Void}=nothing`: Path to a custom `.coveralls.yml`. * `config_file::Union{AbstractString, Nothing}=nothing`: Path to a custom `.coveralls.yml`.
If left unset, no file will be generated. If left unset, no file will be generated.
""" """
@auto_hash_equals struct Coveralls <: GenericPlugin @auto_hash_equals struct Coveralls <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
function Coveralls(; config_file::Union{AbstractString, Void}=nothing) function Coveralls(; config_file::Union{AbstractString, Nothing}=nothing)
if config_file != nothing if config_file != nothing
config_file = if isfile(config_file) config_file = if isfile(config_file)
abspath(config_file) abspath(config_file)

View File

@ -1,5 +1,3 @@
import Base.show
""" """
Add a `Documenter` subtype to a template's plugins to add support for documentation Add a `Documenter` subtype to a template's plugins to add support for documentation
generation via [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl). generation via [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl).
@ -25,13 +23,12 @@ function gen_plugin(
# assets/file1, # assets/file1,
# assets/file2, # assets/file2,
# ] # ]
const TAB = repeat(" ", 4) tab = repeat(" ", 4)
assets_string = "[\n" assets_string = "[\n"
for asset in plugin.assets for asset in plugin.assets
assets_string *= """$(TAB^2)"assets/$(basename(asset))",\n""" assets_string *= """$(tab^2)"assets/$(basename(asset))",\n"""
end end
assets_string *= "$TAB]" assets_string *= "$tab]"
else else
assets_string = "[]" assets_string = "[]"
end end
@ -57,13 +54,13 @@ function gen_plugin(
end end
readme_path = joinpath(dir, pkg_name, "README.md") readme_path = joinpath(dir, pkg_name, "README.md")
if isfile(readme_path) if isfile(readme_path)
cp(readme_path, joinpath(docs_dir, "index.md"), remove_destination=true) cp(readme_path, joinpath(docs_dir, "index.md"), force=true)
end end
end end
function show(io::IO, p::Documenter) function Base.show(io::IO, p::Documenter)
spc = " " spc = " "
println(io, "$(Base.datatype_name(typeof(p))):") println(io, "$(nameof(typeof(p))):")
n = length(p.assets) n = length(p.assets)
s = n == 1 ? "" : "s" s = n == 1 ? "" : "s"
@ -71,7 +68,7 @@ function show(io::IO, p::Documenter)
if n == 0 if n == 0
println(io) println(io)
else else
println(io, ": $(join(map(a -> replace(a, homedir(), "~"), p.assets), ", "))") println(io, ": $(join(map(a -> replace(a, homedir() => "~"), p.assets), ", "))")
end end
n = length(p.gitignore) n = length(p.gitignore)
@ -81,7 +78,7 @@ function show(io::IO, p::Documenter)
end end
function interactive(plugin_type::Type{<:Documenter}) function interactive(plugin_type::Type{<:Documenter})
t = Base.datatype_name(plugin_type) t = nameof(plugin_type)
print("$t: Enter any Documenter asset files (separated by spaces) []: ") print("$t: Enter any Documenter asset files (separated by spaces) []: ")
return plugin_type(; assets=String.(split(readline()))) return plugin_type(; assets=String.(split(readline())))
end end

View File

@ -1,23 +1,23 @@
""" """
GitLabCI(; config_file::Union{AbstractString, Void}="", coverage::Bool=true) -> GitLabCI GitLabCI(; config_file::Union{AbstractString, Nothing}="", coverage::Bool=true) -> GitLabCI
Add `GitLabCI` to a template's plugins to add a `.gitlab-ci.yml` configuration file to Add `GitLabCI` to a template's plugins to add a `.gitlab-ci.yml` configuration file to
generated repositories, and appropriate badge(s) to the README. generated repositories, and appropriate badge(s) to the README.
# Keyword Arguments: # Keyword Arguments:
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.gitlab-ci.yml`. * `config_file::Union{AbstractString, Nothing}=""`: Path to a custom `.gitlab-ci.yml`.
If `nothing` is supplied, no file will be generated. If `nothing` is supplied, no file will be generated.
* `coverage::Bool=true`: Whether or not GitLab CI's built-in code coverage analysis should * `coverage::Bool=true`: Whether or not GitLab CI's built-in code coverage analysis should
be enabled. be enabled.
""" """
@auto_hash_equals struct GitLabCI <: GenericPlugin @auto_hash_equals struct GitLabCI <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
function GitLabCI(; config_file::Union{AbstractString, Void}="", coverage::Bool=true) function GitLabCI(; config_file::Union{AbstractString, Nothing}="", coverage::Bool=true)
if config_file != nothing if config_file != nothing
config_file = if isempty(config_file) config_file = if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "gitlab-ci.yml") config_file = joinpath(DEFAULTS_DIR, "gitlab-ci.yml")

View File

@ -1,21 +1,21 @@
""" """
TravisCI(; config_file::Union{AbstractString, Void}="") -> TravisCI TravisCI(; config_file::Union{AbstractString, Nothing}="") -> TravisCI
Add `TravisCI` to a template's plugins to add a `.travis.yml` configuration file to Add `TravisCI` to a template's plugins to add a `.travis.yml` configuration file to
generated repositories, and an appropriate badge to the README. generated repositories, and an appropriate badge to the README.
# Keyword Arguments: # Keyword Arguments:
* `config_file::Union{AbstractString, Void}=""`: Path to a custom `.travis.yml`. * `config_file::Union{AbstractString, Nothing}=""`: Path to a custom `.travis.yml`.
If `nothing` is supplied, no file will be generated. If `nothing` is supplied, no file will be generated.
""" """
@auto_hash_equals struct TravisCI <: GenericPlugin @auto_hash_equals struct TravisCI <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
function TravisCI(; config_file::Union{AbstractString, Void}="") function TravisCI(; config_file::Union{AbstractString, Nothing}="")
if config_file != nothing if config_file != nothing
config_file = if isempty(config_file) config_file = if isempty(config_file)
config_file = joinpath(DEFAULTS_DIR, "travis.yml") config_file = joinpath(DEFAULTS_DIR, "travis.yml")
@ -32,8 +32,8 @@ generated repositories, and an appropriate badge to the README.
[ [
Badge( Badge(
"Build Status", "Build Status",
"https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl.svg?branch=master", "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl.svg?branch=master",
"https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl", "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl",
), ),
], ],
Dict{String, Any}(), Dict{String, Any}(),

View File

@ -1,4 +1,9 @@
import Base.show """
dev_dir() -> String
Get the default development directory (~/.julia/dev).
"""
dev_dir() = joinpath(first(DEPOT_PATH), "dev")
""" """
Template(; kwargs...) -> Template Template(; kwargs...) -> Template
@ -24,10 +29,10 @@ create a template, you can use [`interactive_template`](@ref) instead.
license. Supply a string for one author or an array for multiple. Similarly to `user`, license. Supply a string for one author or an array for multiple. Similarly to `user`,
it will try to take the value of a supplied git config's "user.name" key, then the global it will try to take the value of a supplied git config's "user.name" key, then the global
git config's value, if it is left unset. git config's value, if it is left unset.
* `years::Union{Integer, AbstractString}=Dates.year(Dates.today())`: Copyright years on the * `years::Union{Integer, AbstractString}=$(Dates.year(Dates.today()))`: Copyright years on
license. Can be supplied by a number, or a string such as "2016 - 2017". the license. Can be supplied by a number, or a string such as "2016 - 2017".
* `dir::AbstractString=Pkg.dir()`: Directory in which the package will go. Relative paths * `dir::AbstractString=$(dev_dir())`: Directory in which the package will go. Relative
are converted to absolute ones at template creation time. paths are converted to absolute ones at template creation time.
* `precompile::Bool=true`: Whether or not to enable precompilation in generated packages. * `precompile::Bool=true`: Whether or not to enable precompilation in generated packages.
* `julia_version::VersionNumber=VERSION`: Minimum allowed Julia version. * `julia_version::VersionNumber=VERSION`: Minimum allowed Julia version.
* `requirements::Vector{<:AbstractString}=String[]`: Package requirements. If there are * `requirements::Vector{<:AbstractString}=String[]`: Package requirements. If there are
@ -53,10 +58,10 @@ create a template, you can use [`interactive_template`](@ref) instead.
function Template(; function Template(;
user::AbstractString="", user::AbstractString="",
host::AbstractString="https://github.com", host::AbstractString="https://github.com",
license::Union{AbstractString, Void}="MIT", license::AbstractString="MIT",
authors::Union{AbstractString, Vector{<:AbstractString}}="", authors::Union{AbstractString, Vector{<:AbstractString}}="",
years::Union{Integer, AbstractString}=Dates.year(Dates.today()), years::Union{Integer, AbstractString}=Dates.year(Dates.today()),
dir::AbstractString=Pkg.dir(), dir::AbstractString=dev_dir(),
precompile::Bool=true, precompile::Bool=true,
julia_version::VersionNumber=VERSION, julia_version::VersionNumber=VERSION,
requirements::Vector{<:AbstractString}=String[], requirements::Vector{<:AbstractString}=String[],
@ -98,12 +103,12 @@ create a template, you can use [`interactive_template`](@ref) instead.
"requirements contains duplicate packages with conflicting versions" "requirements contains duplicate packages with conflicting versions"
)) ))
elseif diff > 0 elseif diff > 0
warn("Removed $(diff) duplicate$(diff == 1 ? "" : "s") from requirements") @warn "Removed $(diff) duplicate$(diff == 1 ? "" : "s") from requirements"
end end
plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins) plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins)
if (length(plugins) != length(plugin_dict)) if (length(plugins) != length(plugin_dict))
warn("Plugin list contained duplicates, only the last of each type was kept") @warn "Plugin list contained duplicates, only the last of each type was kept"
end end
new( new(
@ -113,7 +118,7 @@ create a template, you can use [`interactive_template`](@ref) instead.
end end
end end
function show(io::IO, t::Template) function Base.show(io::IO, t::Template)
maybe_none(s::AbstractString) = isempty(string(s)) ? "None" : string(s) maybe_none(s::AbstractString) = isempty(string(s)) ? "None" : string(s)
spc = " " spc = " "
@ -128,7 +133,7 @@ function show(io::IO, t::Template)
println(io, "$(t.license) ($(t.authors) $(t.years))") println(io, "$(t.license) ($(t.authors) $(t.years))")
end end
println(io, "$spc→ Package directory: $(replace(maybe_none(t.dir), homedir(), "~"))") println(io, "$spc→ Package directory: $(replace(maybe_none(t.dir), homedir() => "~"))")
println(io, "$spc→ Precompilation enabled: $(t.precompile ? "Yes" : "No")") println(io, "$spc→ Precompilation enabled: $(t.precompile ? "Yes" : "No")")
println(io, "$spc→ Minimum Julia version: v$(version_floor(t.julia_version))") println(io, "$spc→ Minimum Julia version: v$(version_floor(t.julia_version))")
@ -173,7 +178,7 @@ Interactively create a [`Template`](@ref). If `fast` is set, defaults will be as
all values except username and plugins. all values except username and plugins.
""" """
function interactive_template(; fast::Bool=false) function interactive_template(; fast::Bool=false)
info("Default values are shown in [brackets]") @info "Default values are shown in [brackets]"
# Getting the leaf types in a separate thread eliminates an awkward wait after # Getting the leaf types in a separate thread eliminates an awkward wait after
# "Select plugins" is printed. # "Select plugins" is printed.
plugin_types = @spawn leaves(Plugin) plugin_types = @spawn leaves(Plugin)
@ -206,7 +211,7 @@ function interactive_template(; fast::Bool=false)
io = IOBuffer() io = IOBuffer()
available_licenses(io) available_licenses(io)
licenses = ["" => "", collect(LICENSES)...] licenses = ["" => "", collect(LICENSES)...]
menu = RadioMenu(["None", split(String(take!(io)), "\n")...]) menu = RadioMenu(String["None", split(String(take!(io)), "\n")...])
# If the user breaks out of the menu with Ctrl-c, the result is -1, the absolute # If the user breaks out of the menu with Ctrl-c, the result is -1, the absolute
# value of which correponds to no license. # value of which correponds to no license.
licenses[abs(request(menu))].first licenses[abs(request(menu))].first
@ -235,9 +240,9 @@ function interactive_template(; fast::Bool=false)
end end
kwargs[:dir] = if fast kwargs[:dir] = if fast
Pkg.dir() dev_dir()
else else
default_dir = Pkg.dir() default_dir = dev_dir()
print("Enter the path to the package directory [$default_dir]: ") print("Enter the path to the package directory [$default_dir]: ")
dir = readline() dir = readline()
isempty(dir) ? default_dir : dir isempty(dir) ? default_dir : dir
@ -276,7 +281,7 @@ function interactive_template(; fast::Bool=false)
isempty(line) && break isempty(line) && break
tokens = split(line, " ", limit=2) tokens = split(line, " ", limit=2)
if haskey(gitconfig, tokens[1]) if haskey(gitconfig, tokens[1])
warn("Duplicate key '$(tokens[1])': Replacing old value '$(tokens[2])'") @warn "Duplicate key '$(tokens[1])': Replacing old value '$(tokens[2])'"
end end
gitconfig[tokens[1]] = tokens[2] gitconfig[tokens[1]] = tokens[2]
end end
@ -285,7 +290,7 @@ function interactive_template(; fast::Bool=false)
println("Select plugins:") println("Select plugins:")
# Only include plugin types which have an `interactive` method. # Only include plugin types which have an `interactive` method.
plugin_types = filter(t -> method_exists(interactive, (Type{t},)), fetch(plugin_types)) plugin_types = filter(t -> hasmethod(interactive, (Type{t},)), fetch(plugin_types))
type_names = map(t -> split(string(t), ".")[end], plugin_types) type_names = map(t -> split(string(t), ".")[end], plugin_types)
menu = MultiSelectMenu(String.(type_names); pagesize=length(type_names)) menu = MultiSelectMenu(String.(type_names); pagesize=length(type_names))
selected = collect(request(menu)) selected = collect(request(menu))
@ -301,4 +306,4 @@ end
Get all concrete subtypes of `t`. Get all concrete subtypes of `t`.
""" """
leaves(t::Type)::Vector{DataType} = isleaftype(t) ? [t] : vcat(leaves.(subtypes(t))...) leaves(t::Type)::Vector{DataType} = isconcretetype(t) ? [t] : vcat(leaves.(subtypes(t))...)

View File

@ -2,30 +2,30 @@
# which seems to be the case in Travis CI OSX builds. # which seems to be the case in Travis CI OSX builds.
# https://travis-ci.org/invenia/PkgTemplates.jl/jobs/267682403#L115 # https://travis-ci.org/invenia/PkgTemplates.jl/jobs/267682403#L115
# https://github.com/nick-paul/TerminalMenus.jl/issues/5 # https://github.com/nick-paul/TerminalMenus.jl/issues/5
# This also affects any time we write to STDIN.buffer, because # This also affects any time we write to stdin.buffer, because
# IOStreams do not have that attribute. # IOStreams do not have that attribute.
# Therefore, we skip any interactive tests on OSX builds. # Therefore, we skip any interactive tests on OSX builds.
@testset "Interactive template creation" begin @testset "Interactive template creation" begin
write(STDIN.buffer, "$me\n\n\r\n\n\n\n\nd") write(stdin.buffer, "$me\n\n\r\n\n\n\n\nd")
t = interactive_template() t = interactive_template()
@test t.user == me @test t.user == me
@test t.host == "github.com" @test t.host == "github.com"
@test isempty(t.license) @test isempty(t.license)
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
@test t.years == string(Dates.year(Dates.today())) @test t.years == string(Dates.year(Dates.today()))
@test t.dir == Pkg.dir() @test t.dir == default_dir
@test t.julia_version == VERSION @test t.julia_version == VERSION
@test isempty(t.requirements) @test isempty(t.requirements)
@test isempty(t.gitconfig) @test isempty(t.gitconfig)
@test isempty(t.plugins) @test isempty(t.plugins)
if isempty(LibGit2.getconfig("github.user", "")) if isempty(LibGit2.getconfig("github.user", ""))
write(STDIN.buffer, "\n") write(stdin.buffer, "\n")
@test_throws ArgumentError t = interactive_template() @test_throws ArgumentError t = interactive_template()
end end
write(STDIN.buffer, "$me\ngitlab.com\n$('\x1b')[B\r$me\n2016\n$test_file\nno\n0.5\nX Y\nkey val val\nkey2 val2\n\n$('\x1b')[B\r$('\x1b')[B\rd\n\n") write(stdin.buffer, "$me\ngitlab.com\n$('\x1b')[B\r$me\n2016\n$test_file\nno\n0.5\nX Y\nkey val val\nkey2 val2\n\n$('\x1b')[B\r$('\x1b')[B\rd\n\n")
t = interactive_template() t = interactive_template()
@test t.user == me @test t.user == me
@test t.host == "gitlab.com" @test t.host == "gitlab.com"
@ -41,10 +41,10 @@
# Like above, not sure which plugins this will generate. # Like above, not sure which plugins this will generate.
@test length(t.plugins) == 2 @test length(t.plugins) == 2
write(STDIN.buffer, "$me\n\n\r\n\n\n\nA B\n A B\n\nd") write(stdin.buffer, "$me\n\n\r\n\n\n\nA B\nA B\n\nd")
@test_warn r".+" interactive_template() @test_logs (:warn, r".+") match_mode=:any interactive_template()
write(STDIN.buffer, "$me\nd") write(stdin.buffer, "$me\nd")
t = interactive_template(; fast=true) t = interactive_template(; fast=true)
@test t.user == me @test t.user == me
@test t.host == "github.com" @test t.host == "github.com"
@ -52,7 +52,7 @@
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
# I guess this could technically break if it runs on New Year's Eve... # I guess this could technically break if it runs on New Year's Eve...
@test t.years == string(Dates.year(Dates.today())) @test t.years == string(Dates.year(Dates.today()))
@test t.dir == Pkg.dir() @test t.dir == default_dir
@test t.julia_version == VERSION @test t.julia_version == VERSION
@test isempty(t.requirements) @test isempty(t.requirements)
@test isempty(t.gitconfig) @test isempty(t.gitconfig)
@ -62,8 +62,8 @@ end
@testset "Interactive package generation" begin @testset "Interactive package generation" begin
cfg = join(("$k $v" for (k, v) in gitconfig), "\n") cfg = join(("$k $v" for (k, v) in gitconfig), "\n")
write(STDIN.buffer, "$me\n\n\r\n\n\n\n$cfg\n\nd") write(stdin.buffer, "$me\n\n\r\n\n\n\n$cfg\n\nd")
generate_interactive(test_pkg) generate_interactive(test_pkg)
@test isdir(Pkg.dir(test_pkg)) @test isdir(joinpath(default_dir, test_pkg))
rm(Pkg.dir(test_pkg); force=true, recursive=true) rm(joinpath(default_dir, test_pkg); force=true, recursive=true)
end end

View File

@ -1,90 +1,90 @@
# These tests are to be skipped in OSX builds, see ./interactive.jl for more info. # These tests are to be skipped in OSX builds, see ./interactive.jl for more info.
@testset "TravisCI" begin @testset "TravisCI" begin
write(STDIN.buffer, "\n") write(stdin.buffer, "\n")
p = interactive(TravisCI) p = interactive(TravisCI)
@test get(p.src, "") == joinpath(DEFAULTS_DIR, "travis.yml") @test p.src == joinpath(DEFAULTS_DIR, "travis.yml")
write(STDIN.buffer, "$test_file\n") write(stdin.buffer, "$test_file\n")
p = interactive(TravisCI) p = interactive(TravisCI)
@test get(p.src, "") == test_file @test p.src == test_file
write(STDIN.buffer, "none\n") write(stdin.buffer, "none\n")
p = interactive(TravisCI) p = interactive(TravisCI)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$fake_path\n") write(stdin.buffer, "$fake_path\n")
@test_throws ArgumentError interactive(TravisCI) @test_throws ArgumentError interactive(TravisCI)
println() println()
end end
@testset "AppVeyor" begin @testset "AppVeyor" begin
write(STDIN.buffer, "\n") write(stdin.buffer, "\n")
p = interactive(AppVeyor) p = interactive(AppVeyor)
@test get(p.src, "") == joinpath(DEFAULTS_DIR, "appveyor.yml") @test p.src == joinpath(DEFAULTS_DIR, "appveyor.yml")
write(STDIN.buffer, "$test_file\n") write(stdin.buffer, "$test_file\n")
p = interactive(AppVeyor) p = interactive(AppVeyor)
@test get(p.src, "") == test_file @test p.src == test_file
write(STDIN.buffer, "none\n") write(stdin.buffer, "none\n")
p = interactive(AppVeyor) p = interactive(AppVeyor)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$fake_path\n") write(stdin.buffer, "$fake_path\n")
@test_throws ArgumentError interactive(AppVeyor) @test_throws ArgumentError interactive(AppVeyor)
println() println()
end end
@testset "GitLabCI" begin @testset "GitLabCI" begin
write(STDIN.buffer, "\n\n") write(stdin.buffer, "\n\n")
p = interactive(GitLabCI) p = interactive(GitLabCI)
@test get(p.src, "") == joinpath(DEFAULTS_DIR, "gitlab-ci.yml") @test p.src == joinpath(DEFAULTS_DIR, "gitlab-ci.yml")
@test p.view == Dict("GITLABCOVERAGE" => true) @test p.view == Dict("GITLABCOVERAGE" => true)
write(STDIN.buffer, "$test_file\nno\n") write(stdin.buffer, "$test_file\nno\n")
p = interactive(GitLabCI) p = interactive(GitLabCI)
@test get(p.src, "") == test_file @test p.src == test_file
@test p.view == Dict("GITLABCOVERAGE" => false) @test p.view == Dict("GITLABCOVERAGE" => false)
write(STDIN.buffer, "none\n\n") write(stdin.buffer, "none\n\n")
p = interactive(GitLabCI) p = interactive(GitLabCI)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$fake_path\n\n") write(stdin.buffer, "$fake_path\n\n")
@test_throws ArgumentError interactive(GitLabCI) @test_throws ArgumentError interactive(GitLabCI)
println() println()
end end
@testset "CodeCov" begin @testset "CodeCov" begin
write(STDIN.buffer, "\n") write(stdin.buffer, "\n")
p = interactive(CodeCov) p = interactive(CodeCov)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$test_file\n") write(stdin.buffer, "$test_file\n")
p = interactive(CodeCov) p = interactive(CodeCov)
@test get(p.src, "") == test_file @test p.src == test_file
write(STDIN.buffer, "none\n") write(stdin.buffer, "none\n")
p = interactive(CodeCov) p = interactive(CodeCov)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$fake_path\n") write(stdin.buffer, "$fake_path\n")
@test_throws ArgumentError interactive(CodeCov) @test_throws ArgumentError interactive(CodeCov)
println() println()
end end
@testset "Coveralls" begin @testset "Coveralls" begin
write(STDIN.buffer, "\n") write(stdin.buffer, "\n")
p = interactive(Coveralls) p = interactive(Coveralls)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$test_file\n") write(stdin.buffer, "$test_file\n")
p = interactive(Coveralls) p = interactive(Coveralls)
@test get(p.src, "") == test_file @test p.src == test_file
write(STDIN.buffer, "none\n") write(stdin.buffer, "none\n")
p = interactive(Coveralls) p = interactive(Coveralls)
@test isnull(p.src) @test p.src === nothing
write(STDIN.buffer, "$fake_path\n") write(stdin.buffer, "$fake_path\n")
@test_throws ArgumentError interactive(Coveralls) @test_throws ArgumentError interactive(Coveralls)
println() println()
end end
@testset "GitHubPages" begin @testset "GitHubPages" begin
write(STDIN.buffer, "\n") write(stdin.buffer, "\n")
p = interactive(GitHubPages) p = interactive(GitHubPages)
@test isempty(p.assets) @test isempty(p.assets)
write(STDIN.buffer, "$test_file\n") write(stdin.buffer, "$test_file\n")
p = interactive(GitHubPages) p = interactive(GitHubPages)
@test p.assets == [test_file] @test p.assets == [test_file]
write(STDIN.buffer, "$fake_path\n") write(stdin.buffer, "$fake_path\n")
@test_throws ArgumentError interactive(GitHubPages) @test_throws ArgumentError interactive(GitHubPages)
println() println()
end end

View File

@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Plugin creation" begin @testset "Plugin creation" begin
p = AppVeyor() p = AppVeyor()
@test isempty(p.gitignore) @test isempty(p.gitignore)
@test get(p.src, "") == joinpath(PkgTemplates.DEFAULTS_DIR, "appveyor.yml") @test p.src == joinpath(PkgTemplates.DEFAULTS_DIR, "appveyor.yml")
@test p.dest == ".appveyor.yml" @test p.dest == ".appveyor.yml"
@test p.badges == [ @test p.badges == [
Badge( Badge(
@ -18,9 +18,9 @@ pkg_dir = joinpath(temp_dir, test_pkg)
] ]
@test isempty(p.view) @test isempty(p.view)
p = AppVeyor(; config_file=nothing) p = AppVeyor(; config_file=nothing)
@test isnull(p.src) @test p.src === nothing
p = AppVeyor(; config_file=test_file) p = AppVeyor(; config_file=test_file)
@test get(p.src, "") == test_file @test p.src == test_file
@test_throws ArgumentError AppVeyor(; config_file=fake_path) @test_throws ArgumentError AppVeyor(; config_file=fake_path)
end end
@ -30,33 +30,39 @@ pkg_dir = joinpath(temp_dir, test_pkg)
end end
@testset "File generation" begin @testset "File generation" begin
# Without a coverage plugin in the template, there should be no post-test step.
p = AppVeyor() p = AppVeyor()
@test gen_plugin(p, t, temp_dir, test_pkg) == [".appveyor.yml"] @test gen_plugin(p, t, temp_dir, test_pkg) == [".appveyor.yml"]
@test isfile(joinpath(pkg_dir, ".appveyor.yml")) @test isfile(joinpath(pkg_dir, ".appveyor.yml"))
appveyor = readstring(joinpath(pkg_dir, ".appveyor.yml")) appveyor = read(joinpath(pkg_dir, ".appveyor.yml"), String)
@test !contains(appveyor, "coverage=true") @test !occursin("coverage=true", appveyor)
@test !contains(appveyor, "after_test") @test !occursin("after_test", appveyor)
@test !contains(appveyor, "Codecov.submit") @test !occursin("Codecov.submit", appveyor)
@test !contains(appveyor, "Coveralls.submit") @test !occursin("Coveralls.submit", appveyor)
rm(joinpath(pkg_dir, ".appveyor.yml")) rm(joinpath(pkg_dir, ".appveyor.yml"))
# Generating the plugin with CodeCov in the template should create a post-test step.
t.plugins[CodeCov] = CodeCov() t.plugins[CodeCov] = CodeCov()
gen_plugin(p, t, temp_dir, test_pkg) gen_plugin(p, t, temp_dir, test_pkg)
delete!(t.plugins, CodeCov) delete!(t.plugins, CodeCov)
appveyor = readstring(joinpath(pkg_dir, ".appveyor.yml")) appveyor = read(joinpath(pkg_dir, ".appveyor.yml"), String)
@test contains(appveyor, "coverage=true") @test occursin("coverage=true", appveyor)
@test contains(appveyor, "after_test") @test occursin("after_test", appveyor)
@test contains(appveyor, "Codecov.submit") @test occursin("Codecov.submit", appveyor)
@test !contains(appveyor, "Coveralls.submit") @test !occursin("Coveralls.submit", appveyor)
rm(joinpath(pkg_dir, ".appveyor.yml")) rm(joinpath(pkg_dir, ".appveyor.yml"))
# Coveralls should do the same.
t.plugins[Coveralls] = Coveralls() t.plugins[Coveralls] = Coveralls()
gen_plugin(p, t, temp_dir, test_pkg) gen_plugin(p, t, temp_dir, test_pkg)
delete!(t.plugins, Coveralls) delete!(t.plugins, Coveralls)
appveyor = readstring(joinpath(pkg_dir, ".appveyor.yml")) appveyor = read(joinpath(pkg_dir, ".appveyor.yml"), String)
@test contains(appveyor, "coverage=true") @test occursin("coverage=true", appveyor)
@test contains(appveyor, "after_test") @test occursin("after_test", appveyor)
@test contains(appveyor, "Coveralls.submit") @test occursin("Coveralls.submit", appveyor)
@test !contains(appveyor, "Codecov.submit") @test !occursin("Codecov.submit", appveyor)
rm(joinpath(pkg_dir, ".appveyor.yml")) rm(joinpath(pkg_dir, ".appveyor.yml"))
p = AppVeyor(; config_file=nothing) p = AppVeyor(; config_file=nothing)
@test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test isempty(gen_plugin(p, t, temp_dir, test_pkg))
@test !isfile(joinpath(pkg_dir, ".appveyor.yml")) @test !isfile(joinpath(pkg_dir, ".appveyor.yml"))

View File

@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Plugin creation" begin @testset "Plugin creation" begin
p = CodeCov() p = CodeCov()
@test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"] @test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
@test isnull(p.src) @test p.src === nothing
@test p.dest == ".codecov.yml" @test p.dest == ".codecov.yml"
@test p.badges == [ @test p.badges == [
Badge( Badge(
@ -18,9 +18,9 @@ pkg_dir = joinpath(temp_dir, test_pkg)
] ]
@test isempty(p.view) @test isempty(p.view)
p = CodeCov(; config_file=nothing) p = CodeCov(; config_file=nothing)
@test isnull(p.src) @test p.src === nothing
p = CodeCov(; config_file=test_file) p = CodeCov(; config_file=test_file)
@test get(p.src, "") == test_file @test p.src == test_file
@test_throws ArgumentError CodeCov(; config_file=fake_path) @test_throws ArgumentError CodeCov(; config_file=fake_path)
end end

View File

@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Plugin creation" begin @testset "Plugin creation" begin
p = Coveralls() p = Coveralls()
@test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"] @test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
@test isnull(p.src) @test p.src === nothing
@test p.dest == ".coveralls.yml" @test p.dest == ".coveralls.yml"
@test p.badges == [ @test p.badges == [
Badge( Badge(
@ -18,9 +18,9 @@ pkg_dir = joinpath(temp_dir, test_pkg)
] ]
@test isempty(p.view) @test isempty(p.view)
p = Coveralls(; config_file=nothing) p = Coveralls(; config_file=nothing)
@test isnull(p.src) @test p.src === nothing
p = Coveralls(; config_file=test_file) p = Coveralls(; config_file=test_file)
@test get(p.src, "") == test_file @test p.src == test_file
@test_throws ArgumentError Coveralls(; config_file=fake_path) @test_throws ArgumentError Coveralls(; config_file=fake_path)
end end

View File

@ -27,8 +27,8 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@test isdir(joinpath(pkg_dir, "docs")) @test isdir(joinpath(pkg_dir, "docs"))
@test isfile(joinpath(pkg_dir, "docs", "make.jl")) @test isfile(joinpath(pkg_dir, "docs", "make.jl"))
make = readchomp(joinpath(pkg_dir, "docs", "make.jl")) make = readchomp(joinpath(pkg_dir, "docs", "make.jl"))
@test contains(make, "assets=[]") @test occursin("assets=[]", make)
@test !contains(make, "deploydocs") @test !occursin("deploydocs", make)
@test isdir(joinpath(pkg_dir, "docs", "src")) @test isdir(joinpath(pkg_dir, "docs", "src"))
@test isfile(joinpath(pkg_dir, "docs", "src", "index.md")) @test isfile(joinpath(pkg_dir, "docs", "src", "index.md"))
index = readchomp(joinpath(pkg_dir, "docs", "src", "index.md")) index = readchomp(joinpath(pkg_dir, "docs", "src", "index.md"))
@ -37,20 +37,21 @@ pkg_dir = joinpath(temp_dir, test_pkg)
p = GitHubPages(; assets=[test_file]) p = GitHubPages(; assets=[test_file])
@test gen_plugin(p, t, temp_dir, test_pkg) == ["docs/"] @test gen_plugin(p, t, temp_dir, test_pkg) == ["docs/"]
make = readchomp(joinpath(pkg_dir, "docs", "make.jl")) make = readchomp(joinpath(pkg_dir, "docs", "make.jl"))
@test contains( # Check the formatting of the assets list.
make, @test occursin(
strip(""" strip("""
assets=[ assets=[
"assets/$(basename(test_file))", "assets/$(basename(test_file))",
] ]
"""), """),
make,
) )
@test isfile(joinpath(pkg_dir, "docs", "src", "assets", basename(test_file))) @test isfile(joinpath(pkg_dir, "docs", "src", "assets", basename(test_file)))
rm(joinpath(pkg_dir, "docs"); recursive=true) rm(joinpath(pkg_dir, "docs"); recursive=true)
t.plugins[TravisCI] = TravisCI() t.plugins[TravisCI] = TravisCI()
@test gen_plugin(p, t, temp_dir, test_pkg) == ["docs/"] @test gen_plugin(p, t, temp_dir, test_pkg) == ["docs/"]
make = readchomp(joinpath(pkg_dir, "docs", "make.jl")) make = readchomp(joinpath(pkg_dir, "docs", "make.jl"))
@test contains(make, "deploydocs") @test occursin("deploydocs", make)
rm(joinpath(pkg_dir, "docs"); recursive=true) rm(joinpath(pkg_dir, "docs"); recursive=true)
end end
end end

View File

@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Plugin creation" begin @testset "Plugin creation" begin
p = GitLabCI() p = GitLabCI()
@test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"] @test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"]
@test get(p.src, "") == joinpath(PkgTemplates.DEFAULTS_DIR, "gitlab-ci.yml") @test p.src == joinpath(PkgTemplates.DEFAULTS_DIR, "gitlab-ci.yml")
@test p.dest == ".gitlab-ci.yml" @test p.dest == ".gitlab-ci.yml"
@test p.badges == [ @test p.badges == [
Badge( Badge(
@ -23,9 +23,9 @@ pkg_dir = joinpath(temp_dir, test_pkg)
] ]
@test p.view == Dict("GITLABCOVERAGE" => true) @test p.view == Dict("GITLABCOVERAGE" => true)
p = GitLabCI(; config_file=nothing) p = GitLabCI(; config_file=nothing)
@test isnull(p.src) @test p.src === nothing
p = GitLabCI(; config_file=test_file) p = GitLabCI(; config_file=test_file)
@test get(p.src, "") == test_file @test p.src == test_file
@test_throws ArgumentError GitLabCI(; config_file=fake_path) @test_throws ArgumentError GitLabCI(; config_file=fake_path)
p = GitLabCI(; coverage=false) p = GitLabCI(; coverage=false)
@test p.badges == [ @test p.badges == [
@ -50,16 +50,20 @@ pkg_dir = joinpath(temp_dir, test_pkg)
p = GitLabCI() p = GitLabCI()
@test gen_plugin(p, t, temp_dir, test_pkg) == [".gitlab-ci.yml"] @test gen_plugin(p, t, temp_dir, test_pkg) == [".gitlab-ci.yml"]
@test isfile(joinpath(pkg_dir, ".gitlab-ci.yml")) @test isfile(joinpath(pkg_dir, ".gitlab-ci.yml"))
gitlab = readstring(joinpath(pkg_dir, ".gitlab-ci.yml")) gitlab = read(joinpath(pkg_dir, ".gitlab-ci.yml"), String)
@test contains(gitlab, "test_template") @test occursin("test_template", gitlab)
@test contains(gitlab, "using Coverage") # The default plugin should enable the coverage step.
@test occursin("using Coverage", gitlab)
rm(joinpath(pkg_dir, ".gitlab-ci.yml")) rm(joinpath(pkg_dir, ".gitlab-ci.yml"))
p = GitLabCI(; coverage=false) p = GitLabCI(; coverage=false)
gen_plugin(p, t, temp_dir, test_pkg) gen_plugin(p, t, temp_dir, test_pkg)
gitlab = readstring(joinpath(pkg_dir, ".gitlab-ci.yml")) gitlab = read(joinpath(pkg_dir, ".gitlab-ci.yml"), String)
@test !contains(gitlab, "using Coverage") # If coverage is false, there should be no coverage step.
@test !occursin("using Coverage", gitlab)
rm(joinpath(pkg_dir, ".gitlab-ci.yml")) rm(joinpath(pkg_dir, ".gitlab-ci.yml"))
p = GitLabCI(; config_file=nothing) p = GitLabCI(; config_file=nothing)
@test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test isempty(gen_plugin(p, t, temp_dir, test_pkg))
@test !isfile(joinpath(pkg_dir, ".gitlab-ci.yml")) @test !isfile(joinpath(pkg_dir, ".gitlab-ci.yml"))
end end

View File

@ -7,65 +7,74 @@ pkg_dir = joinpath(temp_dir, test_pkg)
@testset "Plugin creation" begin @testset "Plugin creation" begin
p = TravisCI() p = TravisCI()
@test isempty(p.gitignore) @test isempty(p.gitignore)
@test get(p.src, "") == joinpath(PkgTemplates.DEFAULTS_DIR, "travis.yml") @test p.src == joinpath(PkgTemplates.DEFAULTS_DIR, "travis.yml")
@test p.dest == ".travis.yml" @test p.dest == ".travis.yml"
@test p.badges == [ @test p.badges == [
Badge( Badge(
"Build Status", "Build Status",
"https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl.svg?branch=master", "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl.svg?branch=master",
"https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl", "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl",
), ),
] ]
@test isempty(p.view) @test isempty(p.view)
p = TravisCI(; config_file=nothing) p = TravisCI(; config_file=nothing)
@test isnull(p.src) @test p.src === nothing
p = TravisCI(; config_file=test_file) p = TravisCI(; config_file=test_file)
@test get(p.src, "") == test_file @test p.src == test_file
@test_throws ArgumentError TravisCI(; config_file=fake_path) @test_throws ArgumentError TravisCI(; config_file=fake_path)
end end
@testset "Badge generation" begin @testset "Badge generation" begin
p = TravisCI() p = TravisCI()
@test badges(p, user, test_pkg) == ["[![Build Status](https://travis-ci.org/$user/$test_pkg.jl.svg?branch=master)](https://travis-ci.org/$user/$test_pkg.jl)"] @test badges(p, user, test_pkg) == ["[![Build Status](https://travis-ci.com/$user/$test_pkg.jl.svg?branch=master)](https://travis-ci.com/$user/$test_pkg.jl)"]
end end
@testset "File generation" begin @testset "File generation" begin
# Without a coverage plugin in the template, there should be no post-test step.
p = TravisCI() p = TravisCI()
@test gen_plugin(p, t, temp_dir, test_pkg) == [".travis.yml"] @test gen_plugin(p, t, temp_dir, test_pkg) == [".travis.yml"]
@test isfile(joinpath(pkg_dir, ".travis.yml")) @test isfile(joinpath(pkg_dir, ".travis.yml"))
travis = readstring(joinpath(pkg_dir, ".travis.yml")) travis = read(joinpath(pkg_dir, ".travis.yml"), String)
@test !contains(travis, "after_success")
@test !contains(travis, "Codecov.submit") @test !occursin("after_success", travis)
@test !contains(travis, "Coveralls.submit") @test !occursin("Codecov.submit", travis)
@test !contains(travis, "Pkg.add(\"Documenter\")") @test !occursin("Coveralls.submit", travis)
@test !occursin("Pkg.add(\"Documenter\")", travis)
rm(joinpath(pkg_dir, ".travis.yml")) rm(joinpath(pkg_dir, ".travis.yml"))
# Generating the plugin with CodeCov in the template should create a post-test step.
t.plugins[CodeCov] = CodeCov() t.plugins[CodeCov] = CodeCov()
gen_plugin(p, t, temp_dir, test_pkg) gen_plugin(p, t, temp_dir, test_pkg)
delete!(t.plugins, CodeCov) delete!(t.plugins, CodeCov)
travis = readstring(joinpath(pkg_dir, ".travis.yml")) travis = read(joinpath(pkg_dir, ".travis.yml"), String)
@test contains(travis, "after_success") @test occursin("after_success", travis)
@test contains(travis, "Codecov.submit") @test occursin("Codecov.submit", travis)
@test !contains(travis, "Coveralls.submit") @test !occursin("Coveralls.submit", travis)
@test !contains(travis, "Pkg.add(\"Documenter\")") @test !occursin("Pkg.add(\"Documenter\")", travis)
rm(joinpath(pkg_dir, ".travis.yml")) rm(joinpath(pkg_dir, ".travis.yml"))
# Coveralls should do the same.
t.plugins[Coveralls] = Coveralls() t.plugins[Coveralls] = Coveralls()
gen_plugin(p, t, temp_dir, test_pkg) gen_plugin(p, t, temp_dir, test_pkg)
delete!(t.plugins, Coveralls) delete!(t.plugins, Coveralls)
travis = readstring(joinpath(pkg_dir, ".travis.yml")) travis = read(joinpath(pkg_dir, ".travis.yml"), String)
@test contains(travis, "after_success") @test occursin("after_success", travis)
@test contains(travis, "Coveralls.submit") @test occursin("Coveralls.submit", travis)
@test !contains(travis, "Codecov.submit") @test !occursin("Codecov.submit", travis)
@test !contains(travis, "Pkg.add(\"Documenter\")") @test !occursin("Pkg.add(\"Documenter\")", travis)
rm(joinpath(pkg_dir, ".travis.yml")) rm(joinpath(pkg_dir, ".travis.yml"))
# With a Documenter plugin, there should be a docs deployment step.
t.plugins[GitHubPages] = GitHubPages() t.plugins[GitHubPages] = GitHubPages()
gen_plugin(p, t, temp_dir, test_pkg) gen_plugin(p, t, temp_dir, test_pkg)
delete!(t.plugins, GitHubPages) delete!(t.plugins, GitHubPages)
travis = readstring(joinpath(pkg_dir, ".travis.yml")) travis = read(joinpath(pkg_dir, ".travis.yml"), String)
@test contains(travis, "after_success") @test occursin("after_success", travis)
@test contains(travis, "Pkg.add(\"Documenter\")") @test occursin("Pkg.add(\"Documenter\")", travis)
@test !contains(travis, "Codecov.submit") @test !occursin("Codecov.submit", travis)
@test !contains(travis, "Coveralls.submit") @test !occursin("Coveralls.submit", travis)
rm(joinpath(pkg_dir, ".travis.yml")) rm(joinpath(pkg_dir, ".travis.yml"))
p = TravisCI(; config_file=nothing) p = TravisCI(; config_file=nothing)
@test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test isempty(gen_plugin(p, t, temp_dir, test_pkg))
@test !isfile(joinpath(pkg_dir, ".travis.yml")) @test !isfile(joinpath(pkg_dir, ".travis.yml"))

View File

@ -1,5 +1,7 @@
using PkgTemplates using PkgTemplates
using Base.Test using Test
using Dates
using LibGit2
import PkgTemplates: badges, version_floor, substitute, read_license, gen_file, gen_readme, import PkgTemplates: badges, version_floor, substitute, read_license, gen_file, gen_readme,
gen_tests, gen_license, gen_require, gen_entrypoint, gen_gitignore, gen_plugin, gen_tests, gen_license, gen_require, gen_entrypoint, gen_gitignore, gen_plugin,
@ -7,17 +9,11 @@ import PkgTemplates: badges, version_floor, substitute, read_license, gen_file,
format, interactive, DEFAULTS_DIR format, interactive, DEFAULTS_DIR
mktempdir() do temp_dir mktempdir() do temp_dir
withenv("JULIA_PKGDIR" => temp_dir) do mkdir(joinpath(temp_dir, "dev"))
# We technically don't need to clone METADATA to run tests. pushfirst!(DEPOT_PATH, temp_dir)
if get(ENV, "PKGTEMPLATES_TEST_FAST", "false") == "true"
mkdir(joinpath(temp_dir, "v$(version_floor())"))
else
Pkg.init()
end
cd(temp_dir) do cd(temp_dir) do
@testset "PkgTemplates.jl" begin @testset "PkgTemplates.jl" begin
include("tests.jl") include("tests.jl")
end end
end end
end
end end

View File

@ -1,6 +1,7 @@
# A dummy GenericPlugin subtype.
struct Foo <: GenericPlugin struct Foo <: GenericPlugin
gitignore::Vector{AbstractString} gitignore::Vector{AbstractString}
src::Nullable{AbstractString} src::Union{AbstractString, Nothing}
dest::AbstractString dest::AbstractString
badges::Vector{Badge} badges::Vector{Badge}
view::Dict{String, Any} view::Dict{String, Any}
@ -8,9 +9,12 @@ struct Foo <: GenericPlugin
new([], @__FILE__, config_file, [Badge("foo", "bar", "baz")], Dict{String, Any}()) new([], @__FILE__, config_file, [Badge("foo", "bar", "baz")], Dict{String, Any}())
end end
end end
# A dummy CustomPlugin subtype.
struct Bar <: CustomPlugin end struct Bar <: CustomPlugin end
# A dummy Plugin subtype.
struct Baz <: Plugin end struct Baz <: Plugin end
# Various options to be passed into templates.
const me = "christopher-dG" const me = "christopher-dG"
const gitconfig = Dict( const gitconfig = Dict(
"user.name" => "Tester McTestFace", "user.name" => "Tester McTestFace",
@ -18,8 +22,9 @@ const gitconfig = Dict(
"github.user" => "TesterMcTestFace", "github.user" => "TesterMcTestFace",
) )
const test_pkg = "TestPkg" const test_pkg = "TestPkg"
const fake_path = bin(hash("/this/file/does/not/exist")) const fake_path = string(hash("/this/file/does/not/exist"); base=2)
const test_file = tempname() const test_file = tempname()
const default_dir = PkgTemplates.dev_dir()
const template_text = """ const template_text = """
PKGNAME: {{PKGNAME}} PKGNAME: {{PKGNAME}}
VERSION: {{VERSION}}} VERSION: {{VERSION}}}
@ -32,16 +37,19 @@ const template_text = """
write(test_file, template_text) write(test_file, template_text)
@testset "Template creation" begin @testset "Template creation" begin
# Checking default field assignments.
t = Template(; user=me) t = Template(; user=me)
@test t.user == me @test t.user == me
@test t.license == "MIT" @test t.license == "MIT"
@test t.years == string(Dates.year(Dates.today())) @test t.years == string(Dates.year(Dates.today()))
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
@test t.dir == Pkg.dir() @test t.dir == default_dir
@test t.julia_version == VERSION @test t.julia_version == VERSION
@test isempty(t.gitconfig) @test isempty(t.gitconfig)
@test isempty(t.plugins) @test isempty(t.plugins)
# Checking non-default field assignments.
t = Template(; user=me, license="") t = Template(; user=me, license="")
@test t.license == "" @test t.license == ""
@ -56,12 +64,14 @@ write(test_file, template_text)
t = Template(; user=me, authors="Some Guy") t = Template(; user=me, authors="Some Guy")
@test t.authors == "Some Guy" @test t.authors == "Some Guy"
# Vectors of authors should be comma-joined.
t = Template(; user=me, authors=["Guy", "Gal"]) t = Template(; user=me, authors=["Guy", "Gal"])
@test t.authors == "Guy, Gal" @test t.authors == "Guy, Gal"
t = Template(; user=me, dir=test_file) t = Template(; user=me, dir=test_file)
@test t.dir == abspath(test_file) @test t.dir == abspath(test_file)
if is_unix() # ~ means temporary file on Windows, not $HOME. if Sys.isunix() # ~ means temporary file on Windows, not $HOME.
# '~' should be replaced by home dir.
t = Template(; user=me, dir="~/$(basename(test_file))") t = Template(; user=me, dir="~/$(basename(test_file))")
@test t.dir == joinpath(homedir(), basename(test_file)) @test t.dir == joinpath(homedir(), basename(test_file))
end end
@ -74,8 +84,10 @@ write(test_file, template_text)
t = Template(; user=me, requirements=["$test_pkg 0.1"]) t = Template(; user=me, requirements=["$test_pkg 0.1"])
@test t.requirements == ["$test_pkg 0.1"] @test t.requirements == ["$test_pkg 0.1"]
@test_warn r".+" t = Template(; user=me, requirements=[test_pkg, test_pkg]) # Duplicate requirements should warn.
@test_logs (:warn, r".+") t = Template(; user=me, requirements=[test_pkg, test_pkg])
@test t.requirements == [test_pkg] @test t.requirements == [test_pkg]
# Duplicate requirements with non-matching versions should throw.
@test_throws ArgumentError Template(; @test_throws ArgumentError Template(;
user=me, user=me,
requirements=[test_pkg, "$test_pkg 0.1"] requirements=[test_pkg, "$test_pkg 0.1"]
@ -84,6 +96,9 @@ write(test_file, template_text)
t = Template(; user=me, gitconfig=gitconfig) t = Template(; user=me, gitconfig=gitconfig)
@test t.gitconfig == gitconfig @test t.gitconfig == gitconfig
# Git options should be used as fallbacks for template user and authors.
# But an explicitly passed username trumps the gitconfig.
t = Template(; user=me, gitconfig=gitconfig) t = Template(; user=me, gitconfig=gitconfig)
@test t.authors == gitconfig["user.name"] @test t.authors == gitconfig["user.name"]
@ -91,6 +106,7 @@ write(test_file, template_text)
@test t.user == gitconfig["github.user"] @test t.user == gitconfig["github.user"]
@test t.authors == gitconfig["user.name"] @test t.authors == gitconfig["user.name"]
# The template should contain whatever plugins you give it.
t = Template(; t = Template(;
user=me, user=me,
plugins = [GitHubPages(), TravisCI(), AppVeyor(), CodeCov(), Coveralls()], plugins = [GitHubPages(), TravisCI(), AppVeyor(), CodeCov(), Coveralls()],
@ -102,11 +118,13 @@ write(test_file, template_text)
[GitHubPages(), TravisCI(), AppVeyor(), CodeCov(), Coveralls()] [GitHubPages(), TravisCI(), AppVeyor(), CodeCov(), Coveralls()]
) )
@test_warn r".+" t = Template(; # Duplicate plugins should warn.
@test_logs (:warn, r".+") t = Template(;
user=me, user=me,
plugins=[TravisCI(), TravisCI()], plugins=[TravisCI(), TravisCI()],
) )
# If github.user is configured, use that as a default.
if isempty(LibGit2.getconfig("github.user", "")) if isempty(LibGit2.getconfig("github.user", ""))
@test_throws ArgumentError Template() @test_throws ArgumentError Template()
else else
@ -116,17 +134,18 @@ write(test_file, template_text)
@test_throws ArgumentError Template(; user=me, license="FakeLicense") @test_throws ArgumentError Template(; user=me, license="FakeLicense")
end end
# TerminalMenus doesn't work quite right on Travis OSX.
if get(ENV, "TRAVIS_OS_NAME", "") != "osx" if get(ENV, "TRAVIS_OS_NAME", "") != "osx"
include(joinpath("interactive", "interactive.jl")) include(joinpath("interactive", "interactive.jl"))
@testset "Interactive plugin creation" begin @testset "Interactive plugin creation" begin
include(joinpath("interactive", "plugins.jl")) include(joinpath("interactive", "plugins.jl"))
end end
else else
info("Skipping tests that require TerminalMenus") @info "Skipping tests that require TerminalMenus on OSX"
end end
@testset "Show methods" begin @testset "Show methods" begin
pkgdir = replace(joinpath(ENV["JULIA_PKGDIR"], "v$(version_floor())"), homedir(), "~") pkg_dir = replace(default_dir, homedir() => "~")
buf = IOBuffer() buf = IOBuffer()
t = Template(; user=me, gitconfig=gitconfig) t = Template(; user=me, gitconfig=gitconfig)
show(buf, t) show(buf, t)
@ -136,7 +155,7 @@ end
User: $me User: $me
Host: github.com Host: github.com
License: MIT ($(gitconfig["user.name"]) $(Dates.year(now()))) License: MIT ($(gitconfig["user.name"]) $(Dates.year(now())))
Package directory: $pkgdir Package directory: $pkg_dir
Precompilation enabled: Yes Precompilation enabled: Yes
Minimum Julia version: v$(PkgTemplates.version_floor()) Minimum Julia version: v$(PkgTemplates.version_floor())
0 package requirements 0 package requirements
@ -165,7 +184,7 @@ end
User: $me User: $me
Host: github.com Host: github.com
License: None License: None
Package directory: $pkgdir Package directory: $pkg_dir
Precompilation enabled: Yes Precompilation enabled: Yes
Minimum Julia version: v$(PkgTemplates.version_floor()) Minimum Julia version: v$(PkgTemplates.version_floor())
2 package requirements: Bar, Foo 2 package requirements: Bar, Foo
@ -201,76 +220,85 @@ end
temp_file = tempname() temp_file = tempname()
gen_file(temp_file, "Hello, world") gen_file(temp_file, "Hello, world")
@test isfile(temp_file) @test isfile(temp_file)
@test readstring(temp_file) == "Hello, world\n" @test read(temp_file, String) == "Hello, world\n"
rm(temp_file) rm(temp_file)
# Test the README generation.
@test gen_readme(temp_dir, test_pkg, t) == ["README.md"] @test gen_readme(temp_dir, test_pkg, t) == ["README.md"]
@test isfile(joinpath(pkg_dir, "README.md")) @test isfile(joinpath(pkg_dir, "README.md"))
readme = readchomp(joinpath(pkg_dir, "README.md")) readme = readchomp(joinpath(pkg_dir, "README.md"))
rm(joinpath(pkg_dir, "README.md")) rm(joinpath(pkg_dir, "README.md"))
@test contains(readme, "# $test_pkg") @test occursin("# $test_pkg", readme)
for p in values(t.plugins) for p in values(t.plugins)
@test contains(readme, join(badges(p, t.user, test_pkg), "\n")) @test occursin(join(badges(p, t.user, test_pkg), "\n"), readme)
end end
# Check the order of the badges. # Check the order of the badges.
@test search(readme, "github.io").start < @test something(findfirst("github.io", readme)).start <
search(readme, "travis").start < something(findfirst("travis", readme)).start <
search(readme, "appveyor").start < something(findfirst("appveyor", readme)).start <
search(readme, "codecov").start < something(findfirst("codecov", readme)).start <
search(readme, "coveralls").start something(findfirst("coveralls", readme)).start
# Plugins with badges but not in BADGE_ORDER should appear at the far right side. # Plugins with badges but not in BADGE_ORDER should appear at the far right side.
t.plugins[Foo] = Foo() t.plugins[Foo] = Foo()
gen_readme(temp_dir, test_pkg, t) gen_readme(temp_dir, test_pkg, t)
readme = readchomp(joinpath(pkg_dir, "README.md")) readme = readchomp(joinpath(pkg_dir, "README.md"))
rm(joinpath(pkg_dir, "README.md")) rm(joinpath(pkg_dir, "README.md"))
@test search(readme, "coveralls").start < search(readme, "baz").start @test <(
something(findfirst("coveralls", readme)).start,
something(findfirst("baz", readme)).start,
)
# Test the gitignore generation.
@test gen_gitignore(temp_dir, test_pkg, t) == [".gitignore"] @test gen_gitignore(temp_dir, test_pkg, t) == [".gitignore"]
@test isfile(joinpath(pkg_dir, ".gitignore")) @test isfile(joinpath(pkg_dir, ".gitignore"))
gitignore = readstring(joinpath(pkg_dir, ".gitignore")) gitignore = read(joinpath(pkg_dir, ".gitignore"), String)
rm(joinpath(pkg_dir, ".gitignore")) rm(joinpath(pkg_dir, ".gitignore"))
@test contains(gitignore, ".DS_Store") @test occursin(".DS_Store", gitignore)
for p in values(t.plugins) for p in values(t.plugins)
for entry in p.gitignore for entry in p.gitignore
@test contains(gitignore, entry) @test occursin(entry, gitignore)
end end
end end
# Test the license generation.
@test gen_license(temp_dir, test_pkg, t) == ["LICENSE"] @test gen_license(temp_dir, test_pkg, t) == ["LICENSE"]
@test isfile(joinpath(pkg_dir, "LICENSE")) @test isfile(joinpath(pkg_dir, "LICENSE"))
license = readchomp(joinpath(pkg_dir, "LICENSE")) license = readchomp(joinpath(pkg_dir, "LICENSE"))
rm(joinpath(pkg_dir, "LICENSE")) rm(joinpath(pkg_dir, "LICENSE"))
@test contains(license, t.authors) @test occursin(t.authors, license)
@test contains(license, t.years) @test occursin(t.years, license)
@test contains(license, read_license(t.license)) @test occursin(read_license(t.license), license)
# Test the source code entrypoint generation.
@test gen_entrypoint(temp_dir, test_pkg, t) == ["src/"] @test gen_entrypoint(temp_dir, test_pkg, t) == ["src/"]
@test isdir(joinpath(pkg_dir, "src")) @test isdir(joinpath(pkg_dir, "src"))
@test isfile(joinpath(pkg_dir, "src", "$test_pkg.jl")) @test isfile(joinpath(pkg_dir, "src", "$test_pkg.jl"))
entrypoint = readchomp(joinpath(pkg_dir, "src", "$test_pkg.jl")) entrypoint = readchomp(joinpath(pkg_dir, "src", "$test_pkg.jl"))
rm(joinpath(pkg_dir, "src"); recursive=true) rm(joinpath(pkg_dir, "src"); recursive=true)
@test contains(entrypoint, "__precompile__()") @test occursin("__precompile__()", entrypoint)
@test contains(entrypoint, "module $test_pkg") @test occursin("module $test_pkg", entrypoint)
t2 = Template(; user=me, precompile=false) t2 = Template(; user=me, precompile=false)
gen_entrypoint(temp_dir, test_pkg, t2) gen_entrypoint(temp_dir, test_pkg, t2)
entrypoint = readchomp(joinpath(pkg_dir, "src", "$test_pkg.jl")) entrypoint = readchomp(joinpath(pkg_dir, "src", "$test_pkg.jl"))
@test !contains(entrypoint, "__precompile__()") @test !occursin("__precompile__()", entrypoint)
@test contains(entrypoint, "module $test_pkg") @test occursin("module $test_pkg", entrypoint)
rm(joinpath(pkg_dir, "src"); recursive=true) rm(joinpath(pkg_dir, "src"); recursive=true)
# Test the REQUIRE generation.
@test gen_require(temp_dir, test_pkg, t) == ["REQUIRE"] @test gen_require(temp_dir, test_pkg, t) == ["REQUIRE"]
@test isfile(joinpath(pkg_dir, "REQUIRE")) @test isfile(joinpath(pkg_dir, "REQUIRE"))
vf = version_floor(t.julia_version) vf = version_floor(t.julia_version)
@test readchomp(joinpath(pkg_dir, "REQUIRE")) == "julia $vf\n$test_pkg" @test readchomp(joinpath(pkg_dir, "REQUIRE")) == "julia $vf\n$test_pkg"
rm(joinpath(pkg_dir, "REQUIRE")) rm(joinpath(pkg_dir, "REQUIRE"))
# Test the test generation.
@test gen_tests(temp_dir, test_pkg, t) == ["test/"] @test gen_tests(temp_dir, test_pkg, t) == ["test/"]
@test isdir(joinpath(pkg_dir, "test")) @test isdir(joinpath(pkg_dir, "test"))
@test isfile(joinpath(pkg_dir, "test", "runtests.jl")) @test isfile(joinpath(pkg_dir, "test", "runtests.jl"))
runtests = readchomp(joinpath(pkg_dir, "test", "runtests.jl")) runtests = readchomp(joinpath(pkg_dir, "test", "runtests.jl"))
rm(joinpath(pkg_dir, "test"); recursive=true) rm(joinpath(pkg_dir, "test"); recursive=true)
@test contains(runtests, "using $test_pkg") @test occursin("using $test_pkg", runtests)
@test contains(runtests, "using Base.Test") @test occursin("using Base.Test", runtests)
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
end end
@ -278,45 +306,54 @@ end
@testset "Package generation" begin @testset "Package generation" begin
t = Template(; user=me, gitconfig=gitconfig) t = Template(; user=me, gitconfig=gitconfig)
generate(test_pkg, t) generate(test_pkg, t)
@test isfile(Pkg.dir(test_pkg, "LICENSE")) pkg_dir = joinpath(default_dir, test_pkg)
@test isfile(Pkg.dir(test_pkg, "README.md"))
@test isfile(Pkg.dir(test_pkg, "REQUIRE")) # Check that the expected files all exist.
@test isfile(Pkg.dir(test_pkg, ".gitignore")) @test isfile(joinpath(pkg_dir, "LICENSE"))
@test isdir(Pkg.dir(test_pkg, "src")) @test isfile(joinpath(pkg_dir, "README.md"))
@test isfile(Pkg.dir(test_pkg, "src", "$test_pkg.jl")) @test isfile(joinpath(pkg_dir, "REQUIRE"))
@test isdir(Pkg.dir(test_pkg, "test")) @test isfile(joinpath(pkg_dir, ".gitignore"))
@test isfile(Pkg.dir(test_pkg, "test", "runtests.jl")) @test isdir(joinpath(pkg_dir, "src"))
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) @test isfile(joinpath(pkg_dir, "src", "$test_pkg.jl"))
@test isdir(joinpath(pkg_dir, "test"))
@test isfile(joinpath(pkg_dir, "test", "runtests.jl"))
# Check the gitconfig.
repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo)) branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo))
@test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"] @test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"]
# Check the configured remote and branches.
# Note: This test will fail on your system if you've configured Git # Note: This test will fail on your system if you've configured Git
# to replace all HTTPS URLs with SSH. # to replace all HTTPS URLs with SSH.
@test LibGit2.url(remote) == "https://github.com/$me/$test_pkg.jl" @test LibGit2.url(remote) == "https://github.com/$me/$test_pkg.jl"
@test in("master", branches) @test in("master", branches)
@test !in("gh-pages", branches) @test !in("gh-pages", branches)
@test !LibGit2.isdirty(repo) @test !LibGit2.isdirty(repo)
rm(Pkg.dir(test_pkg); recursive=true) rm(pkg_dir; recursive=true)
# Check that the remote is an SSH URL.
generate(t, test_pkg; ssh=true) # Test the reversed-arguments method. generate(t, test_pkg; ssh=true) # Test the reversed-arguments method.
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "git@github.com:$me/$test_pkg.jl.git" @test LibGit2.url(remote) == "git@github.com:$me/$test_pkg.jl.git"
rm(Pkg.dir(test_pkg); recursive=true) rm(pkg_dir; recursive=true)
# Check that the remote is set correctly for non-default hosts.
t = Template(; user=me, host="gitlab.com", gitconfig=gitconfig) t = Template(; user=me, host="gitlab.com", gitconfig=gitconfig)
generate(test_pkg, t) generate(test_pkg, t)
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) repo = LibGit2.GitRepo(pkg_dir)
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "https://gitlab.com/$me/$test_pkg.jl" @test LibGit2.url(remote) == "https://gitlab.com/$me/$test_pkg.jl"
rm(Pkg.dir(test_pkg); recursive=true) rm(pkg_dir; recursive=true)
# Check that the package ends up in the right directory.
temp_dir = mktempdir() temp_dir = mktempdir()
t = Template(; user=me, dir=temp_dir, gitconfig=gitconfig) t = Template(; user=me, dir=temp_dir, gitconfig=gitconfig)
generate(test_pkg, t) generate(test_pkg, t)
@test isdir(joinpath(temp_dir, test_pkg)) @test isdir(joinpath(temp_dir, test_pkg))
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
# Check that all the plugin files are generated.
t = Template(; t = Template(;
user=me, user=me,
license="", license="",
@ -324,45 +361,49 @@ end
plugins=[AppVeyor(), GitHubPages(), Coveralls(), CodeCov(), TravisCI()], plugins=[AppVeyor(), GitHubPages(), Coveralls(), CodeCov(), TravisCI()],
) )
generate(test_pkg, t) generate(test_pkg, t)
@test isdir(joinpath(Pkg.dir(), test_pkg)) @test isdir(pkg_dir)
@test !isfile(Pkg.dir(test_pkg, "LICENSE")) @test !isfile(joinpath(pkg_dir, "LICENSE"))
@test isfile(Pkg.dir(test_pkg, ".travis.yml")) @test isfile(joinpath(pkg_dir, ".travis.yml"))
@test isfile(Pkg.dir(test_pkg, ".appveyor.yml")) @test isfile(joinpath(pkg_dir, ".appveyor.yml"))
@test isdir(Pkg.dir(test_pkg, "docs")) @test isdir(joinpath(pkg_dir, "docs"))
@test isfile(Pkg.dir(test_pkg, "docs", "make.jl")) @test isfile(joinpath(pkg_dir, "docs", "make.jl"))
@test isdir(Pkg.dir(test_pkg, "docs", "src")) @test isdir(joinpath(pkg_dir, "docs", "src"))
@test isfile(Pkg.dir(test_pkg, "docs", "src", "index.md")) @test isfile(joinpath(pkg_dir, "docs", "src", "index.md"))
repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) # Test that the gh-pages exists for GitHubPages.
repo = LibGit2.GitRepo(pkg_dir)
@test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"] @test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"]
branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo)) branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo))
@test in("gh-pages", branches) @test in("gh-pages", branches)
@test !LibGit2.isdirty(repo) @test !LibGit2.isdirty(repo)
rm(Pkg.dir(test_pkg); recursive=true) rm(pkg_dir; recursive=true)
mkdir(Pkg.dir(test_pkg)) # Check that an existing directory is removed when force is set.
mkdir(pkg_dir)
@test_throws ArgumentError generate(test_pkg, t) @test_throws ArgumentError generate(test_pkg, t)
generate(test_pkg, t; force=true) generate(test_pkg, t; force=true)
@test isfile(Pkg.dir(test_pkg, "README.md")) @test isfile(joinpath(pkg_dir, "README.md"))
rm(Pkg.dir(test_pkg); recursive=true) rm(pkg_dir; recursive=true)
temp_file, fd = mktemp() # Check that the backup directory mechanism works.
close(fd) temp_file, io = mktemp()
close(io)
temp_dir = mktempdir() temp_dir = mktempdir()
t = Template(; user=me, dir=temp_file, gitconfig=gitconfig) t = Template(; user=me, dir=temp_file)
@test_warn r".+" generate(test_pkg, t; backup_dir=temp_dir) @test_logs (:warn, r".+") match_mode=:any generate(test_pkg, t; backup_dir=temp_dir)
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
temp_dir = mktempdir() temp_dir = mktempdir()
t = Template(; user=me, dir=joinpath(temp_file, "file"), gitconfig=gitconfig) t = Template(; user=me, dir=joinpath(temp_file, "dir"))
@test_warn r".+" generate(test_pkg, t; backup_dir=temp_dir) @test_logs (:warn, r".+") match_mode=:any generate(test_pkg, t; backup_dir=temp_dir)
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
rm(temp_file) rm(temp_file)
# Check that the generated docs root is just the copied README.
t = Template(; user=me, gitconfig=gitconfig, plugins=[GitHubPages()]) t = Template(; user=me, gitconfig=gitconfig, plugins=[GitHubPages()])
generate(test_pkg, t) generate(test_pkg, t)
readme = readstring(Pkg.dir(test_pkg, "README.md")) readme = read(joinpath(pkg_dir, "README.md"), String)
index = readstring(Pkg.dir(test_pkg, "docs", "src", "index.md")) index = read(joinpath(pkg_dir, "docs", "src", "index.md"), String)
@test readme == index @test readme == index
rm(Pkg.dir(test_pkg); recursive=true) rm(pkg_dir; recursive=true)
end end
@testset "Version floor" begin @testset "Version floor" begin
@ -375,72 +416,72 @@ end
@testset "Mustache substitution" begin @testset "Mustache substitution" begin
view = Dict{String, Any}() view = Dict{String, Any}()
text = substitute(template_text, view) text = substitute(template_text, view)
@test !contains(text, "PKGNAME: $test_pkg") @test !occursin("PKGNAME: $test_pkg", text)
@test !contains(text, "Documenter") @test !occursin("Documenter", text)
@test !contains(text, "CodeCov") @test !occursin("CodeCov", text)
@test !contains(text, "Coveralls") @test !occursin("Coveralls", text)
@test !contains(text, "After") @test !occursin("After", text)
@test !contains(text, "Other") @test !occursin("Other", text)
view["PKGNAME"] = test_pkg view["PKGNAME"] = test_pkg
view["OTHER"] = true view["OTHER"] = true
text = substitute(template_text, view) text = substitute(template_text, view)
@test contains(text, "PKGNAME: $test_pkg") @test occursin("PKGNAME: $test_pkg", text)
@test contains(text, "Other") @test occursin("Other", text)
t = Template(; user=me) t = Template(; user=me)
view["OTHER"] = false view["OTHER"] = false
text = substitute(template_text, t; view=view) text = substitute(template_text, t; view=view)
@test contains(text, "PKGNAME: $test_pkg") @test occursin("PKGNAME: $test_pkg", text)
@test contains(text, "VERSION: $(t.julia_version.major).$(t.julia_version.minor)") @test occursin("VERSION: $(t.julia_version.major).$(t.julia_version.minor)", text)
@test !contains(text, "Documenter") @test !occursin("Documenter", text)
@test !contains(text, "After") @test !occursin("After", text)
@test !contains(text, "Other") @test !occursin("Other", text)
t.plugins[GitHubPages] = GitHubPages() t.plugins[GitHubPages] = GitHubPages()
text = substitute(template_text, t; view=view) text = substitute(template_text, t; view=view)
@test contains(text, "Documenter") @test occursin("Documenter", text)
@test contains(text, "After") @test occursin("After", text)
empty!(t.plugins) empty!(t.plugins)
t.plugins[CodeCov] = CodeCov() t.plugins[CodeCov] = CodeCov()
text = substitute(template_text, t; view=view) text = substitute(template_text, t; view=view)
@test contains(text, "CodeCov") @test occursin("CodeCov", text)
@test contains(text, "After") @test occursin("After", text)
empty!(t.plugins) empty!(t.plugins)
t.plugins[Coveralls] = Coveralls() t.plugins[Coveralls] = Coveralls()
text = substitute(template_text, t; view=view) text = substitute(template_text, t; view=view)
@test contains(text, "Coveralls") @test occursin("Coveralls", text)
@test contains(text, "After") @test occursin("After", text)
empty!(t.plugins) empty!(t.plugins)
view["OTHER"] = true view["OTHER"] = true
text = substitute(template_text, t; view=view) text = substitute(template_text, t; view=view)
@test contains(text, "Other") @test occursin("Other", text)
end end
@testset "License display" begin @testset "License display" begin
old_stdout = STDOUT io = IOBuffer()
out_read, out_write = redirect_stdout() available_licenses(io)
available_licenses() licenses = String(take!(io))
licenses = String(readavailable(out_read)) show_license(io, "MIT")
show_license("MIT") mit = String(take!(io))
mit = String(readavailable(out_read))
close(out_write)
close(out_read)
redirect_stdout(old_stdout)
# Check that all licenses are included in the display.
for (short, long) in LICENSES for (short, long) in LICENSES
@test contains(licenses, "$short: $long") @test occursin("$short: $long", licenses)
end end
@test strip(mit) == strip(read_license("MIT")) @test strip(mit) == strip(read_license("MIT"))
@test strip(read_license("MIT")) == strip(readstring(joinpath(LICENSE_DIR, "MIT"))) @test strip(read_license("MIT")) == strip(read(joinpath(LICENSE_DIR, "MIT"), String))
@test_throws ArgumentError read_license(fake_path) @test_throws ArgumentError read_license(fake_path)
# Check that all licenses included with the package are displayed.
for license in readdir(LICENSE_DIR) for license in readdir(LICENSE_DIR)
@test haskey(LICENSES, license) @test haskey(LICENSES, license)
end end
# Check that all licenses displayed are included with the package.
@test length(readdir(LICENSE_DIR)) == length(LICENSES)
end end
@testset "Plugins" begin @testset "Plugins" begin
@ -449,6 +490,7 @@ end
temp_dir = mktempdir() temp_dir = mktempdir()
pkg_dir = joinpath(temp_dir, test_pkg) pkg_dir = joinpath(temp_dir, test_pkg)
# Check badge constructor and formatting.
badge = Badge("A", "B", "C") badge = Badge("A", "B", "C")
@test badge.hover == "A" @test badge.hover == "A"
@test badge.image == "B" @test badge.image == "B"