Merge pull request #29 from invenia/cdg/fixups

Drop Git configuration test dependencies, add Test as test-only, use Pkg's devdir instead of our own
This commit is contained in:
Eric Davies 2018-10-29 13:36:48 -05:00 committed by GitHub
commit aa3758476a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 98 additions and 74 deletions

View File

@ -20,9 +20,6 @@ build_script:
- echo "%JL_BUILD_SCRIPT%" - echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
test_script: test_script:
# 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%" - echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
on_success: on_success:

View File

@ -12,12 +12,10 @@ matrix:
fast_finish: true fast_finish: true
notifications: notifications:
email: false email: false
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: after_success:
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; CodeCov.submit(process_folder())' - julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; CodeCov.submit(process_folder())'
# For zero-argument template example. # For package generation examples.
- git config --global user.name "Travis"
- git config --global user.email "travis@c.i"
- git config --global github.user "travis" - git config --global github.user "travis"
- julia -e 'using Pkg; ps=Pkg.PackageSpec(name="Documenter", version="0.19"); Pkg.add(ps); Pkg.pin(ps); include(joinpath("docs", "make.jl"))' - julia -e 'using Pkg; ps=Pkg.PackageSpec(name="Documenter", version="0.19"); Pkg.add(ps); Pkg.pin(ps); include(joinpath("docs", "make.jl"))'

View File

@ -37,9 +37,9 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
[[Mustache]] [[Mustache]]
deps = ["Pkg", "Tables", "Test"] deps = ["Pkg", "Tables", "Test"]
git-tree-sha1 = "455807b7c098d8a31f26792f685d5be250e83292" git-tree-sha1 = "1cee2f530502aa2357724e7b19af3239b2e7f6b7"
uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
version = "0.5.4" version = "0.5.5"
[[Pkg]] [[Pkg]]
deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]

View File

