diff --git a/.appveyor.yml b/.appveyor.yml index 3b37ad4..5abf512 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,38 +1,30 @@ environment: matrix: - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" - - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" - - + - julia_version: 0.7 + - julia_version: 1.0 + - julia_version: nightly +platform: + - x86 + - x64 matrix: allow_failures: - - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" - + - julia_version: nightly notifications: - provider: Email on_build_success: false on_build_failure: false on_build_status_changed: false - install: - - ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12" - # 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 - + - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) build_script: - # Need to convert from shallow to complete for Pkg.clone to work - - IF EXIST .git\shallow (git fetch --unshallow) - - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"PkgTemplates\")" - + - echo "%JL_BUILD_SCRIPT%" + - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" test_script: - - C:\projects\julia\bin\julia -e "Pkg.test(\"PkgTemplates\"; coverage=true)" - -after_test: - - 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())" + # Git configuration is required to make commits in generated packages. + - git config --global user.name "AppVeyor" + - git config --global user.email "appveyor@example.com" + - 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%" diff --git a/.travis.yml b/.travis.yml index ee27e97..89a1971 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ os: - linux - osx julia: - - 0.6 + - 0.7 + - 1.0 - nightly matrix: allow_failures: @@ -11,9 +12,11 @@ matrix: fast_finish: true notifications: email: false -script: - - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - - julia -e 'Pkg.clone(pwd()); Pkg.test("PkgTemplates"; coverage=true)' +before_script: + # Git configuration is required to make commits in generated packages. + - git config --global user.name "Travis" + - git config --global user.email "travis@example.com" 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 'Pkg.add("Documenter"); cd(Pkg.dir("PkgTemplates")); include(joinpath("docs", "make.jl"))' + - julia -e 'using Pkg; Pkg.add("Coverage")' + - julia -e 'using Coverage; CodeCov.submit(process_folder())' + - julia -e 'using Pkg; Pkg.add("Documenter"); include(joinpath("docs", "make.jl"))' diff --git a/LICENSE b/LICENSE index 390b2cd..694d072 100644 --- a/LICENSE +++ b/LICENSE @@ -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 of this software and associated documentation files (the "Software"), to deal diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..c51e0e9 --- /dev/null +++ b/Manifest.toml @@ -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" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..a238339 --- /dev/null +++ b/Project.toml @@ -0,0 +1,15 @@ +name = "PkgTemplates" +uuid = "19f0ff7e-bab4-11e8-074b-97459630f98a" +authors = ["Chris de Graaf "] +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" diff --git a/REQUIRE b/REQUIRE index a652844..e172632 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,5 +1,4 @@ -julia 0.6 +julia 0.7 AutoHashEquals Mustache -TerminalMenus URIParser diff --git a/defaults/appveyor.yml b/defaults/appveyor.yml index c3c13e2..6ae2557 100644 --- a/defaults/appveyor.yml +++ b/defaults/appveyor.yml @@ -36,8 +36,14 @@ build_script: - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"{{PKGNAME}}\"); Pkg.build(\"{{PKGNAME}}\")" 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}} - - 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}} +after_test: +{{#CODECOV}} + - 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}} diff --git a/defaults/gitlab-ci.yml b/defaults/gitlab-ci.yml index 4120002..49f1693 100644 --- a/defaults/gitlab-ci.yml +++ b/defaults/gitlab-ci.yml @@ -1,19 +1,25 @@ -{{#GITLABCOVERAGE}}stages: +{{#GITLABCOVERAGE}} +stages: - test - coverage -{{/GITLABCOVERAGE}}.test_template: &test_template - stage: test{{#GITLABCOVERAGE}} +{{/GITLABCOVERAGE}} +.test_template: &test_template + stage: test +{{#GITLABCOVERAGE}} artifacts: name: coverage expire_in: 2 hours paths: - - coverage/{{/GITLABCOVERAGE}} + - coverage/ +{{/GITLABCOVERAGE}} tags: - docker script: - - julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#GITLABCOVERAGE}}; coverage=true{{/GITLABCOVERAGE}})'{{#GITLABCOVERAGE}} - - cp -r $(julia -e 'print(Pkg.dir("{{PKGNAME}}", "src"))') coverage{{/GITLABCOVERAGE}} + - julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#GITLABCOVERAGE}}; coverage=true{{/GITLABCOVERAGE}})' +{{#GITLABCOVERAGE}} + - cp -r $(julia -e 'print(Pkg.dir("{{PKGNAME}}", "src"))') coverage +{{/GITLABCOVERAGE}} Julia {{VERSION}}: image: julia:{{VERSION}} @@ -22,7 +28,8 @@ Julia {{VERSION}}: Julia nightly: image: staticfloat/julia:nightly-x64 allow_failure: true - <<: *test_template{{#GITLABCOVERAGE}} + <<: *test_template +{{#GITLABCOVERAGE}} "Coverage": stage: coverage @@ -34,4 +41,5 @@ Julia nightly: - apt-get update && apt-get -y install git make unzip gcc bzip2 script: - 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}} diff --git a/defaults/travis.yml b/defaults/travis.yml index cf1020a..7c4b7eb 100644 --- a/defaults/travis.yml +++ b/defaults/travis.yml @@ -14,8 +14,16 @@ notifications: email: false script: - 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}} -after_success:{{#CODECOV}} - - 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}} + - julia -e 'Pkg.clone(pwd()); Pkg.build("{{PKGNAME}}"); Pkg.test("{{PKGNAME}}"{{#AFTER}}; coverage=true{{/AFTER}})' +{{#AFTER}} +after_success: +{{#CODECOV}} + - 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}} diff --git a/docs/src/pages/plugins.md b/docs/src/pages/plugins.md index 57d1ab9..57bab20 100644 --- a/docs/src/pages/plugins.md +++ b/docs/src/pages/plugins.md @@ -4,7 +4,7 @@ CurrentModule = PkgTemplates # 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 [Plugin Development](@ref). diff --git a/src/PkgTemplates.jl b/src/PkgTemplates.jl index b7bfd96..407d0f6 100644 --- a/src/PkgTemplates.jl +++ b/src/PkgTemplates.jl @@ -2,8 +2,12 @@ __precompile__() module PkgTemplates using AutoHashEquals +using Dates +using Distributed +using InteractiveUtils +using LibGit2 using Mustache -using TerminalMenus +using REPL.TerminalMenus using URIParser export diff --git a/src/generate.jl b/src/generate.jl index 9f18483..a5c31b3 100644 --- a/src/generate.jl +++ b/src/generate.jl @@ -5,7 +5,7 @@ force::Bool=false, ssh::Bool=false, backup_dir::AbstractString="", - ) -> Void + ) -> Nothing Generate a package named `pkg_name` from `template`. @@ -42,7 +42,7 @@ function generate( ssh::Bool=false, backup_dir::AbstractString="", ) - pkg_name = Pkg.splitjl(pkg_name) + pkg_name = splitjl(pkg_name) pkg_dir = joinpath(t.dir, pkg_name) temp_pkg_dir = joinpath(dir, pkg_name) @@ -54,15 +54,15 @@ function generate( # Initialize the repo and configure it. 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 for (key, val) in t.gitconfig LibGit2.set!(cfg, key, val) end end - !isempty(t.gitconfig) && info("Applied git configuration") + !isempty(t.gitconfig) && @info "Applied git configuration" LibGit2.commit(repo, "Initial commit") - info("Made empty initial commit") + @info "Made empty initial commit" rmt = if ssh "git@$(t.host):$(t.user)/$pkg_name.jl.git" else @@ -70,13 +70,13 @@ function generate( end # We need to set the remote in a strange way, see #8. 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. if haskey(t.plugins, GitHubPages) LibGit2.branch!(repo, "gh-pages") LibGit2.commit(repo, "Empty initial commit") - info("Created empty gh-pages branch") + @info "Created empty gh-pages branch" LibGit2.branch!(repo, "master") end @@ -92,14 +92,14 @@ function generate( ) 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") - info("Committed files generated by PkgTemplates") + @info "Committed files generated by PkgTemplates" multiple_branches = length(collect(LibGit2.GitBranchIter(repo))) > 1 try mkpath(dirname(pkg_dir)) - mv(temp_pkg_dir, pkg_dir; remove_destination=force) - info("Moved temporary package directory into $(t.dir)/") + mv(temp_pkg_dir, pkg_dir; force=force) + @info "Moved temporary package directory into $(t.dir)/" 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. backup_dir = if isempty(backup_dir) @@ -109,12 +109,12 @@ function generate( end mkpath(backup_dir) 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 - info("Finished") + @info "Finished" 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 @@ -135,7 +135,7 @@ end ssh::Bool=false, backup_dir::AbstractString="", fast::Bool=false, - ) -> Void + ) -> Nothing 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 @@ -426,3 +426,10 @@ function substitute( d["AFTER"] = d["DOCUMENTER"] || d["CODECOV"] || d["COVERALLS"] return substitute(template, merge(d, view)) 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 diff --git a/src/licenses.jl b/src/licenses.jl index 3e26478..a0d1787 100644 --- a/src/licenses.jl +++ b/src/licenses.jl @@ -8,24 +8,24 @@ const LICENSES = Dict( "GPL-2.0+" => "GNU Public License, Version 2.0+", "GPL-3.0+" => "GNU Public License, Version 3.0+", "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. """ -available_licenses(io::IO) = println(io, join(("$k: $v" for (k, v) in LICENSES), "\n")) -available_licenses() = available_licenses(STDOUT) +available_licenses(io::IO) = print(io, join(("$k: $v" for (k, v) in LICENSES), "\n")) +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. """ -show_license(io::IO, license::AbstractString) = println(io, read_license(license)) -show_license(license::AbstractString) = show_license(STDOUT, license) +show_license(io::IO, license::AbstractString) = print(io, read_license(license)) +show_license(license::AbstractString) = show_license(stdout, license) """ read_license(license::AbstractString) -> String diff --git a/src/plugin.jl b/src/plugin.jl index 87a74f3..6f73ec6 100644 --- a/src/plugin.jl +++ b/src/plugin.jl @@ -1,5 +1,3 @@ -import Base.show - """ 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. @@ -7,7 +5,7 @@ Generic plugins are plugins that add any number of patterns to the generated pac # Attributes * `gitignore::Vector{AbstractString}`: Array of patterns to be added to the `.gitignore` of 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 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 @@ -25,12 +23,12 @@ Generic plugins are plugins that add any number of patterns to the generated pac ```julia @auto_hash_equals struct MyPlugin <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} view::Dict{String, Any} - function MyPlugin(; config_file::Union{AbstractString, Void}="") + function MyPlugin(; config_file::Union{AbstractString, Nothing}="") if config_file != nothing config_file = if isempty(config_file) 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 -function show(io::IO, p::GenericPlugin) +function Base.show(io::IO, p::GenericPlugin) spc = " " - println(io, "$(Base.datatype_name(typeof(p))):") + println(io, "$(nameof(typeof(p))):") - cfg = if isnull(p.src) + cfg = if p.src === nothing "None" else - dirname(get(p.src)) == DEFAULTS_DIR ? "Default" : get(p.src) + dirname(p.src) == DEFAULTS_DIR ? "Default" : p.src end println(io, "$spc→ Config file: $cfg") @@ -213,13 +211,11 @@ function gen_plugin( dir::AbstractString, pkg_name::AbstractString, ) - src = try - get(plugin.src) - catch + if plugin.src === nothing return String[] end text = substitute( - readstring(src), + read(plugin.src, String), template; view=merge(Dict("PKGNAME" => pkg_name), plugin.view), ) @@ -250,7 +246,7 @@ end """ interactive( plugin_type::Type{<:Plugin}; - file::Union{AbstractString, Void}="", + file::Union{AbstractString, Nothing}="", ) -> Plugin 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( plugin_type::Type{<:GenericPlugin}; - file::Union{AbstractString, Void}="", + file::Union{AbstractString, Nothing}="", ) plugin_name = String(split(string(plugin_type), ".")[end]) # By default, we expect the default plugin file template for a plugin called @@ -270,7 +266,7 @@ function interactive( if default_config_file == nothing print("[None]: ") else - print("[$(replace(default_config_file, homedir(), "~"))]: ") + print("[$(replace(default_config_file, homedir() => "~"))]: ") end config_file = readline() config_file = if uppercase(config_file) == "NONE" diff --git a/src/plugins/appveyor.jl b/src/plugins/appveyor.jl index 8b0e65c..857d188 100644 --- a/src/plugins/appveyor.jl +++ b/src/plugins/appveyor.jl @@ -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 generated repositories, and an appropriate badge to the README. # 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. """ @auto_hash_equals struct AppVeyor <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} view::Dict{String, Any} - function AppVeyor(; config_file::Union{AbstractString, Void}="") + function AppVeyor(; config_file::Union{AbstractString, Nothing}="") if config_file != nothing config_file = if isempty(config_file) config_file = joinpath(DEFAULTS_DIR, "appveyor.yml") diff --git a/src/plugins/codecov.jl b/src/plugins/codecov.jl index ae54f52..c605d0d 100644 --- a/src/plugins/codecov.jl +++ b/src/plugins/codecov.jl @@ -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 to generated repositories, and an appropriate badge to the README. Also updates the `.gitignore` accordingly. # 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. """ @auto_hash_equals struct CodeCov <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} view::Dict{String, Any} - function CodeCov(; config_file::Union{AbstractString, Void}=nothing) + function CodeCov(; config_file::Union{AbstractString, Nothing}=nothing) if config_file != nothing config_file = if isfile(config_file) abspath(config_file) diff --git a/src/plugins/coveralls.jl b/src/plugins/coveralls.jl index 0ebb087..1406db7 100644 --- a/src/plugins/coveralls.jl +++ b/src/plugins/coveralls.jl @@ -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 file to generated repositories, and an appropriate badge to the README. Also updates the `.gitignore` accordingly. # 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. """ @auto_hash_equals struct Coveralls <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} view::Dict{String, Any} - function Coveralls(; config_file::Union{AbstractString, Void}=nothing) + function Coveralls(; config_file::Union{AbstractString, Nothing}=nothing) if config_file != nothing config_file = if isfile(config_file) abspath(config_file) diff --git a/src/plugins/documenter.jl b/src/plugins/documenter.jl index 76560ce..51b4787 100644 --- a/src/plugins/documenter.jl +++ b/src/plugins/documenter.jl @@ -1,5 +1,3 @@ -import Base.show - """ Add a `Documenter` subtype to a template's plugins to add support for documentation generation via [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl). @@ -25,13 +23,12 @@ function gen_plugin( # assets/file1, # assets/file2, # ] - const TAB = repeat(" ", 4) + tab = repeat(" ", 4) assets_string = "[\n" for asset in plugin.assets - assets_string *= """$(TAB^2)"assets/$(basename(asset))",\n""" + assets_string *= """$(tab^2)"assets/$(basename(asset))",\n""" end - assets_string *= "$TAB]" - + assets_string *= "$tab]" else assets_string = "[]" end @@ -57,13 +54,13 @@ function gen_plugin( end readme_path = joinpath(dir, pkg_name, "README.md") 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 -function show(io::IO, p::Documenter) +function Base.show(io::IO, p::Documenter) spc = " " - println(io, "$(Base.datatype_name(typeof(p))):") + println(io, "$(nameof(typeof(p))):") n = length(p.assets) s = n == 1 ? "" : "s" @@ -71,7 +68,7 @@ function show(io::IO, p::Documenter) if n == 0 println(io) else - println(io, ": $(join(map(a -> replace(a, homedir(), "~"), p.assets), ", "))") + println(io, ": $(join(map(a -> replace(a, homedir() => "~"), p.assets), ", "))") end n = length(p.gitignore) @@ -81,7 +78,7 @@ function show(io::IO, p::Documenter) end 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) []: ") return plugin_type(; assets=String.(split(readline()))) end diff --git a/src/plugins/gitlabci.jl b/src/plugins/gitlabci.jl index 1b63204..c91f4f2 100644 --- a/src/plugins/gitlabci.jl +++ b/src/plugins/gitlabci.jl @@ -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 generated repositories, and appropriate badge(s) to the README. # 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. * `coverage::Bool=true`: Whether or not GitLab CI's built-in code coverage analysis should be enabled. """ @auto_hash_equals struct GitLabCI <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} 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 config_file = if isempty(config_file) config_file = joinpath(DEFAULTS_DIR, "gitlab-ci.yml") diff --git a/src/plugins/travisci.jl b/src/plugins/travisci.jl index 12401ee..1f1c46e 100644 --- a/src/plugins/travisci.jl +++ b/src/plugins/travisci.jl @@ -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 generated repositories, and an appropriate badge to the README. # 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. """ @auto_hash_equals struct TravisCI <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} view::Dict{String, Any} - function TravisCI(; config_file::Union{AbstractString, Void}="") + function TravisCI(; config_file::Union{AbstractString, Nothing}="") if config_file != nothing config_file = if isempty(config_file) config_file = joinpath(DEFAULTS_DIR, "travis.yml") @@ -32,8 +32,8 @@ generated repositories, and an appropriate badge to the README. [ Badge( "Build Status", - "https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl.svg?branch=master", - "https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl", + "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl.svg?branch=master", + "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl", ), ], Dict{String, Any}(), diff --git a/src/template.jl b/src/template.jl index 7695061..90fed90 100644 --- a/src/template.jl +++ b/src/template.jl @@ -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 @@ -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`, 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. -* `years::Union{Integer, AbstractString}=Dates.year(Dates.today())`: Copyright years on 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 - are converted to absolute ones at template creation time. +* `years::Union{Integer, AbstractString}=$(Dates.year(Dates.today()))`: Copyright years on + the license. Can be supplied by a number, or a string such as "2016 - 2017". +* `dir::AbstractString=$(dev_dir())`: Directory in which the package will go. Relative + paths are converted to absolute ones at template creation time. * `precompile::Bool=true`: Whether or not to enable precompilation in generated packages. * `julia_version::VersionNumber=VERSION`: Minimum allowed Julia version. * `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(; user::AbstractString="", host::AbstractString="https://github.com", - license::Union{AbstractString, Void}="MIT", + license::AbstractString="MIT", authors::Union{AbstractString, Vector{<:AbstractString}}="", years::Union{Integer, AbstractString}=Dates.year(Dates.today()), - dir::AbstractString=Pkg.dir(), + dir::AbstractString=dev_dir(), precompile::Bool=true, julia_version::VersionNumber=VERSION, 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" )) elseif diff > 0 - warn("Removed $(diff) duplicate$(diff == 1 ? "" : "s") from requirements") + @warn "Removed $(diff) duplicate$(diff == 1 ? "" : "s") from requirements" end plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins) 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 new( @@ -113,7 +118,7 @@ create a template, you can use [`interactive_template`](@ref) instead. 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) spc = " " @@ -128,7 +133,7 @@ function show(io::IO, t::Template) println(io, "$(t.license) ($(t.authors) $(t.years))") 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→ 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. """ 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 # "Select plugins" is printed. plugin_types = @spawn leaves(Plugin) @@ -206,7 +211,7 @@ function interactive_template(; fast::Bool=false) io = IOBuffer() available_licenses(io) 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 # value of which correponds to no license. licenses[abs(request(menu))].first @@ -235,9 +240,9 @@ function interactive_template(; fast::Bool=false) end kwargs[:dir] = if fast - Pkg.dir() + dev_dir() else - default_dir = Pkg.dir() + default_dir = dev_dir() print("Enter the path to the package directory [$default_dir]: ") dir = readline() isempty(dir) ? default_dir : dir @@ -276,7 +281,7 @@ function interactive_template(; fast::Bool=false) isempty(line) && break tokens = split(line, " ", limit=2) 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 gitconfig[tokens[1]] = tokens[2] end @@ -285,7 +290,7 @@ function interactive_template(; fast::Bool=false) println("Select plugins:") # 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) menu = MultiSelectMenu(String.(type_names); pagesize=length(type_names)) selected = collect(request(menu)) @@ -301,4 +306,4 @@ end 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))...) diff --git a/test/interactive/interactive.jl b/test/interactive/interactive.jl index 51ec178..df4743b 100644 --- a/test/interactive/interactive.jl +++ b/test/interactive/interactive.jl @@ -2,30 +2,30 @@ # which seems to be the case in Travis CI OSX builds. # https://travis-ci.org/invenia/PkgTemplates.jl/jobs/267682403#L115 # 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. # Therefore, we skip any interactive tests on OSX builds. @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() @test t.user == me @test t.host == "github.com" @test isempty(t.license) @test t.authors == LibGit2.getconfig("user.name", "") @test t.years == string(Dates.year(Dates.today())) - @test t.dir == Pkg.dir() + @test t.dir == default_dir @test t.julia_version == VERSION @test isempty(t.requirements) @test isempty(t.gitconfig) @test isempty(t.plugins) if isempty(LibGit2.getconfig("github.user", "")) - write(STDIN.buffer, "\n") + write(stdin.buffer, "\n") @test_throws ArgumentError t = interactive_template() 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() @test t.user == me @test t.host == "gitlab.com" @@ -41,10 +41,10 @@ # Like above, not sure which plugins this will generate. @test length(t.plugins) == 2 - write(STDIN.buffer, "$me\n\n\r\n\n\n\nA B\n A B\n\nd") - @test_warn r".+" interactive_template() + write(stdin.buffer, "$me\n\n\r\n\n\n\nA B\nA B\n\nd") + @test_logs (:warn, r".+") match_mode=:any interactive_template() - write(STDIN.buffer, "$me\nd") + write(stdin.buffer, "$me\nd") t = interactive_template(; fast=true) @test t.user == me @test t.host == "github.com" @@ -52,7 +52,7 @@ @test t.authors == LibGit2.getconfig("user.name", "") # I guess this could technically break if it runs on New Year's Eve... @test t.years == string(Dates.year(Dates.today())) - @test t.dir == Pkg.dir() + @test t.dir == default_dir @test t.julia_version == VERSION @test isempty(t.requirements) @test isempty(t.gitconfig) @@ -62,8 +62,8 @@ end @testset "Interactive package generation" begin 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) - @test isdir(Pkg.dir(test_pkg)) - rm(Pkg.dir(test_pkg); force=true, recursive=true) + @test isdir(joinpath(default_dir, test_pkg)) + rm(joinpath(default_dir, test_pkg); force=true, recursive=true) end diff --git a/test/interactive/plugins.jl b/test/interactive/plugins.jl index ddf3efa..36cf86c 100644 --- a/test/interactive/plugins.jl +++ b/test/interactive/plugins.jl @@ -1,90 +1,90 @@ # These tests are to be skipped in OSX builds, see ./interactive.jl for more info. @testset "TravisCI" begin - write(STDIN.buffer, "\n") + write(stdin.buffer, "\n") p = interactive(TravisCI) - @test get(p.src, "") == joinpath(DEFAULTS_DIR, "travis.yml") - write(STDIN.buffer, "$test_file\n") + @test p.src == joinpath(DEFAULTS_DIR, "travis.yml") + write(stdin.buffer, "$test_file\n") p = interactive(TravisCI) - @test get(p.src, "") == test_file - write(STDIN.buffer, "none\n") + @test p.src == test_file + write(stdin.buffer, "none\n") p = interactive(TravisCI) - @test isnull(p.src) - write(STDIN.buffer, "$fake_path\n") + @test p.src === nothing + write(stdin.buffer, "$fake_path\n") @test_throws ArgumentError interactive(TravisCI) println() end @testset "AppVeyor" begin - write(STDIN.buffer, "\n") + write(stdin.buffer, "\n") p = interactive(AppVeyor) - @test get(p.src, "") == joinpath(DEFAULTS_DIR, "appveyor.yml") - write(STDIN.buffer, "$test_file\n") + @test p.src == joinpath(DEFAULTS_DIR, "appveyor.yml") + write(stdin.buffer, "$test_file\n") p = interactive(AppVeyor) - @test get(p.src, "") == test_file - write(STDIN.buffer, "none\n") + @test p.src == test_file + write(stdin.buffer, "none\n") p = interactive(AppVeyor) - @test isnull(p.src) - write(STDIN.buffer, "$fake_path\n") + @test p.src === nothing + write(stdin.buffer, "$fake_path\n") @test_throws ArgumentError interactive(AppVeyor) println() end @testset "GitLabCI" begin - write(STDIN.buffer, "\n\n") + write(stdin.buffer, "\n\n") 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) - write(STDIN.buffer, "$test_file\nno\n") + write(stdin.buffer, "$test_file\nno\n") p = interactive(GitLabCI) - @test get(p.src, "") == test_file + @test p.src == test_file @test p.view == Dict("GITLABCOVERAGE" => false) - write(STDIN.buffer, "none\n\n") + write(stdin.buffer, "none\n\n") p = interactive(GitLabCI) - @test isnull(p.src) - write(STDIN.buffer, "$fake_path\n\n") + @test p.src === nothing + write(stdin.buffer, "$fake_path\n\n") @test_throws ArgumentError interactive(GitLabCI) println() end @testset "CodeCov" begin - write(STDIN.buffer, "\n") + write(stdin.buffer, "\n") p = interactive(CodeCov) - @test isnull(p.src) - write(STDIN.buffer, "$test_file\n") + @test p.src === nothing + write(stdin.buffer, "$test_file\n") p = interactive(CodeCov) - @test get(p.src, "") == test_file - write(STDIN.buffer, "none\n") + @test p.src == test_file + write(stdin.buffer, "none\n") p = interactive(CodeCov) - @test isnull(p.src) - write(STDIN.buffer, "$fake_path\n") + @test p.src === nothing + write(stdin.buffer, "$fake_path\n") @test_throws ArgumentError interactive(CodeCov) println() end @testset "Coveralls" begin - write(STDIN.buffer, "\n") + write(stdin.buffer, "\n") p = interactive(Coveralls) - @test isnull(p.src) - write(STDIN.buffer, "$test_file\n") + @test p.src === nothing + write(stdin.buffer, "$test_file\n") p = interactive(Coveralls) - @test get(p.src, "") == test_file - write(STDIN.buffer, "none\n") + @test p.src == test_file + write(stdin.buffer, "none\n") p = interactive(Coveralls) - @test isnull(p.src) - write(STDIN.buffer, "$fake_path\n") + @test p.src === nothing + write(stdin.buffer, "$fake_path\n") @test_throws ArgumentError interactive(Coveralls) println() end @testset "GitHubPages" begin - write(STDIN.buffer, "\n") + write(stdin.buffer, "\n") p = interactive(GitHubPages) @test isempty(p.assets) - write(STDIN.buffer, "$test_file\n") + write(stdin.buffer, "$test_file\n") p = interactive(GitHubPages) @test p.assets == [test_file] - write(STDIN.buffer, "$fake_path\n") + write(stdin.buffer, "$fake_path\n") @test_throws ArgumentError interactive(GitHubPages) println() end diff --git a/test/plugins/appveyor.jl b/test/plugins/appveyor.jl index ef0a9e6..5aa304b 100644 --- a/test/plugins/appveyor.jl +++ b/test/plugins/appveyor.jl @@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg) @testset "Plugin creation" begin p = AppVeyor() @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.badges == [ Badge( @@ -18,9 +18,9 @@ pkg_dir = joinpath(temp_dir, test_pkg) ] @test isempty(p.view) p = AppVeyor(; config_file=nothing) - @test isnull(p.src) + @test p.src === nothing 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) end @@ -30,33 +30,39 @@ pkg_dir = joinpath(temp_dir, test_pkg) end @testset "File generation" begin + # Without a coverage plugin in the template, there should be no post-test step. p = AppVeyor() @test gen_plugin(p, t, temp_dir, test_pkg) == [".appveyor.yml"] @test isfile(joinpath(pkg_dir, ".appveyor.yml")) - appveyor = readstring(joinpath(pkg_dir, ".appveyor.yml")) - @test !contains(appveyor, "coverage=true") - @test !contains(appveyor, "after_test") - @test !contains(appveyor, "Codecov.submit") - @test !contains(appveyor, "Coveralls.submit") + appveyor = read(joinpath(pkg_dir, ".appveyor.yml"), String) + @test !occursin("coverage=true", appveyor) + @test !occursin("after_test", appveyor) + @test !occursin("Codecov.submit", appveyor) + @test !occursin("Coveralls.submit", appveyor) rm(joinpath(pkg_dir, ".appveyor.yml")) + + # Generating the plugin with CodeCov in the template should create a post-test step. t.plugins[CodeCov] = CodeCov() gen_plugin(p, t, temp_dir, test_pkg) delete!(t.plugins, CodeCov) - appveyor = readstring(joinpath(pkg_dir, ".appveyor.yml")) - @test contains(appveyor, "coverage=true") - @test contains(appveyor, "after_test") - @test contains(appveyor, "Codecov.submit") - @test !contains(appveyor, "Coveralls.submit") + appveyor = read(joinpath(pkg_dir, ".appveyor.yml"), String) + @test occursin("coverage=true", appveyor) + @test occursin("after_test", appveyor) + @test occursin("Codecov.submit", appveyor) + @test !occursin("Coveralls.submit", appveyor) rm(joinpath(pkg_dir, ".appveyor.yml")) + + # Coveralls should do the same. t.plugins[Coveralls] = Coveralls() gen_plugin(p, t, temp_dir, test_pkg) delete!(t.plugins, Coveralls) - appveyor = readstring(joinpath(pkg_dir, ".appveyor.yml")) - @test contains(appveyor, "coverage=true") - @test contains(appveyor, "after_test") - @test contains(appveyor, "Coveralls.submit") - @test !contains(appveyor, "Codecov.submit") + appveyor = read(joinpath(pkg_dir, ".appveyor.yml"), String) + @test occursin("coverage=true", appveyor) + @test occursin("after_test", appveyor) + @test occursin("Coveralls.submit", appveyor) + @test !occursin("Codecov.submit", appveyor) rm(joinpath(pkg_dir, ".appveyor.yml")) + p = AppVeyor(; config_file=nothing) @test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test !isfile(joinpath(pkg_dir, ".appveyor.yml")) diff --git a/test/plugins/codecov.jl b/test/plugins/codecov.jl index e4db4bf..e410363 100644 --- a/test/plugins/codecov.jl +++ b/test/plugins/codecov.jl @@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg) @testset "Plugin creation" begin p = CodeCov() @test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"] - @test isnull(p.src) + @test p.src === nothing @test p.dest == ".codecov.yml" @test p.badges == [ Badge( @@ -18,9 +18,9 @@ pkg_dir = joinpath(temp_dir, test_pkg) ] @test isempty(p.view) p = CodeCov(; config_file=nothing) - @test isnull(p.src) + @test p.src === nothing 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) end diff --git a/test/plugins/coveralls.jl b/test/plugins/coveralls.jl index fabce93..3b257c2 100644 --- a/test/plugins/coveralls.jl +++ b/test/plugins/coveralls.jl @@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg) @testset "Plugin creation" begin p = Coveralls() @test p.gitignore == ["*.jl.cov", "*.jl.*.cov", "*.jl.mem"] - @test isnull(p.src) + @test p.src === nothing @test p.dest == ".coveralls.yml" @test p.badges == [ Badge( @@ -18,9 +18,9 @@ pkg_dir = joinpath(temp_dir, test_pkg) ] @test isempty(p.view) p = Coveralls(; config_file=nothing) - @test isnull(p.src) + @test p.src === nothing 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) end diff --git a/test/plugins/githubpages.jl b/test/plugins/githubpages.jl index 226ca2d..7c45151 100644 --- a/test/plugins/githubpages.jl +++ b/test/plugins/githubpages.jl @@ -27,8 +27,8 @@ pkg_dir = joinpath(temp_dir, test_pkg) @test isdir(joinpath(pkg_dir, "docs")) @test isfile(joinpath(pkg_dir, "docs", "make.jl")) make = readchomp(joinpath(pkg_dir, "docs", "make.jl")) - @test contains(make, "assets=[]") - @test !contains(make, "deploydocs") + @test occursin("assets=[]", make) + @test !occursin("deploydocs", make) @test isdir(joinpath(pkg_dir, "docs", "src")) @test isfile(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]) @test gen_plugin(p, t, temp_dir, test_pkg) == ["docs/"] make = readchomp(joinpath(pkg_dir, "docs", "make.jl")) - @test contains( - make, + # Check the formatting of the assets list. + @test occursin( strip(""" assets=[ "assets/$(basename(test_file))", ] """), + make, ) @test isfile(joinpath(pkg_dir, "docs", "src", "assets", basename(test_file))) rm(joinpath(pkg_dir, "docs"); recursive=true) t.plugins[TravisCI] = TravisCI() @test gen_plugin(p, t, temp_dir, test_pkg) == ["docs/"] make = readchomp(joinpath(pkg_dir, "docs", "make.jl")) - @test contains(make, "deploydocs") + @test occursin("deploydocs", make) rm(joinpath(pkg_dir, "docs"); recursive=true) end end diff --git a/test/plugins/gitlabci.jl b/test/plugins/gitlabci.jl index 732ac62..c3523c2 100644 --- a/test/plugins/gitlabci.jl +++ b/test/plugins/gitlabci.jl @@ -7,7 +7,7 @@ pkg_dir = joinpath(temp_dir, test_pkg) @testset "Plugin creation" begin p = GitLabCI() @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.badges == [ Badge( @@ -23,9 +23,9 @@ pkg_dir = joinpath(temp_dir, test_pkg) ] @test p.view == Dict("GITLABCOVERAGE" => true) p = GitLabCI(; config_file=nothing) - @test isnull(p.src) + @test p.src === nothing 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) p = GitLabCI(; coverage=false) @test p.badges == [ @@ -50,16 +50,20 @@ pkg_dir = joinpath(temp_dir, test_pkg) p = GitLabCI() @test gen_plugin(p, t, temp_dir, test_pkg) == [".gitlab-ci.yml"] @test isfile(joinpath(pkg_dir, ".gitlab-ci.yml")) - gitlab = readstring(joinpath(pkg_dir, ".gitlab-ci.yml")) - @test contains(gitlab, "test_template") - @test contains(gitlab, "using Coverage") + gitlab = read(joinpath(pkg_dir, ".gitlab-ci.yml"), String) + @test occursin("test_template", gitlab) + # The default plugin should enable the coverage step. + @test occursin("using Coverage", gitlab) rm(joinpath(pkg_dir, ".gitlab-ci.yml")) + p = GitLabCI(; coverage=false) gen_plugin(p, t, temp_dir, test_pkg) - gitlab = readstring(joinpath(pkg_dir, ".gitlab-ci.yml")) - @test !contains(gitlab, "using Coverage") + gitlab = read(joinpath(pkg_dir, ".gitlab-ci.yml"), String) + # If coverage is false, there should be no coverage step. + @test !occursin("using Coverage", gitlab) rm(joinpath(pkg_dir, ".gitlab-ci.yml")) p = GitLabCI(; config_file=nothing) + @test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test !isfile(joinpath(pkg_dir, ".gitlab-ci.yml")) end diff --git a/test/plugins/travisci.jl b/test/plugins/travisci.jl index 4b2409e..db0056f 100644 --- a/test/plugins/travisci.jl +++ b/test/plugins/travisci.jl @@ -7,65 +7,74 @@ pkg_dir = joinpath(temp_dir, test_pkg) @testset "Plugin creation" begin p = TravisCI() @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.badges == [ Badge( "Build Status", - "https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl.svg?branch=master", - "https://travis-ci.org/{{USER}}/{{PKGNAME}}.jl", + "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl.svg?branch=master", + "https://travis-ci.com/{{USER}}/{{PKGNAME}}.jl", ), ] @test isempty(p.view) p = TravisCI(; config_file=nothing) - @test isnull(p.src) + @test p.src === nothing 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) end @testset "Badge generation" begin 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 @testset "File generation" begin + # Without a coverage plugin in the template, there should be no post-test step. p = TravisCI() @test gen_plugin(p, t, temp_dir, test_pkg) == [".travis.yml"] @test isfile(joinpath(pkg_dir, ".travis.yml")) - travis = readstring(joinpath(pkg_dir, ".travis.yml")) - @test !contains(travis, "after_success") - @test !contains(travis, "Codecov.submit") - @test !contains(travis, "Coveralls.submit") - @test !contains(travis, "Pkg.add(\"Documenter\")") + travis = read(joinpath(pkg_dir, ".travis.yml"), String) + + @test !occursin("after_success", travis) + @test !occursin("Codecov.submit", travis) + @test !occursin("Coveralls.submit", travis) + @test !occursin("Pkg.add(\"Documenter\")", travis) rm(joinpath(pkg_dir, ".travis.yml")) + + # Generating the plugin with CodeCov in the template should create a post-test step. t.plugins[CodeCov] = CodeCov() gen_plugin(p, t, temp_dir, test_pkg) delete!(t.plugins, CodeCov) - travis = readstring(joinpath(pkg_dir, ".travis.yml")) - @test contains(travis, "after_success") - @test contains(travis, "Codecov.submit") - @test !contains(travis, "Coveralls.submit") - @test !contains(travis, "Pkg.add(\"Documenter\")") + travis = read(joinpath(pkg_dir, ".travis.yml"), String) + @test occursin("after_success", travis) + @test occursin("Codecov.submit", travis) + @test !occursin("Coveralls.submit", travis) + @test !occursin("Pkg.add(\"Documenter\")", travis) rm(joinpath(pkg_dir, ".travis.yml")) + + # Coveralls should do the same. t.plugins[Coveralls] = Coveralls() gen_plugin(p, t, temp_dir, test_pkg) delete!(t.plugins, Coveralls) - travis = readstring(joinpath(pkg_dir, ".travis.yml")) - @test contains(travis, "after_success") - @test contains(travis, "Coveralls.submit") - @test !contains(travis, "Codecov.submit") - @test !contains(travis, "Pkg.add(\"Documenter\")") + travis = read(joinpath(pkg_dir, ".travis.yml"), String) + @test occursin("after_success", travis) + @test occursin("Coveralls.submit", travis) + @test !occursin("Codecov.submit", travis) + @test !occursin("Pkg.add(\"Documenter\")", travis) rm(joinpath(pkg_dir, ".travis.yml")) + + # With a Documenter plugin, there should be a docs deployment step. t.plugins[GitHubPages] = GitHubPages() gen_plugin(p, t, temp_dir, test_pkg) delete!(t.plugins, GitHubPages) - travis = readstring(joinpath(pkg_dir, ".travis.yml")) - @test contains(travis, "after_success") - @test contains(travis, "Pkg.add(\"Documenter\")") - @test !contains(travis, "Codecov.submit") - @test !contains(travis, "Coveralls.submit") + travis = read(joinpath(pkg_dir, ".travis.yml"), String) + @test occursin("after_success", travis) + @test occursin("Pkg.add(\"Documenter\")", travis) + @test !occursin("Codecov.submit", travis) + @test !occursin("Coveralls.submit", travis) rm(joinpath(pkg_dir, ".travis.yml")) + p = TravisCI(; config_file=nothing) @test isempty(gen_plugin(p, t, temp_dir, test_pkg)) @test !isfile(joinpath(pkg_dir, ".travis.yml")) diff --git a/test/runtests.jl b/test/runtests.jl index c4fbac2..0bc2150 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,7 @@ using PkgTemplates -using Base.Test +using Test +using Dates +using LibGit2 import PkgTemplates: badges, version_floor, substitute, read_license, gen_file, gen_readme, 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 mktempdir() do temp_dir - withenv("JULIA_PKGDIR" => temp_dir) do - # We technically don't need to clone METADATA to run tests. - if get(ENV, "PKGTEMPLATES_TEST_FAST", "false") == "true" - mkdir(joinpath(temp_dir, "v$(version_floor())")) - else - Pkg.init() - end - cd(temp_dir) do - @testset "PkgTemplates.jl" begin - include("tests.jl") - end + mkdir(joinpath(temp_dir, "dev")) + pushfirst!(DEPOT_PATH, temp_dir) + cd(temp_dir) do + @testset "PkgTemplates.jl" begin + include("tests.jl") end end end diff --git a/test/tests.jl b/test/tests.jl index 9f7c176..427ac1a 100644 --- a/test/tests.jl +++ b/test/tests.jl @@ -1,6 +1,7 @@ +# A dummy GenericPlugin subtype. struct Foo <: GenericPlugin gitignore::Vector{AbstractString} - src::Nullable{AbstractString} + src::Union{AbstractString, Nothing} dest::AbstractString badges::Vector{Badge} view::Dict{String, Any} @@ -8,9 +9,12 @@ struct Foo <: GenericPlugin new([], @__FILE__, config_file, [Badge("foo", "bar", "baz")], Dict{String, Any}()) end end +# A dummy CustomPlugin subtype. struct Bar <: CustomPlugin end +# A dummy Plugin subtype. struct Baz <: Plugin end +# Various options to be passed into templates. const me = "christopher-dG" const gitconfig = Dict( "user.name" => "Tester McTestFace", @@ -18,8 +22,9 @@ const gitconfig = Dict( "github.user" => "TesterMcTestFace", ) 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 default_dir = PkgTemplates.dev_dir() const template_text = """ PKGNAME: {{PKGNAME}} VERSION: {{VERSION}}} @@ -32,16 +37,19 @@ const template_text = """ write(test_file, template_text) @testset "Template creation" begin + # Checking default field assignments. t = Template(; user=me) @test t.user == me @test t.license == "MIT" @test t.years == string(Dates.year(Dates.today())) @test t.authors == LibGit2.getconfig("user.name", "") - @test t.dir == Pkg.dir() + @test t.dir == default_dir @test t.julia_version == VERSION @test isempty(t.gitconfig) @test isempty(t.plugins) + # Checking non-default field assignments. + t = Template(; user=me, license="") @test t.license == "" @@ -56,12 +64,14 @@ write(test_file, template_text) t = Template(; user=me, authors="Some Guy") @test t.authors == "Some Guy" + # Vectors of authors should be comma-joined. t = Template(; user=me, authors=["Guy", "Gal"]) @test t.authors == "Guy, Gal" t = Template(; user=me, dir=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))") @test t.dir == joinpath(homedir(), basename(test_file)) end @@ -74,8 +84,10 @@ write(test_file, template_text) t = Template(; user=me, 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] + # Duplicate requirements with non-matching versions should throw. @test_throws ArgumentError Template(; user=me, requirements=[test_pkg, "$test_pkg 0.1"] @@ -84,6 +96,9 @@ write(test_file, template_text) t = Template(; user=me, 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) @test t.authors == gitconfig["user.name"] @@ -91,6 +106,7 @@ write(test_file, template_text) @test t.user == gitconfig["github.user"] @test t.authors == gitconfig["user.name"] + # The template should contain whatever plugins you give it. t = Template(; user=me, plugins = [GitHubPages(), TravisCI(), AppVeyor(), CodeCov(), Coveralls()], @@ -102,11 +118,13 @@ write(test_file, template_text) [GitHubPages(), TravisCI(), AppVeyor(), CodeCov(), Coveralls()] ) - @test_warn r".+" t = Template(; + # Duplicate plugins should warn. + @test_logs (:warn, r".+") t = Template(; user=me, plugins=[TravisCI(), TravisCI()], ) + # If github.user is configured, use that as a default. if isempty(LibGit2.getconfig("github.user", "")) @test_throws ArgumentError Template() else @@ -116,17 +134,18 @@ write(test_file, template_text) @test_throws ArgumentError Template(; user=me, license="FakeLicense") end +# TerminalMenus doesn't work quite right on Travis OSX. if get(ENV, "TRAVIS_OS_NAME", "") != "osx" include(joinpath("interactive", "interactive.jl")) @testset "Interactive plugin creation" begin include(joinpath("interactive", "plugins.jl")) end else - info("Skipping tests that require TerminalMenus") + @info "Skipping tests that require TerminalMenus on OSX" end @testset "Show methods" begin - pkgdir = replace(joinpath(ENV["JULIA_PKGDIR"], "v$(version_floor())"), homedir(), "~") + pkg_dir = replace(default_dir, homedir() => "~") buf = IOBuffer() t = Template(; user=me, gitconfig=gitconfig) show(buf, t) @@ -136,7 +155,7 @@ end → User: $me → Host: github.com → License: MIT ($(gitconfig["user.name"]) $(Dates.year(now()))) - → Package directory: $pkgdir + → Package directory: $pkg_dir → Precompilation enabled: Yes → Minimum Julia version: v$(PkgTemplates.version_floor()) → 0 package requirements @@ -165,7 +184,7 @@ end → User: $me → Host: github.com → License: None - → Package directory: $pkgdir + → Package directory: $pkg_dir → Precompilation enabled: Yes → Minimum Julia version: v$(PkgTemplates.version_floor()) → 2 package requirements: Bar, Foo @@ -201,76 +220,85 @@ end temp_file = tempname() gen_file(temp_file, "Hello, world") @test isfile(temp_file) - @test readstring(temp_file) == "Hello, world\n" + @test read(temp_file, String) == "Hello, world\n" rm(temp_file) + # Test the README generation. @test gen_readme(temp_dir, test_pkg, t) == ["README.md"] @test isfile(joinpath(pkg_dir, "README.md")) readme = readchomp(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) - @test contains(readme, join(badges(p, t.user, test_pkg), "\n")) + @test occursin(join(badges(p, t.user, test_pkg), "\n"), readme) end # Check the order of the badges. - @test search(readme, "github.io").start < - search(readme, "travis").start < - search(readme, "appveyor").start < - search(readme, "codecov").start < - search(readme, "coveralls").start + @test something(findfirst("github.io", readme)).start < + something(findfirst("travis", readme)).start < + something(findfirst("appveyor", readme)).start < + something(findfirst("codecov", readme)).start < + something(findfirst("coveralls", readme)).start # Plugins with badges but not in BADGE_ORDER should appear at the far right side. t.plugins[Foo] = Foo() gen_readme(temp_dir, test_pkg, t) readme = readchomp(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 isfile(joinpath(pkg_dir, ".gitignore")) - gitignore = readstring(joinpath(pkg_dir, ".gitignore")) + gitignore = read(joinpath(pkg_dir, ".gitignore"), String) rm(joinpath(pkg_dir, ".gitignore")) - @test contains(gitignore, ".DS_Store") + @test occursin(".DS_Store", gitignore) for p in values(t.plugins) for entry in p.gitignore - @test contains(gitignore, entry) + @test occursin(entry, gitignore) end end + # Test the license generation. @test gen_license(temp_dir, test_pkg, t) == ["LICENSE"] @test isfile(joinpath(pkg_dir, "LICENSE")) license = readchomp(joinpath(pkg_dir, "LICENSE")) rm(joinpath(pkg_dir, "LICENSE")) - @test contains(license, t.authors) - @test contains(license, t.years) - @test contains(license, read_license(t.license)) + @test occursin(t.authors, license) + @test occursin(t.years, license) + @test occursin(read_license(t.license), license) + # Test the source code entrypoint generation. @test gen_entrypoint(temp_dir, test_pkg, t) == ["src/"] @test isdir(joinpath(pkg_dir, "src")) @test isfile(joinpath(pkg_dir, "src", "$test_pkg.jl")) entrypoint = readchomp(joinpath(pkg_dir, "src", "$test_pkg.jl")) rm(joinpath(pkg_dir, "src"); recursive=true) - @test contains(entrypoint, "__precompile__()") - @test contains(entrypoint, "module $test_pkg") + @test occursin("__precompile__()", entrypoint) + @test occursin("module $test_pkg", entrypoint) t2 = Template(; user=me, precompile=false) gen_entrypoint(temp_dir, test_pkg, t2) entrypoint = readchomp(joinpath(pkg_dir, "src", "$test_pkg.jl")) - @test !contains(entrypoint, "__precompile__()") - @test contains(entrypoint, "module $test_pkg") + @test !occursin("__precompile__()", entrypoint) + @test occursin("module $test_pkg", entrypoint) rm(joinpath(pkg_dir, "src"); recursive=true) + # Test the REQUIRE generation. @test gen_require(temp_dir, test_pkg, t) == ["REQUIRE"] @test isfile(joinpath(pkg_dir, "REQUIRE")) vf = version_floor(t.julia_version) @test readchomp(joinpath(pkg_dir, "REQUIRE")) == "julia $vf\n$test_pkg" rm(joinpath(pkg_dir, "REQUIRE")) + # Test the test generation. @test gen_tests(temp_dir, test_pkg, t) == ["test/"] @test isdir(joinpath(pkg_dir, "test")) @test isfile(joinpath(pkg_dir, "test", "runtests.jl")) runtests = readchomp(joinpath(pkg_dir, "test", "runtests.jl")) rm(joinpath(pkg_dir, "test"); recursive=true) - @test contains(runtests, "using $test_pkg") - @test contains(runtests, "using Base.Test") + @test occursin("using $test_pkg", runtests) + @test occursin("using Base.Test", runtests) rm(temp_dir; recursive=true) end @@ -278,45 +306,54 @@ end @testset "Package generation" begin t = Template(; user=me, gitconfig=gitconfig) generate(test_pkg, t) - @test isfile(Pkg.dir(test_pkg, "LICENSE")) - @test isfile(Pkg.dir(test_pkg, "README.md")) - @test isfile(Pkg.dir(test_pkg, "REQUIRE")) - @test isfile(Pkg.dir(test_pkg, ".gitignore")) - @test isdir(Pkg.dir(test_pkg, "src")) - @test isfile(Pkg.dir(test_pkg, "src", "$test_pkg.jl")) - @test isdir(Pkg.dir(test_pkg, "test")) - @test isfile(Pkg.dir(test_pkg, "test", "runtests.jl")) - repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) + pkg_dir = joinpath(default_dir, test_pkg) + + # Check that the expected files all exist. + @test isfile(joinpath(pkg_dir, "LICENSE")) + @test isfile(joinpath(pkg_dir, "README.md")) + @test isfile(joinpath(pkg_dir, "REQUIRE")) + @test isfile(joinpath(pkg_dir, ".gitignore")) + @test isdir(joinpath(pkg_dir, "src")) + @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") branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo)) @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 # to replace all HTTPS URLs with SSH. @test LibGit2.url(remote) == "https://github.com/$me/$test_pkg.jl" @test in("master", branches) @test !in("gh-pages", branches) @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. - repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) + repo = LibGit2.GitRepo(pkg_dir) remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") @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) generate(test_pkg, t) - repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) + repo = LibGit2.GitRepo(pkg_dir) remote = LibGit2.get(LibGit2.GitRemote, repo, "origin") @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() t = Template(; user=me, dir=temp_dir, gitconfig=gitconfig) generate(test_pkg, t) @test isdir(joinpath(temp_dir, test_pkg)) rm(temp_dir; recursive=true) + # Check that all the plugin files are generated. t = Template(; user=me, license="", @@ -324,45 +361,49 @@ end plugins=[AppVeyor(), GitHubPages(), Coveralls(), CodeCov(), TravisCI()], ) generate(test_pkg, t) - @test isdir(joinpath(Pkg.dir(), test_pkg)) - @test !isfile(Pkg.dir(test_pkg, "LICENSE")) - @test isfile(Pkg.dir(test_pkg, ".travis.yml")) - @test isfile(Pkg.dir(test_pkg, ".appveyor.yml")) - @test isdir(Pkg.dir(test_pkg, "docs")) - @test isfile(Pkg.dir(test_pkg, "docs", "make.jl")) - @test isdir(Pkg.dir(test_pkg, "docs", "src")) - @test isfile(Pkg.dir(test_pkg, "docs", "src", "index.md")) - repo = LibGit2.GitRepo(Pkg.dir(test_pkg)) + @test isdir(pkg_dir) + @test !isfile(joinpath(pkg_dir, "LICENSE")) + @test isfile(joinpath(pkg_dir, ".travis.yml")) + @test isfile(joinpath(pkg_dir, ".appveyor.yml")) + @test isdir(joinpath(pkg_dir, "docs")) + @test isfile(joinpath(pkg_dir, "docs", "make.jl")) + @test isdir(joinpath(pkg_dir, "docs", "src")) + @test isfile(joinpath(pkg_dir, "docs", "src", "index.md")) + # Test that the gh-pages exists for GitHubPages. + repo = LibGit2.GitRepo(pkg_dir) @test LibGit2.getconfig(repo, "user.name", "") == gitconfig["user.name"] branches = map(b -> LibGit2.shortname(first(b)), LibGit2.GitBranchIter(repo)) @test in("gh-pages", branches) @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) generate(test_pkg, t; force=true) - @test isfile(Pkg.dir(test_pkg, "README.md")) - rm(Pkg.dir(test_pkg); recursive=true) + @test isfile(joinpath(pkg_dir, "README.md")) + rm(pkg_dir; recursive=true) - temp_file, fd = mktemp() - close(fd) + # Check that the backup directory mechanism works. + temp_file, io = mktemp() + close(io) temp_dir = mktempdir() - t = Template(; user=me, dir=temp_file, gitconfig=gitconfig) - @test_warn r".+" generate(test_pkg, t; backup_dir=temp_dir) + t = Template(; user=me, dir=temp_file) + @test_logs (:warn, r".+") match_mode=:any generate(test_pkg, t; backup_dir=temp_dir) rm(temp_dir; recursive=true) temp_dir = mktempdir() - t = Template(; user=me, dir=joinpath(temp_file, "file"), gitconfig=gitconfig) - @test_warn r".+" generate(test_pkg, t; backup_dir=temp_dir) + t = Template(; user=me, dir=joinpath(temp_file, "dir")) + @test_logs (:warn, r".+") match_mode=:any generate(test_pkg, t; backup_dir=temp_dir) rm(temp_dir; recursive=true) rm(temp_file) + # Check that the generated docs root is just the copied README. t = Template(; user=me, gitconfig=gitconfig, plugins=[GitHubPages()]) generate(test_pkg, t) - readme = readstring(Pkg.dir(test_pkg, "README.md")) - index = readstring(Pkg.dir(test_pkg, "docs", "src", "index.md")) + readme = read(joinpath(pkg_dir, "README.md"), String) + index = read(joinpath(pkg_dir, "docs", "src", "index.md"), String) @test readme == index - rm(Pkg.dir(test_pkg); recursive=true) + rm(pkg_dir; recursive=true) end @testset "Version floor" begin @@ -375,72 +416,72 @@ end @testset "Mustache substitution" begin view = Dict{String, Any}() text = substitute(template_text, view) - @test !contains(text, "PKGNAME: $test_pkg") - @test !contains(text, "Documenter") - @test !contains(text, "CodeCov") - @test !contains(text, "Coveralls") - @test !contains(text, "After") - @test !contains(text, "Other") + @test !occursin("PKGNAME: $test_pkg", text) + @test !occursin("Documenter", text) + @test !occursin("CodeCov", text) + @test !occursin("Coveralls", text) + @test !occursin("After", text) + @test !occursin("Other", text) view["PKGNAME"] = test_pkg view["OTHER"] = true text = substitute(template_text, view) - @test contains(text, "PKGNAME: $test_pkg") - @test contains(text, "Other") + @test occursin("PKGNAME: $test_pkg", text) + @test occursin("Other", text) t = Template(; user=me) view["OTHER"] = false text = substitute(template_text, t; view=view) - @test contains(text, "PKGNAME: $test_pkg") - @test contains(text, "VERSION: $(t.julia_version.major).$(t.julia_version.minor)") - @test !contains(text, "Documenter") - @test !contains(text, "After") - @test !contains(text, "Other") + @test occursin("PKGNAME: $test_pkg", text) + @test occursin("VERSION: $(t.julia_version.major).$(t.julia_version.minor)", text) + @test !occursin("Documenter", text) + @test !occursin("After", text) + @test !occursin("Other", text) t.plugins[GitHubPages] = GitHubPages() text = substitute(template_text, t; view=view) - @test contains(text, "Documenter") - @test contains(text, "After") + @test occursin("Documenter", text) + @test occursin("After", text) empty!(t.plugins) t.plugins[CodeCov] = CodeCov() text = substitute(template_text, t; view=view) - @test contains(text, "CodeCov") - @test contains(text, "After") + @test occursin("CodeCov", text) + @test occursin("After", text) empty!(t.plugins) t.plugins[Coveralls] = Coveralls() text = substitute(template_text, t; view=view) - @test contains(text, "Coveralls") - @test contains(text, "After") + @test occursin("Coveralls", text) + @test occursin("After", text) empty!(t.plugins) view["OTHER"] = true text = substitute(template_text, t; view=view) - @test contains(text, "Other") + @test occursin("Other", text) end @testset "License display" begin - old_stdout = STDOUT - out_read, out_write = redirect_stdout() - available_licenses() - licenses = String(readavailable(out_read)) - show_license("MIT") - mit = String(readavailable(out_read)) - close(out_write) - close(out_read) - redirect_stdout(old_stdout) + io = IOBuffer() + available_licenses(io) + licenses = String(take!(io)) + show_license(io, "MIT") + mit = String(take!(io)) + # Check that all licenses are included in the display. for (short, long) in LICENSES - @test contains(licenses, "$short: $long") + @test occursin("$short: $long", licenses) end @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) + # Check that all licenses included with the package are displayed. for license in readdir(LICENSE_DIR) @test haskey(LICENSES, license) end + # Check that all licenses displayed are included with the package. + @test length(readdir(LICENSE_DIR)) == length(LICENSES) end @testset "Plugins" begin @@ -449,6 +490,7 @@ end temp_dir = mktempdir() pkg_dir = joinpath(temp_dir, test_pkg) + # Check badge constructor and formatting. badge = Badge("A", "B", "C") @test badge.hover == "A" @test badge.image == "B"