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.
@ -9,8 +14,15 @@ Generate a package from a template.
# Keyword Arguments
* `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_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)
end
info("Finished configuring git")
url = "$(t.remote_prefix)$pkg_name.jl"
LibGit2.commit(repo, "Empty initial commit")
info("Made initial empty commit")
LibGit2.set_remote_url(repo, url)
info("Set remote origin to $url")
rmt = ssh ? "git@$(t.host):$(t.user)/$pkg_name.jl.git" :
"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.
if haskey(t.plugins, GitHubPages)
@ -89,7 +103,7 @@ function gen_readme(pkg_dir::AbstractString, t::Template)
ordering = [GitHubPages, TravisCI, AppVeyor, CodeCov]
for plugin_type in ordering
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

View File

@ -25,19 +25,18 @@ Add AppVeyor to a template's plugins to add AppVeyor CI support.
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.
# Arguments
* `_::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.
Returns an array of Markdown badges.
"""
function badges(_::AppVeyor, t::Template, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
function badges(_::AppVeyor, user::AbstractString, pkg_name::AbstractString)
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)"
]

View File

@ -30,14 +30,13 @@ end
Generate Markdown badges for the current package.
# Arguments
* `_::CodeCov`: plugin whose badges we are generating.
* `t::Template`: Template configuration options.
* `_::CodeCov`: Plugin whose badges we are generating.
* `user::AbstractString`: GitHub username of the package creator.
* `pkg_name::AbstractString`: Name of the package.
Returns an array of Markdown badges.
"""
function badges(_::CodeCov, t::Template, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
function badges(_::CodeCov, user::AbstractString, pkg_name::AbstractString)
return [
"[![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]"
else
assets = "[]"
assets_string = "[]"
end
user = strip(URI(template.remote_prefix).path, '/')
text = """
using Documenter, $pkg_name
@ -52,7 +51,7 @@ function gen_plugin(plugin::Documenter, template::Template, pkg_name::AbstractSt
pages=[
"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",
authors="$(template.authors)",
assets=$assets_string,

View File

@ -22,19 +22,18 @@ Add GitHubPages to a template's plugins to add Documenter.jl support via GitHub
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.
# Arguments
* `_::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.
Returns an array of Markdown badges.
"""
function badges(_::GitHubPages, t::Template, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
function badges(_::GitHubPages, user::AbstractString, pkg_name::AbstractString)
return [
"[![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)"
@ -61,14 +60,13 @@ function gen_plugin(plugin::GitHubPages, template::Template, pkg_name::AbstractS
)
if haskey(template.plugins, TravisCI)
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
write(
file,
"""
deploydocs(
repo="github.com/$user/$pkg_name.jl",
repo="github.com/$(template.user)/$pkg_name.jl",
target="build",
julia="0.6",
deps=nothing,

View File

@ -25,21 +25,20 @@ Add TravisCI to a template's plugins to add Travis CI support.
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.
# Arguments
* `_::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.
Returns an array of Markdown badges.
"""
function badges(_::TravisCI, t::Template, pkg_name::AbstractString)
user = strip(URI(t.remote_prefix).path, '/')
function badges(_::TravisCI, user::AbstractString, pkg_name::AbstractString)
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)"
]
end

View File

@ -4,11 +4,11 @@
Records common information used to generate a package.
# Keyword Arguments
* `remote_prefix::AbstractString`: The base url for the remote repository. e.g.
"https://github.com/username/". This will be used with the package name to set the url
for the remote repository, as well as to determine the account's username. Failing to
specify this will cause an error. This is case-sensitive for some plugins, so take care
to enter it correctly.
* `user::AbstractString=LibGit2.getconfig("github.username", "")`: GitHub username.
If left as default and there is no value configured, an error will be thrown.
Alternatively, you can add a value to `git_config["github.username"]` to set your
username. This is case-sensitive for some plugins, so take care 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
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.
@ -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.
"""
@auto_hash_equals struct Template
remote_prefix::AbstractString
user::AbstractString
host::AbstractString
license::Union{AbstractString, Void}
authors::Union{AbstractString, Array}
years::AbstractString
@ -31,8 +32,9 @@ Records common information used to generate a package.
git_config::Dict{String, String}
plugins::Dict{DataType, Plugin}
function Template{P <: Plugin}(;
remote_prefix::AbstractString="",
function Template(;
user::AbstractString=LibGit2.getconfig("github.username", ""),
host::AbstractString="https://github.com",
license::Union{AbstractString, Void}=nothing,
authors::Union{AbstractString, Array}=LibGit2.getconfig("user.name", ""),
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,
git_config::Dict{String, String}=Dict{String, String}(),
plugins::Vector{P}=Vector{Plugin}(),
)
if isempty(remote_prefix)
throw(ArgumentError("Must specify remote_prefix::AbstractString"))
) where P <: Plugin
# If no username was set or found, look for one in the supplied git config.
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
years = string(years)
# 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.
@ -53,13 +64,8 @@ Records common information used to generate a package.
elseif isa(authors, Array)
authors = join(authors, ", ")
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)
if (length(plugins) != length(plugin_dict))
@ -67,8 +73,8 @@ Records common information used to generate a package.
end
new(
remote_prefix, license, authors, years, path,
julia_version, git_config, plugin_dict,
user, host, license, authors, years, path,
julia_version, git_config, plugin_dict
)
end
end

View File

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