@ -1,7 +1,7 @@
name = "PkgTemplates" name = "PkgTemplates"
uuid = "19f0ff7e-bab4-11e8-074b-97459630f98a" uuid = "19f0ff7e-bab4-11e8-074b-97459630f98a"
authors = ["Chris de Graaf <chrisadegraaf@gmail.com>"] authors = ["Chris de Graaf <chrisadegraaf@gmail.com>"]
version = "0.1.0" version = "0.3.0"
[deps] [deps]
AutoHashEquals = "15f4f7f2-30c1-5605-9d31-71845cf9641f" AutoHashEquals = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
@ -12,5 +12,10 @@ LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
URIParser = "30578b45-9adc-5946-b283-645ec420af67" URIParser = "30578b45-9adc-5946-b283-645ec420af67"
[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[targets]
test = ["Test"]

View File

@ -1,27 +1,40 @@
""" """
generate(pkg_name::AbstractString, t::Template) -> Nothing generate(pkg::AbstractString, t::Template) -> Nothing
generate(t::Template, pkg::AbstractString) -> Nothing
Generate a package named `pkg_name` from `t`. Generate a package named `pkg` from `t`.
""" """
function generate(pkg_name::AbstractString, t::Template) function generate(
pkg_dir = joinpath(t.dir, pkg_name) pkg::AbstractString,
t::Template;
gitconfig::Union{GitConfig, Nothing}=nothing,
)
pkg = splitjl(pkg)
pkg_dir = joinpath(t.dir, pkg)
ispath(pkg_dir) && throw(ArgumentError("$pkg_dir already exists")) ispath(pkg_dir) && throw(ArgumentError("$pkg_dir already exists"))
try try
pkg_name = splitjl(pkg_name)
pkg_dir = joinpath(t.dir, pkg_name)
# Create the directory with some boilerplate inside. # Create the directory with some boilerplate inside.
Pkg.generate(pkg_dir) Pkg.generate(pkg_dir)
# Initialize the repo. # Initialize the repo.
repo = LibGit2.init(pkg_dir) repo = LibGit2.init(pkg_dir)
@info "Initialized git repo at $pkg_dir" @info "Initialized git repo at $pkg_dir"
if gitconfig !== nothing
# Configure the repo.
repoconfig = GitConfig(repo)
for c in LibGit2.GitConfigIter(gitconfig)
LibGit2.set!(repoconfig, unsafe_string(c.name), unsafe_string(c.value))
end
end
# Commit and set the remote.
LibGit2.commit(repo, "Initial commit") LibGit2.commit(repo, "Initial commit")
rmt = if t.ssh rmt = if t.ssh
"git@$(t.host):$(t.user)/$pkg_name.jl.git" "git@$(t.host):$(t.user)/$pkg.jl.git"
else else
"https://$(t.host)/$(t.user)/$pkg_name.jl" "https://$(t.host)/$(t.user)/$pkg.jl"
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))
@ -30,7 +43,7 @@ function generate(pkg_name::AbstractString, t::Template)
# 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, "Initial commit")
@info "Created empty gh-pages branch" @info "Created empty gh-pages branch"
LibGit2.branch!(repo, "master") LibGit2.branch!(repo, "master")
end end
@ -43,14 +56,13 @@ function generate(pkg_name::AbstractString, t::Template)
gen_readme(pkg_dir, t), gen_readme(pkg_dir, t),
gen_gitignore(pkg_dir, t), gen_gitignore(pkg_dir, t),
gen_license(pkg_dir, t), gen_license(pkg_dir, t),
vcat(map(p -> gen_plugin(p, t, pkg_name), values(t.plugins))...), vcat(map(p -> gen_plugin(p, t, pkg), values(t.plugins))...),
) )
LibGit2.add!(repo, files...) LibGit2.add!(repo, files...)
LibGit2.commit(repo, "Files generated by PkgTemplates") LibGit2.commit(repo, "Files generated by PkgTemplates")
@info "Staged and committed $(length(files)) files/directories: $(join(files, ", "))" @info "Committed $(length(files)) files/directories: $(join(files, ", "))"
@info "Finished"
if length(collect(LibGit2.GitBranchIter(repo))) > 1 if length(collect(LibGit2.GitBranchIter(repo))) > 1
@info "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
@ -60,7 +72,13 @@ function generate(pkg_name::AbstractString, t::Template)
end end
end end
generate(t::Template, pkg_name::AbstractString) = generate(pkg_name, t) function generate(
t::Template,
pkg::AbstractString;
gitconfig::Union{GitConfig, Nothing}=nothing,
)
generate(pkg, t; gitconfig=gitconfig)
end
""" """
generate_interactive(pkg::AbstractString; fast::Bool=false) -> Template generate_interactive(pkg::AbstractString; fast::Bool=false) -> Template
@ -69,9 +87,13 @@ Interactively create a template, and then generate a package with it. Arguments
keywords are used in the same way as in [`generate`](@ref) and keywords are used in the same way as in [`generate`](@ref) and
[`interactive_template`](@ref). [`interactive_template`](@ref).
""" """
function generate_interactive(pkg::AbstractString; fast::Bool=false) function generate_interactive(
pkg::AbstractString;
fast::Bool=false,
gitconfig::Union{GitConfig, Nothing}=nothing,
)
t = interactive_template(; fast=fast) t = interactive_template(; fast=fast)
generate(pkg, t) generate(pkg, t; gitconfig=gitconfig)
return t return t
end end
@ -87,13 +109,28 @@ Create the test entrypoint in `pkg_dir`.
Returns an array of generated file/directory names. Returns an array of generated file/directory names.
""" """
function gen_tests(pkg_dir::AbstractString, t::Template) function gen_tests(pkg_dir::AbstractString, t::Template)
# TODO: Silence Pkg for this section? Adding and removing Test creates a lot of noise.
proj = Base.current_project() proj = Base.current_project()
try try
Pkg.activate(pkg_dir) Pkg.activate(pkg_dir)
Pkg.add("Test") Pkg.add("Test")
# Move the Test dependency into the [extras] section.
toml = read(joinpath(pkg_dir, "Project.toml"), String)
lines = split(toml, "\n")
idx = findfirst(l -> startswith(l, "Test = "), lines)
testdep = lines[idx]
deleteat!(lines, idx)
toml = join(lines, "\n") * """
[extras]
$testdep
[targets]
test = ["Test"]
"""
gen_file(joinpath(pkg_dir, "Project.toml"), toml)
Pkg.update() # Regenerate Manifest.toml (this cleans up Project.toml too).
finally finally
# TODO: What should we do if there is no current project?
# Activating the generated project is now a side effect.
proj !== nothing && Pkg.activate(dirname(proj)) proj !== nothing && Pkg.activate(dirname(proj))
end end
@ -104,12 +141,10 @@ function gen_tests(pkg_dir::AbstractString, t::Template)
@testset "$pkg.jl" begin @testset "$pkg.jl" begin
# Write your own tests here. # Write your own tests here.
@test 1 == 2
end end
""" """
gen_file(joinpath(pkg_dir, "test", "runtests.jl"), text) gen_file(joinpath(pkg_dir, "test", "runtests.jl"), text)
# TODO: Should we be checking Manifest.toml into Git?
return ["Manifest.toml", "test/"] return ["Manifest.toml", "test/"]
end end
@ -298,9 +333,4 @@ function substitute(
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 splitjl(pkg::AbstractString) = endswith(pkg, ".jl") ? pkg[1:end-3] : pkg

View File

@ -1,10 +1,3 @@
"""
dev_dir() -> String
Get the default development directory (~/.julia/dev).
"""
dev_dir() = joinpath(first(DEPOT_PATH), "dev")
""" """
Template(; kwargs...) -> Template Template(; kwargs...) -> Template
@ -13,9 +6,9 @@ create a template, you can use [`interactive_template`](@ref) instead.
# Keyword Arguments # Keyword Arguments
* `user::AbstractString=""`: GitHub (or other code hosting service) username. If left * `user::AbstractString=""`: GitHub (or other code hosting service) username. If left
unset, it will take the the global git config's value. If that is not set, an unset, it will take the the global git config's value (`github.user`). If that is not
`ArgumentError` is thrown. **This is case-sensitive for some plugins, so take care to set, an `ArgumentError` is thrown. **This is case-sensitive for some plugins, so take
enter it correctly.** care to enter it correctly.**
* `host::AbstractString="github.com"`: URL to the code hosting service where your package * `host::AbstractString="github.com"`: URL to the code hosting service where your package
will reside. Note that while hosts other than GitHub won't cause errors, they are not will reside. Note that while hosts other than GitHub won't cause errors, they are not
officially supported and they will cause certain plugins will produce incorrect output. officially supported and they will cause certain plugins will produce incorrect output.
@ -26,9 +19,9 @@ create a template, you can use [`interactive_template`](@ref) instead.
* `authors::Union{AbstractString, Vector{<:AbstractString}}=""`: Names that appear on the * `authors::Union{AbstractString, Vector{<:AbstractString}}=""`: Names that appear on the
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 take the value of of the global git config's value if it is left unset. it will take the value of of the global git config's value if it is left unset.
* `dir::AbstractString=$(dev_dir())`: Directory in which the package will go. Relative * `dir::AbstractString=$(replace(Pkg.devdir(), homedir() => "~"))`: Directory in which the
paths are converted to absolute ones at template creation time. package will go. Relative paths are converted to absolute ones at template creation time.
* `julia_version::VersionNumber=VERSION`: Minimum allowed Julia version. * `julia_version::VersionNumber=$VERSION`: Minimum allowed Julia version.
* `ssh::Bool=false`: Whether or not to use SSH for the remote. * `ssh::Bool=false`: Whether or not to use SSH for the remote.
* `plugins::Vector{<:Plugin}=Plugin[]`: A list of `Plugin`s that the package will include. * `plugins::Vector{<:Plugin}=Plugin[]`: A list of `Plugin`s that the package will include.
""" """
@ -47,22 +40,18 @@ create a template, you can use [`interactive_template`](@ref) instead.
host::AbstractString="https://github.com", host::AbstractString="https://github.com",
license::AbstractString="MIT", license::AbstractString="MIT",
authors::Union{AbstractString, Vector{<:AbstractString}}="", authors::Union{AbstractString, Vector{<:AbstractString}}="",
dir::AbstractString=dev_dir(), dir::AbstractString=Pkg.devdir(),
julia_version::VersionNumber=VERSION, julia_version::VersionNumber=VERSION,
ssh::Bool=false, ssh::Bool=false,
plugins::Vector{<:Plugin}=Plugin[], plugins::Vector{<:Plugin}=Plugin[],
) )
# Check for required Git options for package generation # Check for required Git options for package generation
# (you can't commit to a repository without them). # (you can't commit to a repository without them).
if isempty(LibGit2.getconfig("user.name", "")) isempty(LibGit2.getconfig("user.name", "")) && missingopt("user.name")
@warn "Git config option 'user.name' missing, package generation will fail" isempty(LibGit2.getconfig("user.email", "")) && missingopt("user.email")
end
if isempty(LibGit2.getconfig("user.email", ""))
@warn "Git config option 'user.email' missing, package generation will fail"
end
# If no username was set, look for one in the global git config. # If no username was set, look for one in the global git config.
# Note: This is one of a few GitHub specifics. # Note: This is one of a few GitHub specifics (maybe we could use the host value).
if isempty(user) if isempty(user)
user = LibGit2.getconfig("github.user", "") user = LibGit2.getconfig("github.user", "")
end end
@ -186,9 +175,9 @@ function interactive_template(; fast::Bool=false)
end end
kwargs[:dir] = if fast kwargs[:dir] = if fast
dev_dir() Pkg.devdir()
else else
default_dir = dev_dir() default_dir = Pkg.devdir()
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
@ -223,9 +212,6 @@ function interactive_template(; fast::Bool=false)
return Template(; kwargs...) return Template(; kwargs...)
end end
"""
leaves(t:Type) -> Vector{DataType}
Get all concrete subtypes of `t`.
"""
leaves(t::Type)::Vector{DataType} = isconcretetype(t) ? [t] : vcat(leaves.(subtypes(t))...) leaves(t::Type)::Vector{DataType} = isconcretetype(t) ? [t] : vcat(leaves.(subtypes(t))...)
missingopt(name) = @warn "Git config option '$name' missing, package generation will fail unless you supply a GitConfig"

