Take username and host as separate keywords, allow ssh remotes

This commit is contained in:
Chris de Graaf 2017-08-15 11:10:05 -05:00
parent ffdf06d441
commit 9824d1a61a
8 changed files with 107 additions and 75 deletions

View File

@ -1,5 +1,10 @@
""" """
generate(pkg_name::AbstractString, t::Template) -> Void generate(
pkg_name::AbstractString,
t::Template;
force::Bool=false,
ssh::Bool=false,
) -> Void
Generate a package from a template. Generate a package from a template.
@ -9,8 +14,15 @@ Generate a package from a template.
# Keyword Arguments # Keyword Arguments
* `force::Bool=false`: Whether or not to overwrite old packages with the same name. * `force::Bool=false`: Whether or not to overwrite old packages with the same name.
* `ssh::Bool=false`: Whether or not to use SSH for the remote.
""" """
function generate(pkg_name::AbstractString, t::Template; force::Bool=false) function generate(
pkg_name::AbstractString,
t::Template;
force::Bool=false,
ssh::Bool=false,
)
pkg_name = Pkg.splitjl(pkg_name) pkg_name = Pkg.splitjl(pkg_name)
pkg_dir = joinpath(t.path, pkg_name) pkg_dir = joinpath(t.path, pkg_name)
@ -31,11 +43,13 @@ function generate(pkg_name::AbstractString, t::Template; force::Bool=false)
LibGit2.set!(cfg, key, val) LibGit2.set!(cfg, key, val)
end end
info("Finished configuring git") info("Finished configuring git")
url = "$(t.remote_prefix)$pkg_name.jl"
LibGit2.commit(repo, "Empty initial commit") LibGit2.commit(repo, "Empty initial commit")
info("Made initial empty commit") info("Made initial empty commit")
LibGit2.set_remote_url(repo, url) rmt = ssh ? "git@$(t.host):$(t.user)/$pkg_name.jl.git" :
info("Set remote origin to $url") "https://$(t.host)/$(t.user)/$pkg_name.jl"
LibGit2.set_remote_url(repo, rmt)
info("Set remote origin to $rmt")
# Create the gh-pages branch if necessary. # Create the gh-pages branch if necessary.
if haskey(t.plugins, GitHubPages) if haskey(t.plugins, GitHubPages)
@ -89,7 +103,7 @@ function gen_readme(pkg_dir::AbstractString, t::Template)
ordering = [GitHubPages, TravisCI, AppVeyor, CodeCov] ordering = [GitHubPages, TravisCI, AppVeyor, CodeCov]
for plugin_type in ordering for plugin_type in ordering
if haskey(t.plugins, plugin_type) if haskey(t.plugins, plugin_type)
text *= "\n" * join(badges(t.plugins[plugin_type], t, pkg_name), "\n") text *= "\n" * join(badges(t.plugins[plugin_type], t.user, pkg_name), "\n")
end end
end end

View File

