diff --git a/src/generate.jl b/src/generate.jl index 0610df1..fec6a79 100644 --- a/src/generate.jl +++ b/src/generate.jl @@ -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 diff --git a/src/plugins/appveyor.jl b/src/plugins/appveyor.jl index 088676e..6dab3b4 100644 --- a/src/plugins/appveyor.jl +++ b/src/plugins/appveyor.jl @@ -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)" ] diff --git a/src/plugins/codecov.jl b/src/plugins/codecov.jl index c798d32..381f1c8 100644 --- a/src/plugins/codecov.jl +++ b/src/plugins/codecov.jl @@ -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)" ] diff --git a/src/plugins/documenter.jl b/src/plugins/documenter.jl index a86dd6c..69e0669 100644 --- a/src/plugins/documenter.jl +++ b/src/plugins/documenter.jl @@ -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, diff --git a/src/plugins/githubpages.jl b/src/plugins/githubpages.jl index 7c51d9f..f5f9891 100644 --- a/src/plugins/githubpages.jl +++ b/src/plugins/githubpages.jl @@ -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, diff --git a/src/plugins/travis.jl b/src/plugins/travis.jl index b48c406..5fb9aeb 100644 --- a/src/plugins/travis.jl +++ b/src/plugins/travis.jl @@ -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 diff --git a/src/template.jl b/src/template.jl index 86f65b2..d7f4e53 100644 --- a/src/template.jl +++ b/src/template.jl @@ -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 diff --git a/test/tests.jl b/test/tests.jl index defa19d..dfd8998 100644 --- a/test/tests.jl +++ b/test/tests.jl @@ -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)