3
test/gitconfig Normal file
View File

@ -0,0 +1,3 @@
[user]
name = Travis
email = travis@c.i

View File

@ -52,7 +52,7 @@ end
@testset "Interactive package generation" begin @testset "Interactive package generation" begin
write(stdin.buffer, "$me\n\n\r\n\n\n\n\n\nd") write(stdin.buffer, "$me\n\n\r\n\n\n\n\n\nd")
generate_interactive(test_pkg) generate_interactive(test_pkg; gitconfig=gitconfig)
@test isdir(joinpath(default_dir, test_pkg)) @test isdir(joinpath(default_dir, test_pkg))
rm(joinpath(default_dir, test_pkg); force=true, recursive=true) rm(joinpath(default_dir, test_pkg); force=true, recursive=true)
end end

View File

@ -56,7 +56,7 @@ pkg_dir = joinpath(t.dir, test_pkg)
@testset "Package generation with GitHubPages plugin" begin @testset "Package generation with GitHubPages plugin" begin
temp_dir = mktempdir() temp_dir = mktempdir()
t = Template(; user=me, dir=temp_dir, plugins=[GitHubPages()]) t = Template(; user=me, dir=temp_dir, plugins=[GitHubPages()])
generate(test_pkg, t) generate(test_pkg, t; gitconfig=gitconfig)
# Check that the gh-pages branch exists. # Check that the gh-pages branch exists.
repo = LibGit2.GitRepo(joinpath(t.dir, test_pkg)) repo = LibGit2.GitRepo(joinpath(t.dir, test_pkg))