@ -25,19 +25,18 @@ Add AppVeyor to a template's plugins to add AppVeyor CI support.
end end
""" """
badges(\_::AppVeyor, pkg_name::AbstractString, t::Template) -> Vector{String} badges(\_::AppVeyor, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package. Generate Markdown badges for the current package.
# Arguments # Arguments
* `_::AppVeyor`: Plugin whose badges we are generating. * `_::AppVeyor`: Plugin whose badges we are generating.
* `t::Template`: Template configuration options. * `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package. * `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges. Returns an array of Markdown badges.
""" """
function badges(_::AppVeyor, t::Template, pkg_name::AbstractString) function badges(_::AppVeyor, user::AbstractString, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
return [ return [
"[![Build Status](https://ci.appveyor.com/api/projects/status/github/$user/$pkg_name.jl?svg=true)](https://ci.appveyor.com/project/$user/$pkg_name-jl)" "[![Build Status](https://ci.appveyor.com/api/projects/status/github/$user/$pkg_name.jl?svg=true)](https://ci.appveyor.com/project/$user/$pkg_name-jl)"
] ]

View File

@ -30,14 +30,13 @@ end
Generate Markdown badges for the current package. Generate Markdown badges for the current package.
# Arguments # Arguments
* `_::CodeCov`: plugin whose badges we are generating. * `_::CodeCov`: Plugin whose badges we are generating.
* `t::Template`: Template configuration options. * `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package. * `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges. Returns an array of Markdown badges.
""" """
function badges(_::CodeCov, t::Template, pkg_name::AbstractString) function badges(_::CodeCov, user::AbstractString, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
return [ return [
"[![CodeCov](https://codecov.io/gh/$user/$pkg_name.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/$user/$pkg_name.jl)" "[![CodeCov](https://codecov.io/gh/$user/$pkg_name.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/$user/$pkg_name.jl)"
] ]

View File

@ -40,9 +40,8 @@ function gen_plugin(plugin::Documenter, template::Template, pkg_name::AbstractSt
assets_string *= "$TAB]" assets_string *= "$TAB]"
else else
assets = "[]" assets_string = "[]"
end end
user = strip(URI(template.remote_prefix).path, '/')
text = """ text = """
using Documenter, $pkg_name using Documenter, $pkg_name
@ -52,7 +51,7 @@ function gen_plugin(plugin::Documenter, template::Template, pkg_name::AbstractSt
pages=[ pages=[
"Home" => "index.md", "Home" => "index.md",
], ],
repo="$(template.remote_prefix)$pkg_name.jl/blob/{commit}{path}#L{line}", repo="https://github.com/$(template.user)/$pkg_name.jl/blob/{commit}{path}#L{line}",
sitename="$pkg_name.jl", sitename="$pkg_name.jl",
authors="$(template.authors)", authors="$(template.authors)",
assets=$assets_string, assets=$assets_string,

View File

@ -22,19 +22,18 @@ Add GitHubPages to a template's plugins to add Documenter.jl support via GitHub
end end
""" """
badges(\_::GitHubPages, pkg_name::AbstractString, t::Template) -> Vector{String} badges(\_::GitHubPages, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package. Generate Markdown badges for the current package.
# Arguments # Arguments
* `_::GitHubPages`: plugin whose badges we are generating. * `_::GitHubPages`: plugin whose badges we are generating.
* `t::Template`: Template configuration options. * `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package. * `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges. Returns an array of Markdown badges.
""" """
function badges(_::GitHubPages, t::Template, pkg_name::AbstractString) function badges(_::GitHubPages, user::AbstractString, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
return [ return [
"[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$user.github.io/$pkg_name.jl/stable)" "[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://$user.github.io/$pkg_name.jl/stable)"
"[![Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://$user.github.io/$pkg_name.jl/latest)" "[![Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://$user.github.io/$pkg_name.jl/latest)"
@ -61,14 +60,13 @@ function gen_plugin(plugin::GitHubPages, template::Template, pkg_name::AbstractS
) )
if haskey(template.plugins, TravisCI) if haskey(template.plugins, TravisCI)
docs_src = joinpath(template.path, pkg_name, "docs", "src") docs_src = joinpath(template.path, pkg_name, "docs", "src")
user = strip(URI(template.remote_prefix).path, '/')
open(joinpath(dirname(docs_src), "make.jl"), "a") do file open(joinpath(dirname(docs_src), "make.jl"), "a") do file
write( write(
file, file,
""" """
deploydocs( deploydocs(
repo="github.com/$user/$pkg_name.jl", repo="github.com/$(template.user)/$pkg_name.jl",
target="build", target="build",
julia="0.6", julia="0.6",
deps=nothing, deps=nothing,

View File

@ -25,19 +25,18 @@ Add TravisCI to a template's plugins to add Travis CI support.
end end
""" """
badges(\_::TravisCI, pkg_name::AbstractString, t::Template) -> Vector{String} badges(\_::TravisCI, user::AbstractString, pkg_name::AbstractString) -> Vector{String}
Generate Markdown badges for the current package. Generate Markdown badges for the current package.
# Arguments # Arguments
* `_::TravisCI`: plugin whose badges we are generating. * `_::TravisCI`: plugin whose badges we are generating.
* `t::Template`: Template configuration and plugins. * `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package. * `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges. Returns an array of Markdown badges.
""" """
function badges(_::TravisCI, t::Template, pkg_name::AbstractString) function badges(_::TravisCI, user::AbstractString, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
return [ return [
"[![Build Status](https://travis-ci.org/$user/$pkg_name.jl.svg?branch=master)](https://travis-ci.org/$user/$pkg_name.jl)" "[![Build Status](https://travis-ci.org/$user/$pkg_name.jl.svg?branch=master)](https://travis-ci.org/$user/$pkg_name.jl)"
] ]

View File

@ -4,11 +4,11 @@
Records common information used to generate a package. Records common information used to generate a package.
# Keyword Arguments # Keyword Arguments
* `remote_prefix::AbstractString`: The base url for the remote repository. e.g. * `user::AbstractString=LibGit2.getconfig("github.username", "")`: GitHub username.
"https://github.com/username/". This will be used with the package name to set the url If left as default and there is no value configured, an error will be thrown.
for the remote repository, as well as to determine the account's username. Failing to Alternatively, you can add a value to `git_config["github.username"]` to set your
specify this will cause an error. This is case-sensitive for some plugins, so take care username. This is case-sensitive for some plugins, so take care to enter it correctly.
to enter it correctly. * `host::AbstractString="github.com"`: Code hosting service where your package will reside.
* `license::Union{AbstractString, Void}=nothing`: Name of the package licsense. If * `license::Union{AbstractString, Void}=nothing`: Name of the package licsense. If
no license is specified, no license is created. `show_license` can be used to list all no license is specified, no license is created. `show_license` can be used to list all
available licenses, or to print out a particular license's text. available licenses, or to print out a particular license's text.
@ -22,7 +22,8 @@ Records common information used to generate a package.
* `plugins::Vector{Plugin}`: A list of `Plugin`s that the package will include. * `plugins::Vector{Plugin}`: A list of `Plugin`s that the package will include.
""" """
@auto_hash_equals struct Template @auto_hash_equals struct Template
remote_prefix::AbstractString user::AbstractString
host::AbstractString
license::Union{AbstractString, Void} license::Union{AbstractString, Void}
authors::Union{AbstractString, Array} authors::Union{AbstractString, Array}
years::AbstractString years::AbstractString
@ -31,8 +32,9 @@ Records common information used to generate a package.
git_config::Dict{String, String} git_config::Dict{String, String}
plugins::Dict{DataType, Plugin} plugins::Dict{DataType, Plugin}
function Template{P <: Plugin}(; function Template(;
remote_prefix::AbstractString="", user::AbstractString=LibGit2.getconfig("github.username", ""),
host::AbstractString="https://github.com",
license::Union{AbstractString, Void}=nothing, license::Union{AbstractString, Void}=nothing,
authors::Union{AbstractString, Array}=LibGit2.getconfig("user.name", ""), authors::Union{AbstractString, Array}=LibGit2.getconfig("user.name", ""),
years::Union{Int, AbstractString}=string(Dates.year(Dates.today())), years::Union{Int, AbstractString}=string(Dates.year(Dates.today())),
@ -40,11 +42,20 @@ Records common information used to generate a package.
julia_version::VersionNumber=VERSION, julia_version::VersionNumber=VERSION,
git_config::Dict{String, String}=Dict{String, String}(), git_config::Dict{String, String}=Dict{String, String}(),
plugins::Vector{P}=Vector{Plugin}(), plugins::Vector{P}=Vector{Plugin}(),
) ) where P <: Plugin
if isempty(remote_prefix) # If no username was set or found, look for one in the supplied git config.
throw(ArgumentError("Must specify remote_prefix::AbstractString")) if isempty(user) && (!haskey(git_config, "github.username") ||
isempty(git_config["github.username"]))
throw(ArgumentError("No GitHub username found, set one with user=username"))
elseif isempty(user)
user = git_config["github.username"]
end
host = URI(startswith(host, "https://") ? host : "https://$host").host
if license != nothing && !isfile(joinpath(LICENSE_DIR, license))
throw(ArgumentError("License '$license' is not available"))
end end
years = string(years)
# If an explicitly supplied git config contains a name and the author name was not # If an explicitly supplied git config contains a name and the author name was not
# explicitly supplied, then take the git config's name as the author name. # explicitly supplied, then take the git config's name as the author name.
@ -53,13 +64,8 @@ Records common information used to generate a package.
elseif isa(authors, Array) elseif isa(authors, Array)
authors = join(authors, ", ") authors = join(authors, ", ")
end end
if !endswith(remote_prefix, "/")
remote_prefix *= "/"
end
if license != nothing && !isfile(joinpath(LICENSE_DIR, license))
throw(ArgumentError("License '$license' is not available"))
end
years = string(years)
plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins) plugin_dict = Dict{DataType, Plugin}(typeof(p) => p for p in plugins)
if (length(plugins) != length(plugin_dict)) if (length(plugins) != length(plugin_dict))
@ -67,8 +73,8 @@ Records common information used to generate a package.
end end
new( new(
remote_prefix, license, authors, years, path, user, host, license, authors, years, path,
julia_version, git_config, plugin_dict, julia_version, git_config, plugin_dict
) )
end end
end end

View File

@ -1,7 +1,7 @@
const invenia_url = "https://github.com/invenia"
const git_config = Dict( const git_config = Dict(
"user.name" => "Tester McTestFace", "user.name" => "Tester McTestFace",
"user.email" => "email@web.site", "user.email" => "email@web.site",
"github.username" => "TesterMcTestFace",
) )
const fake_path = joinpath(tempdir(), tempdir()) const fake_path = joinpath(tempdir(), tempdir())
@ -17,8 +17,8 @@ template_text = """
write(test_file, template_text) write(test_file, template_text)
@testset "Template creation" begin @testset "Template creation" begin
t = Template(remote_prefix=invenia_url) t = Template(; user="invenia")
@test t.remote_prefix == "$invenia_url/" @test t.user == "invenia"
@test t.license == nothing @test t.license == nothing
@test t.years == string(Dates.year(Dates.today())) @test t.years == string(Dates.year(Dates.today()))
@test t.authors == LibGit2.getconfig("user.name", "") @test t.authors == LibGit2.getconfig("user.name", "")
@ -27,44 +27,47 @@ write(test_file, template_text)
@test isempty(t.git_config) @test isempty(t.git_config)
@test isempty(t.plugins) @test isempty(t.plugins)
t = Template(remote_prefix=invenia_url; license="MIT") t = Template(; user="invenia", license="MIT")
@test t.license == "MIT" @test t.license == "MIT"
t = Template(remote_prefix=invenia_url; years=2014) t = Template(; user="invenia", years=2014)
@test t.years == "2014" @test t.years == "2014"
t = Template(remote_prefix=invenia_url; years="2014-2015") t = Template(user="invenia", years="2014-2015")
@test t.years == "2014-2015" @test t.years == "2014-2015"
t = Template(remote_prefix=invenia_url; authors="Some Guy") t = Template(; user="invenia", authors="Some Guy")
@test t.authors == "Some Guy" @test t.authors == "Some Guy"
t = Template(remote_prefix=invenia_url; authors=["Guy", "Gal"]) t = Template(; user="invenia", authors=["Guy", "Gal"])
@test t.authors == "Guy, Gal" @test t.authors == "Guy, Gal"
t = Template(remote_prefix=invenia_url; path=test_file) t = Template(; user="invenia", path=test_file)
@test t.path == test_file @test t.path == test_file
t = Template(remote_prefix=invenia_url; julia_version=v"0.1.2") t = Template(; user="invenia", julia_version=v"0.1.2")
@test t.julia_version == v"0.1.2" @test t.julia_version == v"0.1.2"
t = Template(remote_prefix=invenia_url; git_config=git_config) t = Template(; user="invenia", git_config=git_config)
@test t.git_config == git_config @test t.git_config == git_config
t = Template(remote_prefix=invenia_url; git_config=git_config) t = Template(; user="invenia", git_config=git_config)
@test t.authors == git_config["user.name"] @test t.authors == git_config["user.name"]
t = Template( t = Template(; git_config=git_config)
remote_prefix=invenia_url, @test t.user == "TesterMcTestFace"
t = Template(;
user="invenia",
plugins = [GitHubPages(), TravisCI(), AppVeyor(), CodeCov()], plugins = [GitHubPages(), TravisCI(), AppVeyor(), CodeCov()],
) )
@test Set(keys(t.plugins)) == Set([GitHubPages, TravisCI, AppVeyor, CodeCov]) @test Set(keys(t.plugins)) == Set([GitHubPages, TravisCI, AppVeyor, CodeCov])
@test Set(values(t.plugins)) == Set([GitHubPages(), TravisCI(), AppVeyor(), CodeCov()]) @test Set(values(t.plugins)) == Set([GitHubPages(), TravisCI(), AppVeyor(), CodeCov()])
@test_warn r".*" Template(; @test_warn r".*" Template(;
remote_prefix=invenia_url, user="invenia",
plugins=[TravisCI(), TravisCI()], plugins=[TravisCI(), TravisCI()],
) )
@test_throws ArgumentError Template() @test_throws ArgumentError Template()
@test_throws ArgumentError Template(; remote_prefix=invenia_url, license="FakeLicense") @test_throws ArgumentError Template(; user="invenia", license="FakeLicense")
end end
@testset "Plugin creation" begin @testset "Plugin creation" begin
@ -98,7 +101,7 @@ end
@testset "File generation" begin @testset "File generation" begin
t = Template(; t = Template(;
remote_prefix=invenia_url, user="invenia",
license="MPL", license="MPL",
git_config=git_config, git_config=git_config,
plugins=[TravisCI(), CodeCov(), GitHubPages(), AppVeyor()], plugins=[TravisCI(), CodeCov(), GitHubPages(), AppVeyor()],
@ -116,7 +119,7 @@ end
readme = readchomp(joinpath(temp_dir, "README.md")) readme = readchomp(joinpath(temp_dir, "README.md"))
@test contains(readme, "# $(basename(temp_dir))") @test contains(readme, "# $(basename(temp_dir))")
for p in values(t.plugins) for p in values(t.plugins)
@test contains(readme, join(badges(p, t, basename(temp_dir)), "\n")) @test contains(readme, join(badges(p, t.user, basename(temp_dir)), "\n"))
end end
# Check the order of the badges. # Check the order of the badges.
@test search(readme, "github.io").start < @test search(readme, "github.io").start <
@ -172,7 +175,7 @@ end
end end
@testset "Package generation" begin @testset "Package generation" begin
t = Template(; remote_prefix=invenia_url) t = Template(; user="invenia")
generate("TestPkg", t) generate("TestPkg", t)
@test !isfile(Pkg.dir("TestPkg", "LICENSE")) @test !isfile(Pkg.dir("TestPkg", "LICENSE"))
@test isfile(Pkg.dir("TestPkg", "README.md")) @test isfile(Pkg.dir("TestPkg", "README.md"))
@ -183,15 +186,30 @@ end
@test isdir(Pkg.dir("TestPkg", "test")) @test isdir(Pkg.dir("TestPkg", "test"))
@test isfile(Pkg.dir("TestPkg", "test", "runtests.jl")) @test isfile(Pkg.dir("TestPkg", "test", "runtests.jl"))
repo = LibGit2.GitRepo(Pkg.dir("TestPkg")) repo = LibGit2.GitRepo(Pkg.dir("TestPkg"))
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
branches = [LibGit2.shortname(branch[1]) for branch in LibGit2.GitBranchIter(repo)]
@test LibGit2.getconfig(repo, "user.name", "") == LibGit2.getconfig("user.name", "") @test LibGit2.getconfig(repo, "user.name", "") == LibGit2.getconfig("user.name", "")
branches = [LibGit2.name(branch[1]) for branch in LibGit2.GitBranchIter(repo)] @test LibGit2.url(remote) == "https://github.com/invenia/TestPkg.jl"
@test in("refs/heads/master", branches) @test in("master", branches)
@test !in("refs/heads/gh-pages", branches) @test !in("gh-pages", branches)
@test !LibGit2.isdirty(repo) @test !LibGit2.isdirty(repo)
rm(Pkg.dir("TestPkg"); recursive=true) rm(Pkg.dir("TestPkg"); recursive=true)
generate("TestPkg", t; ssh=true)
repo = LibGit2.GitRepo(Pkg.dir("TestPkg"))
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "git@github.com:invenia/TestPkg.jl.git"
rm(Pkg.dir("TestPkg"); recursive=true)
t = Template(; user="invenia", host="gitlab.com")
generate("TestPkg", t)
repo = LibGit2.GitRepo(Pkg.dir("TestPkg"))
remote = LibGit2.get(LibGit2.GitRemote, repo, "origin")
@test LibGit2.url(remote) == "https://gitlab.com/invenia/TestPkg.jl"
rm(Pkg.dir("TestPkg"); recursive=true)
t = Template(; t = Template(;
remote_prefix=invenia_url, user="invenia",
license="MIT", license="MIT",
git_config=git_config, git_config=git_config,
plugins=[AppVeyor(), GitHubPages(), CodeCov(), TravisCI()], plugins=[AppVeyor(), GitHubPages(), CodeCov(), TravisCI()],
@ -208,8 +226,8 @@ end
@test isfile(Pkg.dir("TestPkg", "docs", "src", "index.md")) @test isfile(Pkg.dir("TestPkg", "docs", "src", "index.md"))
repo = LibGit2.GitRepo(Pkg.dir("TestPkg")) repo = LibGit2.GitRepo(Pkg.dir("TestPkg"))
@test LibGit2.getconfig(repo, "user.name", "") == git_config["user.name"] @test LibGit2.getconfig(repo, "user.name", "") == git_config["user.name"]
branches = [LibGit2.name(branch[1]) for branch in LibGit2.GitBranchIter(repo)] branches = [LibGit2.shortname(branch[1]) for branch in LibGit2.GitBranchIter(repo)]
@test in("refs/heads/gh-pages", branches) @test in("gh-pages", branches)
@test !LibGit2.isdirty(repo) @test !LibGit2.isdirty(repo)
rm(Pkg.dir("TestPkg"); recursive=true) rm(Pkg.dir("TestPkg"); recursive=true)
@ -222,7 +240,7 @@ end
@testset "Plugin generation" begin @testset "Plugin generation" begin
mktempdir() do temp_dir mktempdir() do temp_dir
pkg_dir = joinpath(temp_dir, "TestPkg") pkg_dir = joinpath(temp_dir, "TestPkg")
t = Template(; remote_prefix=invenia_url, path=temp_dir) t = Template(; user="invenia", path=temp_dir)
p = TravisCI() p = TravisCI()
@test gen_plugin(p, t, "TestPkg") == [".travis.yml"] @test gen_plugin(p, t, "TestPkg") == [".travis.yml"]
@ -293,7 +311,7 @@ end
end end
@testset "Mustache substitution" begin @testset "Mustache substitution" begin
t = Template(; remote_prefix=invenia_url) t = Template(; user="invenia")
view = Dict{String, Any}("OTHER" => false) view = Dict{String, Any}("OTHER" => false)
text = substitute(template_text, "TestPkg", t; view=view) text = substitute(template_text, "TestPkg", t; view=view)