diff --git a/src/PkgTemplates.jl b/src/PkgTemplates.jl index 8c9ae6d8..29d06f22 100644 --- a/src/PkgTemplates.jl +++ b/src/PkgTemplates.jl @@ -38,7 +38,8 @@ export SrcDir, TagBot, Tests, - TravisCI + TravisCI, + fixup """ Plugins are PkgTemplates' source of customization and extensibility. @@ -48,10 +49,19 @@ When implementing a new plugin, subtype this type to have full control over its """ abstract type Plugin end +""" + isfixable(::Plugin, pkg_dir) -> Bool + +Determines whether or not the plugin can be updated on an existing project via +[`fixup`](@ref). +""" +isfixable(::Plugin, pkg_dir) = false + include("template.jl") include("plugin.jl") include("show.jl") include("interactive.jl") +include("fixup.jl") include("deprecated.jl") # Run some function with a project activated at the given path. diff --git a/src/fixup.jl b/src/fixup.jl new file mode 100644 index 00000000..78e6dfbb --- /dev/null +++ b/src/fixup.jl @@ -0,0 +1,15 @@ +function fixup(tpl::Template, pkg_dir) + pkg_dir = realpath(pkg_dir) + ispath(pkg_dir) || throw(ArgumentError("Not a directory.")) + isdir(joinpath(pkg_dir, "src")) || throw(ArgumentError("No `src/` directory.")) + + fixable = filter(p -> isfixable(p, pkg_dir), tpl.plugins) + foreach((prehook, hook, posthook)) do h + @info "Running $(nameof(h))s" + foreach(sort(fixable; by=p -> priority(p, h), rev=true)) do p + h(p, tpl, pkg_dir) + end + end + @info "Fixed up package at $pkg_dir" + # TODO: some magic to add badges to an existing Readme?! +end diff --git a/src/plugin.jl b/src/plugin.jl index c6c6eed4..ba2a59a7 100644 --- a/src/plugin.jl +++ b/src/plugin.jl @@ -210,6 +210,17 @@ This function **must** be implemented. """ function destination end +""" + isfixable(p::FilePlugin) -> Bool + +Determines whether or not [`fixup`](@ref) should update the files created by `p`. + +By default, returns `true` if the [`destination(p)`](@ref) file does not exist. +Subtype of [`FilePlugin`](@ref) should implement their own method if they require +different behaviour. +""" +isfixable(p::FilePlugin, pkg_dir) = !isfile(joinpath(pkg_dir, destination(p))) + """ Badge(hover::AbstractString, image::AbstractString, link::AbstractString) diff --git a/src/plugins/documenter.jl b/src/plugins/documenter.jl index 2f321659..359a6660 100644 --- a/src/plugins/documenter.jl +++ b/src/plugins/documenter.jl @@ -161,6 +161,9 @@ function validate(p::Documenter{T}, t::Template) where T <: YesDeploy end end +# Do not edit existing docs. +isfixable(::Documenter, pkg_dir) = !isdir(joinpath(pkg_dir, "docs")) + function hook(p::Documenter, t::Template, pkg_dir::AbstractString) pkg = basename(pkg_dir) docs_dir = joinpath(pkg_dir, "docs") diff --git a/src/plugins/git.jl b/src/plugins/git.jl index 5b235d56..be15f781 100644 --- a/src/plugins/git.jl +++ b/src/plugins/git.jl @@ -54,6 +54,16 @@ function validate(p::Git, t::Template) end end +# fixup only if pkg_dir not a git repo +function isfixable(::Git, pkg_dir) + try + r = GitRepo(pkg_dir) + return !isa(r, GitRepo) + catch + return true + end +end + # Set up the Git repository. function prehook(p::Git, t::Template, pkg_dir::AbstractString) LibGit2.with(LibGit2.init(pkg_dir)) do repo diff --git a/src/plugins/license.jl b/src/plugins/license.jl index 656fb16b..e5bbf248 100644 --- a/src/plugins/license.jl +++ b/src/plugins/license.jl @@ -40,6 +40,10 @@ view(::License, t::Template, ::AbstractString) = Dict( "YEAR" => year(today()), ) +function isfixable(::License, pkg_dir) + return !any(isfile, joinpath.(pkg_dir, ("LICENSE", "LICENSE.md"))) +end + function prompt(::Type{License}, ::Type, ::Val{:name}) options = readdir(default_file("licenses")) # Move MIT to the top. diff --git a/src/plugins/project_file.jl b/src/plugins/project_file.jl index 28efd583..ff78b892 100644 --- a/src/plugins/project_file.jl +++ b/src/plugins/project_file.jl @@ -15,7 +15,9 @@ priority(::ProjectFile, ::typeof(hook)) = typemax(Int) - 5 function hook(p::ProjectFile, t::Template, pkg_dir::AbstractString) toml = Dict( - "name" => basename(pkg_dir), + "name" => let pkg = basename(pkg_dir) + endswith(pkg, ".jl") ? pkg[1:end-3] : pkg + end, "uuid" => string(uuid4()), "authors" => t.authors, "version" => string(p.version), @@ -38,3 +40,7 @@ function compat_version(v::VersionNumber) "$(v.major).$(v.minor).$(v.patch)" end end + +function isfixable(::ProjectFile, pkg_dir) + return !any(isfile, joinpath.(pkg_dir, ("Project.toml", "JuliaProject.toml"))) +end diff --git a/src/plugins/src_dir.jl b/src/plugins/src_dir.jl index e6004e08..41fb2a57 100644 --- a/src/plugins/src_dir.jl +++ b/src/plugins/src_dir.jl @@ -29,3 +29,6 @@ view(::SrcDir, ::Template, pkg::AbstractString) = Dict("PKG" => pkg) function prehook(p::SrcDir, t::Template, pkg_dir::AbstractString) p.destination = joinpath("src", basename(pkg_dir) * ".jl") end + +# TODO: should this return `true` if `src/` exists but `src/pkg_name.jl` doesn't? +isfixable(p::SrcDir, pkg_dir) = false