View File

@ -2,6 +2,7 @@ using PkgTemplates
using Test using Test
using Dates using Dates
using LibGit2 using LibGit2
using Pkg
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_gitignore, gen_plugin, show_license, LICENSES, gen_tests, gen_license, gen_require, gen_gitignore, gen_plugin, show_license, LICENSES,

View File

@ -19,7 +19,8 @@ const me = "christopher-dG"
const test_pkg = "TestPkg" const test_pkg = "TestPkg"
const fake_path = "/dev/null/this/file/does/not/exist" const fake_path = "/dev/null/this/file/does/not/exist"
const test_file = tempname() const test_file = tempname()
const default_dir = PkgTemplates.dev_dir() const default_dir = Pkg.devdir()
const gitconfig = GitConfig(joinpath(@__DIR__, "gitconfig"))
const template_text = """ const template_text = """
PKGNAME: {{PKGNAME}} PKGNAME: {{PKGNAME}}
VERSION: {{VERSION}}} VERSION: {{VERSION}}}
@ -79,7 +80,7 @@ write(test_file, template_text)
) )
# Duplicate plugins should warn. # Duplicate plugins should warn.
@test_logs (:warn, r".+") t = Template(; @test_logs (:warn, r"duplicates") match_mode=:any t = Template(;
user=me, user=me,
plugins=[TravisCI(), TravisCI()], plugins=[TravisCI(), TravisCI()],
) )
@ -224,6 +225,9 @@ end
# Test the test generation. # Test the test generation.
@test gen_tests(pkg_dir, t) == ["Manifest.toml", "test/"] @test gen_tests(pkg_dir, t) == ["Manifest.toml", "test/"]
@test isfile(joinpath(pkg_dir, "Project.toml"))
project = read(joinpath(pkg_dir, "Project.toml"), String)
@test occursin("[extras]\nTest = ", project)
@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"))
@test isfile(joinpath(pkg_dir, "Manifest.toml")) @test isfile(joinpath(pkg_dir, "Manifest.toml"))
@ -232,14 +236,14 @@ end
@test occursin("using $test_pkg", runtests) @test occursin("using $test_pkg", runtests)
@test occursin("using Test", runtests) @test occursin("using Test", runtests)
manifest = read(joinpath(pkg_dir, "Manifest.toml"), String) manifest = read(joinpath(pkg_dir, "Manifest.toml"), String)
@test occursin("[[Test]]", manifest) @test !occursin("[[Test]]", manifest)
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
end end
@testset "Package generation" begin @testset "Package generation" begin
t = Template(; user=me) t = Template(; user=me)
generate(test_pkg, t) generate(test_pkg, t; gitconfig=gitconfig)
pkg_dir = joinpath(default_dir, test_pkg) pkg_dir = joinpath(default_dir, test_pkg)
# Check that the expected files all exist. # Check that the expected files all exist.
@ -266,7 +270,7 @@ end
# Check that the remote is an SSH URL when we want it to be. # Check that the remote is an SSH URL when we want it to be.
t = Template(; user=me, ssh=true) t = Template(; user=me, ssh=true)
generate(t, test_pkg) # Test the reversed-arguments method here. generate(t, test_pkg; gitconfig=gitconfig) # Test the reversed-arguments method here.
repo = LibGit2.GitRepo(pkg_dir) 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"
@ -274,7 +278,7 @@ end
# Check that the remote is set correctly for non-default hosts. # Check that the remote is set correctly for non-default hosts.
t = Template(; user=me, host="gitlab.com") t = Template(; user=me, host="gitlab.com")
generate(test_pkg, t) generate(test_pkg, t; gitconfig=gitconfig)
repo = LibGit2.GitRepo(pkg_dir) 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"
@ -283,7 +287,7 @@ end
# Check that the package ends up in the right directory. # Check that the package ends up in the right directory.
temp_dir = mktempdir() temp_dir = mktempdir()
t = Template(; user=me, dir=temp_dir) t = Template(; user=me, dir=temp_dir)
generate(test_pkg, t) generate(test_pkg, t; gitconfig=gitconfig)
@test isdir(joinpath(temp_dir, test_pkg)) @test isdir(joinpath(temp_dir, test_pkg))
rm(temp_dir; recursive=true) rm(temp_dir; recursive=true)
end end