From 5a8050e922d8bf730a74a27ad08b47e630f2cfdf Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 17:24:50 -0500 Subject: [PATCH 01/10] Split default template into multiple templates. Simplify interface. --- Project.toml | 2 + src/ITensorPkgSkeleton.jl | 174 ++++++++++++++---- .../benchmark/benchmarks.jl | 0 templates/{default => docs}/docs/Project.toml | 0 templates/{default => docs}/docs/make.jl | 0 .../{default => docs}/docs/make_index.jl | 0 .../.github/workflows/Downstream.yml | 0 .../examples/Project.toml | 0 .../{default => examples}/examples/README.jl | 0 .../.JuliaFormatter.toml | 0 .../.github/ISSUE_TEMPLATE/BUG_REPORT.md | 0 .../.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 0 .../.github/PULL_REQUEST_TEMPLATE.md | 0 .../.github/dependabot.yml | 0 .../.github/workflows/CI.yml | 0 .../.github/workflows/CompatHelper.yml | 0 .../.github/workflows/FormatCheck.yml | 0 .../.github/workflows/LiterateCheck.yml | 0 .../.github/workflows/Register.yml | 0 .../.github/workflows/TagBot.yml | 0 templates/{default => gitignore}/.gitignore | 0 templates/{default => license}/LICENSE | 2 +- .../.pre-commit-config.yaml | 0 templates/{default => readme}/README.md | 0 templates/{default => readme}/make_readme.jl | 0 templates/{default => src}/Project.toml | 0 templates/{default => src}/src/{PKGNAME}.jl | 0 templates/{default => test}/test/Project.toml | 0 templates/{default => test}/test/runtests.jl | 0 templates/{default => test}/test/test_aqua.jl | 0 .../{default => test}/test/test_basics.jl | 0 .../{default => test}/test/test_examples.jl | 0 test/test_basics.jl | 16 +- 33 files changed, 147 insertions(+), 47 deletions(-) rename templates/{default => benchmark}/benchmark/benchmarks.jl (100%) rename templates/{default => docs}/docs/Project.toml (100%) rename templates/{default => docs}/docs/make.jl (100%) rename templates/{default => docs}/docs/make_index.jl (100%) rename templates/{downstream => downstreampkgs}/.github/workflows/Downstream.yml (100%) rename templates/{default => examples}/examples/Project.toml (100%) rename templates/{default => examples}/examples/README.jl (100%) rename templates/{default => formatter}/.JuliaFormatter.toml (100%) rename templates/{default => github}/.github/ISSUE_TEMPLATE/BUG_REPORT.md (100%) rename templates/{default => github}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md (100%) rename templates/{default => github}/.github/PULL_REQUEST_TEMPLATE.md (100%) rename templates/{default => github}/.github/dependabot.yml (100%) rename templates/{default => github}/.github/workflows/CI.yml (100%) rename templates/{default => github}/.github/workflows/CompatHelper.yml (100%) rename templates/{default => github}/.github/workflows/FormatCheck.yml (100%) rename templates/{default => github}/.github/workflows/LiterateCheck.yml (100%) rename templates/{default => github}/.github/workflows/Register.yml (100%) rename templates/{default => github}/.github/workflows/TagBot.yml (100%) rename templates/{default => gitignore}/.gitignore (100%) rename templates/{default => license}/LICENSE (92%) rename templates/{default => precommit}/.pre-commit-config.yaml (100%) rename templates/{default => readme}/README.md (100%) rename templates/{default => readme}/make_readme.jl (100%) rename templates/{default => src}/Project.toml (100%) rename templates/{default => src}/src/{PKGNAME}.jl (100%) rename templates/{default => test}/test/Project.toml (100%) rename templates/{default => test}/test/runtests.jl (100%) rename templates/{default => test}/test/test_aqua.jl (100%) rename templates/{default => test}/test/test_basics.jl (100%) rename templates/{default => test}/test/test_examples.jl (100%) diff --git a/Project.toml b/Project.toml index 7374470..b4efaa7 100644 --- a/Project.toml +++ b/Project.toml @@ -4,6 +4,7 @@ authors = ["ITensor developers and contributors"] version = "0.1.0" [deps] +DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" Git = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" Git_jll = "f8c6e375-362e-5223-8a59-34ff63f689eb" LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433" @@ -12,6 +13,7 @@ Preferences = "21216c6a-2e73-6563-6e65-726566657250" [compat] Aqua = "0.8.9" +DocStringExtensions = "0.9.3" Git = "1.3.1" Git_jll = "2.46.2" LibGit2 = "1.10" diff --git a/src/ITensorPkgSkeleton.jl b/src/ITensorPkgSkeleton.jl index d4dcaa1..5ce5547 100644 --- a/src/ITensorPkgSkeleton.jl +++ b/src/ITensorPkgSkeleton.jl @@ -1,5 +1,10 @@ module ITensorPkgSkeleton +## @static if Base.VERSION >= v"1.11.0-DEV.469" +## public generate +## end + +using DocStringExtensions: SIGNATURES using Git: git using LibGit2: LibGit2 using PkgSkeleton: PkgSkeleton @@ -37,56 +42,77 @@ function default_branch_name() end function change_branch_name(path, branch_name) - original_dir = pwd() - cd(path) - original_branch_name = readchomp(`$(git()) branch --show-current`) - run(`$(git()) branch -m $original_branch_name $branch_name`) - cd(original_dir) + cd(path) do + original_branch_name = readchomp(`$(git()) branch --show-current`) + run(`$(git()) branch -m $original_branch_name $branch_name`) + return nothing + end return nothing end -function default_path() - # TODO: Use something like `joinpath(first(DEPOT_PATH), "dev", pkg_name)` - # to make it more general. - return joinpath(homedir(), ".julia", "dev") +function set_remote_url(path, pkgname, ghuser) + url = "git@github.com:$ghuser/$pkgname.jl.git" + cd(joinpath(path, pkgname)) do + try + run(`$(git()) ls-remote -h "$url" HEAD $("&>") /dev/null`) + run(`$(git()) add origin $url`) + catch + end + return nothing + end + return nothing end -default_templates() = ["default"] +# https://pkgdocs.julialang.org/v1/api/#Pkg.develop +function default_path() + return joinpath(DEPOT_PATH[1], "dev") +end -default_user() = "ITensor" +default_ghuser() = "ITensor" +default_username() = "ITensor developers" +default_usermail() = "support@itensor.org" function default_user_replacements() - return ( - GHUSER=default_user(), USERNAME="ITensor developers", USEREMAIL="support@itensor.org" - ) + return (ghuser=default_ghuser(), username=default_username(), usermail=default_usermail()) +end + +# See: +# https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664 +# https://github.com/JuliaLang/julia/pull/55270 +# https://github.com/JuliaLang/julia/issues/34772 +function delete(nt::NamedTuple{names}, key::Symbol) where {names} + return NamedTuple{filter(≠(key), names)}(nt) end #= This processes inputs like: ```julia -ITensorPkgSkeleton.generate("NewPkg"; user_replacements=(DOWNSTREAMPKGS=("ITensors",))) -ITensorPkgSkeleton.generate("NewPkg"; user_replacements=(DOWNSTREAMPKGS=(repo="ITensors",))) -ITensorPkgSkeleton.generate("NewPkg"; user_replacements=(DOWNSTREAMPKGS=(user="ITensor", repo="ITensors",))) +ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=["ITensors"]) +ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=[(ghuser="ITensor", repo="ITensors")]) ``` =# -function format_downstream_pkgs(user_replacements) - if !haskey(user_replacements, :DOWNSTREAMPKGS) +function format_downstreampkgs(user_replacements) + if !haskey(user_replacements, :downstreampkgs) return user_replacements end - DOWNSTREAMPKGS = "" - for user_repo in user_replacements.DOWNSTREAMPKGS - user, repo = if user_repo isa AbstractString + if isempty(user_replacements.downstreampkgs) + return delete(user_replacements, :downstreampkgs) + end + downstreampkgs = "" + for ghuser_and_or_repo in user_replacements.downstreampkgs + ghuser, repo = if ghuser_and_or_repo isa AbstractString # Only the repo was passed as a standalone value. - default_user(), user_repo + default_ghuser(), ghuser_and_or_repo else # The user and repo were passed in a NamedTuple, # or just the repo was passed in a NamedTuple. - get(user_repo, :user, default_user()), user_repo.repo + get(ghuser_and_or_repo, :user, default_ghuser()), ghuser_and_or_repo.repo end - DOWNSTREAMPKGS *= " - {user: $(user), repo: $(repo).jl}\n" + downstreampkgs *= " - {user: $(ghuser), repo: $(repo).jl}\n" end - DOWNSTREAMPKGS = chop(DOWNSTREAMPKGS) - return merge(user_replacements, (; DOWNSTREAMPKGS)) + # Remove extraneous trailing newline character. + downstreampkgs = chop(downstreampkgs) + return merge(user_replacements, (; downstreampkgs)) end function set_default_template_path(template) @@ -103,23 +129,99 @@ function is_git_repo(path) end end +function all_templates() + return [ + "benchmark", + "docs", + "examples", + "formatter", + "github", + "gitignore", + "license", + "precommit", + "readme", + "src", + "test", + ] +end + +default_templates() = all_templates() + +function to_pkgskeleton(user_replacements) + return Dict(uppercase.(string.(keys(user_replacements))) .=> values(user_replacements)) +end + +""" +$(SIGNATURES) + +!!! warning + This function might overwrite existing code if you specify a path to a package that already exists, use with caution! See [`PkgSkeleton.jl`](https://github.com/tpapp/PkgSkeleton.jl) for more details. If you are updating an existing package, make sure you save everything you want to keep (for example, commit all of your changes if it is a git repository). + +Generate a package template for a package, by default in the ITensor organization, or update an existing package. This is a wrapper around [`PkgSkeleton.generate`](https://github.com/tpapp/PkgSkeleton.jl) but with extra functionality, custom templates used in the ITensor organization, and defaults biased towards creating a package in the ITensor organization. + +# Examples + +```jldoctest +julia> using ITensorPkgSkeleton: ITensorPkgSkeleton; + +julia> ITensorPkgSkeleton.generate("NewPkg"); + +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mkdtempdir()); + +julia> ITensorPkgSkeleton.generate("NewPkg"; templates=ITensorPkgSkeleton.all_templates()); + +julia> ITensorPkgSkeleton.generate("NewPkg"; templates=["github"]); + +julia> ITensorPkgSkeleton.generate("NewPkg"; templates=["src", "github"]); + +julia> ITensorPkgSkeleton.generate("NewPkg"; ignore_templates=["src", "github"]); + +julia> ITensorPkgSkeleton.generate("NewPkg"; ghuser="MyOrg"); + +julia> ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=["ITensors", "ITensorMPS"]); + +julia> ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=[(user="ITensor", repo="ITensors")]); +``` + +# Arguments + +- `pkgname::AbstractString`: Name of the package (without the `.jl` extension). Replaces `{PKGNAME}` in the template. + +# Keywords + +- `path::AbstractString`: Path where the package will be generated. Defaults to the [development directory](https://pkgdocs.julialang.org/v1/api/#Pkg.develop), i.e. `$(default_path())`. +- `templates`: A list of templates to use. Select a subset of `$(all_templates())`. Defaults to `$(default_templates())`. +- `ignore_templates`: A list of templates to ignore. This is the same as setting `templates=setdiff(templates, ignore_templates)`. +- `downstreampkgs`: Specify the downstream packages that depend on this package. Setting this will create a workflow where the downstream tests will be run alongside the tests for this package in Github Actions to ensure that changes to your package don't break the specified downstream packages. Specify it as a list of packages, for example `["DownstreamPkg1", "DownstreamPkg2"]`, which assumes the packages are in the `$(default_ghuser())` organization. Alternatively, specify the organization with `[(user="Org1", repo="DownstreamPkg1"), (user="Org2", repo="DownstreamPkg2")]`; . Defaults to an empty list. +- `uuid`: Replaces `{UUID}` in the template. Defaults to the existing UUID in the `Project.toml` if the path points to an existing package, otherwise generates one randomly with `UUIDs.uuid4()`. +- `year`: Replaces `{YEAR}` in the template. Year the package/repository was created. Defaults to the current year. +""" function generate( - pkg_name; path=default_path(), templates=default_templates(), user_replacements=(;) + pkgname; + path=default_path(), + templates=default_templates(), + ignore_templates=[], + user_replacements..., ) - # Set default values. + pkgpath = joinpath(path, pkgname) user_replacements = merge(default_user_replacements(), user_replacements) + # Process downstream package information. + user_replacements = format_downstreampkgs(user_replacements) + templates = setdiff(templates, ignore_templates) + # Set default values. + if haskey(user_replacements, :downstreampkgs) + templates = [templates; "downstreampkgs"] + end # Fill in default path if missing. templates = set_default_template_path.(templates) - # Process downstream package information. - user_replacements = format_downstream_pkgs(user_replacements) - pkg_path = joinpath(path, pkg_name) - is_new_repo = !is_git_repo(pkg_path) + is_new_repo = !is_git_repo(pkgpath) branch_name = default_branch_name() - user_replacements_dict = Dict(keys(user_replacements) .=> values(user_replacements)) - PkgSkeleton.generate(pkg_path; templates, user_replacements=user_replacements_dict) + user_replacements_pkgskeleton = to_pkgskeleton(user_replacements) + PkgSkeleton.generate(pkgpath; templates, user_replacements=user_replacements_pkgskeleton) if is_new_repo # Change the default branch if this is a new repository. - change_branch_name(pkg_path, branch_name) + change_branch_name(pkgpath, branch_name) + set_remote_url(path, pkgname, user_replacements.ghuser) end return nothing end diff --git a/templates/default/benchmark/benchmarks.jl b/templates/benchmark/benchmark/benchmarks.jl similarity index 100% rename from templates/default/benchmark/benchmarks.jl rename to templates/benchmark/benchmark/benchmarks.jl diff --git a/templates/default/docs/Project.toml b/templates/docs/docs/Project.toml similarity index 100% rename from templates/default/docs/Project.toml rename to templates/docs/docs/Project.toml diff --git a/templates/default/docs/make.jl b/templates/docs/docs/make.jl similarity index 100% rename from templates/default/docs/make.jl rename to templates/docs/docs/make.jl diff --git a/templates/default/docs/make_index.jl b/templates/docs/docs/make_index.jl similarity index 100% rename from templates/default/docs/make_index.jl rename to templates/docs/docs/make_index.jl diff --git a/templates/downstream/.github/workflows/Downstream.yml b/templates/downstreampkgs/.github/workflows/Downstream.yml similarity index 100% rename from templates/downstream/.github/workflows/Downstream.yml rename to templates/downstreampkgs/.github/workflows/Downstream.yml diff --git a/templates/default/examples/Project.toml b/templates/examples/examples/Project.toml similarity index 100% rename from templates/default/examples/Project.toml rename to templates/examples/examples/Project.toml diff --git a/templates/default/examples/README.jl b/templates/examples/examples/README.jl similarity index 100% rename from templates/default/examples/README.jl rename to templates/examples/examples/README.jl diff --git a/templates/default/.JuliaFormatter.toml b/templates/formatter/.JuliaFormatter.toml similarity index 100% rename from templates/default/.JuliaFormatter.toml rename to templates/formatter/.JuliaFormatter.toml diff --git a/templates/default/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/templates/github/.github/ISSUE_TEMPLATE/BUG_REPORT.md similarity index 100% rename from templates/default/.github/ISSUE_TEMPLATE/BUG_REPORT.md rename to templates/github/.github/ISSUE_TEMPLATE/BUG_REPORT.md diff --git a/templates/default/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/templates/github/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md similarity index 100% rename from templates/default/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md rename to templates/github/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md diff --git a/templates/default/.github/PULL_REQUEST_TEMPLATE.md b/templates/github/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from templates/default/.github/PULL_REQUEST_TEMPLATE.md rename to templates/github/.github/PULL_REQUEST_TEMPLATE.md diff --git a/templates/default/.github/dependabot.yml b/templates/github/.github/dependabot.yml similarity index 100% rename from templates/default/.github/dependabot.yml rename to templates/github/.github/dependabot.yml diff --git a/templates/default/.github/workflows/CI.yml b/templates/github/.github/workflows/CI.yml similarity index 100% rename from templates/default/.github/workflows/CI.yml rename to templates/github/.github/workflows/CI.yml diff --git a/templates/default/.github/workflows/CompatHelper.yml b/templates/github/.github/workflows/CompatHelper.yml similarity index 100% rename from templates/default/.github/workflows/CompatHelper.yml rename to templates/github/.github/workflows/CompatHelper.yml diff --git a/templates/default/.github/workflows/FormatCheck.yml b/templates/github/.github/workflows/FormatCheck.yml similarity index 100% rename from templates/default/.github/workflows/FormatCheck.yml rename to templates/github/.github/workflows/FormatCheck.yml diff --git a/templates/default/.github/workflows/LiterateCheck.yml b/templates/github/.github/workflows/LiterateCheck.yml similarity index 100% rename from templates/default/.github/workflows/LiterateCheck.yml rename to templates/github/.github/workflows/LiterateCheck.yml diff --git a/templates/default/.github/workflows/Register.yml b/templates/github/.github/workflows/Register.yml similarity index 100% rename from templates/default/.github/workflows/Register.yml rename to templates/github/.github/workflows/Register.yml diff --git a/templates/default/.github/workflows/TagBot.yml b/templates/github/.github/workflows/TagBot.yml similarity index 100% rename from templates/default/.github/workflows/TagBot.yml rename to templates/github/.github/workflows/TagBot.yml diff --git a/templates/default/.gitignore b/templates/gitignore/.gitignore similarity index 100% rename from templates/default/.gitignore rename to templates/gitignore/.gitignore diff --git a/templates/default/LICENSE b/templates/license/LICENSE similarity index 92% rename from templates/default/LICENSE rename to templates/license/LICENSE index c931e76..cbe94c1 100644 --- a/templates/default/LICENSE +++ b/templates/license/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 ITensor developers and contributors +Copyright (c) {YEAR} ITensor developers and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/templates/default/.pre-commit-config.yaml b/templates/precommit/.pre-commit-config.yaml similarity index 100% rename from templates/default/.pre-commit-config.yaml rename to templates/precommit/.pre-commit-config.yaml diff --git a/templates/default/README.md b/templates/readme/README.md similarity index 100% rename from templates/default/README.md rename to templates/readme/README.md diff --git a/templates/default/make_readme.jl b/templates/readme/make_readme.jl similarity index 100% rename from templates/default/make_readme.jl rename to templates/readme/make_readme.jl diff --git a/templates/default/Project.toml b/templates/src/Project.toml similarity index 100% rename from templates/default/Project.toml rename to templates/src/Project.toml diff --git a/templates/default/src/{PKGNAME}.jl b/templates/src/src/{PKGNAME}.jl similarity index 100% rename from templates/default/src/{PKGNAME}.jl rename to templates/src/src/{PKGNAME}.jl diff --git a/templates/default/test/Project.toml b/templates/test/test/Project.toml similarity index 100% rename from templates/default/test/Project.toml rename to templates/test/test/Project.toml diff --git a/templates/default/test/runtests.jl b/templates/test/test/runtests.jl similarity index 100% rename from templates/default/test/runtests.jl rename to templates/test/test/runtests.jl diff --git a/templates/default/test/test_aqua.jl b/templates/test/test/test_aqua.jl similarity index 100% rename from templates/default/test/test_aqua.jl rename to templates/test/test/test_aqua.jl diff --git a/templates/default/test/test_basics.jl b/templates/test/test/test_basics.jl similarity index 100% rename from templates/default/test/test_basics.jl rename to templates/test/test/test_basics.jl diff --git a/templates/default/test/test_examples.jl b/templates/test/test/test_examples.jl similarity index 100% rename from templates/default/test/test_examples.jl rename to templates/test/test/test_examples.jl diff --git a/test/test_basics.jl b/test/test_basics.jl index 1b9e412..a7dcce5 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -22,15 +22,10 @@ using Test: @test, @testset end end @testset "generate with downstream tests" begin - for templates in (["downstream"], ["default", "downstream"]) - for DOWNSTREAMPKGS in ( - ("DownstreamPkg",), (repo="DownstreamPkg",), (user="ITensor", repo="DownstreamPkg") - ) + for templates in (ITensorPkgSkeleton.default_templates(), []) + for downstreampkgs in (["DownstreamPkg"], [(user="ITensor", repo="DownstreamPkg")]) path = mktempdir() - templates = ["default", "downstream"] - ITensorPkgSkeleton.generate( - "NewPkg"; path, templates, user_replacements=(; DOWNSTREAMPKGS) - ) + ITensorPkgSkeleton.generate("NewPkg"; path, templates, downstreampkgs) @test isdir(joinpath(path, "NewPkg")) @test isdir(joinpath(path, "NewPkg", ".github", "workflows")) @test isfile(joinpath(path, "NewPkg", ".github", "workflows", "Downstream.yml")) @@ -39,8 +34,9 @@ using Test: @test, @testset ) do io return contains(read(io, String), "- {user: ITensor, repo: DownstreamPkg.jl}") end - for dir in pkgdirs - @test isdir(joinpath(path, "NewPkg", dir)) == ("default" in templates) + @show templates + for dir in setdiff(pkgdirs, [".github", ".github/workflows"]) + @test isdir(joinpath(path, "NewPkg", dir)) == !isempty(templates) end end end From b0749aceff2ae3e54e30263dfe1bb1fd29846cee Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 17:38:30 -0500 Subject: [PATCH 02/10] Declare public, better docs --- src/ITensorPkgSkeleton.jl | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/ITensorPkgSkeleton.jl b/src/ITensorPkgSkeleton.jl index 5ce5547..c3776d7 100644 --- a/src/ITensorPkgSkeleton.jl +++ b/src/ITensorPkgSkeleton.jl @@ -1,8 +1,11 @@ module ITensorPkgSkeleton -## @static if Base.VERSION >= v"1.11.0-DEV.469" -## public generate -## end +# Declare `ITensorPkgSkeleton.generate` as public in a +# backwards-compatible way. +# See: https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041 +if VERSION >= v"1.11.0-DEV.469" + eval(Meta.parse("public all_templates, default_templates, generate")) +end using DocStringExtensions: SIGNATURES using Git: git @@ -129,6 +132,11 @@ function is_git_repo(path) end end +""" +$(SIGNATURES) + +All available templates when constructing a package. Includes the following templates: $(all_templates()) +""" function all_templates() return [ "benchmark", @@ -145,6 +153,11 @@ function all_templates() ] end +""" +$(SIGNATURES) + +Default templates when constructing a package. Includes the following templates: $(default_templates()) +""" default_templates() = all_templates() function to_pkgskeleton(user_replacements) @@ -168,7 +181,7 @@ julia> ITensorPkgSkeleton.generate("NewPkg"); julia> ITensorPkgSkeleton.generate("NewPkg"; path=mkdtempdir()); -julia> ITensorPkgSkeleton.generate("NewPkg"; templates=ITensorPkgSkeleton.all_templates()); +julia> ITensorPkgSkeleton.generate("NewPkg"; templates=ITensorPkgSkeleton.default_templates()); julia> ITensorPkgSkeleton.generate("NewPkg"; templates=["github"]); @@ -190,7 +203,7 @@ julia> ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=[(user="ITensor", re # Keywords - `path::AbstractString`: Path where the package will be generated. Defaults to the [development directory](https://pkgdocs.julialang.org/v1/api/#Pkg.develop), i.e. `$(default_path())`. -- `templates`: A list of templates to use. Select a subset of `$(all_templates())`. Defaults to `$(default_templates())`. +- `templates`: A list of templates to use. Select a subset of `ITensorPkgSkeleton.all_templates() = $(all_templates())`. Defaults to `ITensorPkgSkeleton.default_templates() = $(default_templates())`. - `ignore_templates`: A list of templates to ignore. This is the same as setting `templates=setdiff(templates, ignore_templates)`. - `downstreampkgs`: Specify the downstream packages that depend on this package. Setting this will create a workflow where the downstream tests will be run alongside the tests for this package in Github Actions to ensure that changes to your package don't break the specified downstream packages. Specify it as a list of packages, for example `["DownstreamPkg1", "DownstreamPkg2"]`, which assumes the packages are in the `$(default_ghuser())` organization. Alternatively, specify the organization with `[(user="Org1", repo="DownstreamPkg1"), (user="Org2", repo="DownstreamPkg2")]`; . Defaults to an empty list. - `uuid`: Replaces `{UUID}` in the template. Defaults to the existing UUID in the `Project.toml` if the path points to an existing package, otherwise generates one randomly with `UUIDs.uuid4()`. From 737e16d99f3f337a1e19dfc41cabef41aa856936 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 17:45:27 -0500 Subject: [PATCH 03/10] Fix typo --- examples/Project.toml | 1 + src/ITensorPkgSkeleton.jl | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/Project.toml b/examples/Project.toml index 668a5cb..2f9e3f0 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -1,2 +1,3 @@ [deps] +Git_jll = "f8c6e375-362e-5223-8a59-34ff63f689eb" ITensorPkgSkeleton = "3d388ab1-018a-49f4-ae50-18094d5f71ea" diff --git a/src/ITensorPkgSkeleton.jl b/src/ITensorPkgSkeleton.jl index c3776d7..8b172bb 100644 --- a/src/ITensorPkgSkeleton.jl +++ b/src/ITensorPkgSkeleton.jl @@ -73,10 +73,10 @@ end default_ghuser() = "ITensor" default_username() = "ITensor developers" -default_usermail() = "support@itensor.org" +default_useremail() = "support@itensor.org" function default_user_replacements() - return (ghuser=default_ghuser(), username=default_username(), usermail=default_usermail()) + return (ghuser=default_ghuser(), username=default_username(), useremail=default_useremail()) end # See: @@ -230,6 +230,9 @@ function generate( is_new_repo = !is_git_repo(pkgpath) branch_name = default_branch_name() user_replacements_pkgskeleton = to_pkgskeleton(user_replacements) + + @show user_replacements_pkgskeleton + PkgSkeleton.generate(pkgpath; templates, user_replacements=user_replacements_pkgskeleton) if is_new_repo # Change the default branch if this is a new repository. From d6d41c0cd365eba19d58aee6153213e811c30b9a Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 17:46:07 -0500 Subject: [PATCH 04/10] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f16e612..4b432fc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ Manifest.toml benchmark/*.json docs/build/ +examples/LocalPreferences.toml test/LocalPreferences.toml From 360c953d74ac7168f7516c434ad5b3d7c4f29a46 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 18:55:33 -0500 Subject: [PATCH 05/10] Try fixing tests --- Project.toml | 2 ++ src/ITensorPkgSkeleton.jl | 34 +++++++++++++++++++--------------- test/test_basics.jl | 1 - 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Project.toml b/Project.toml index b4efaa7..30b5fef 100644 --- a/Project.toml +++ b/Project.toml @@ -10,6 +10,7 @@ Git_jll = "f8c6e375-362e-5223-8a59-34ff63f689eb" LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433" PkgSkeleton = "d254efa0-af53-535e-b7f1-03c1c9fbcbe7" Preferences = "21216c6a-2e73-6563-6e65-726566657250" +Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" [compat] Aqua = "0.8.9" @@ -19,6 +20,7 @@ Git_jll = "2.46.2" LibGit2 = "1.10" PkgSkeleton = "1.3.1" Preferences = "1.4.3" +Suppressor = "0.2.8" Test = "1.10" julia = "1.10" diff --git a/src/ITensorPkgSkeleton.jl b/src/ITensorPkgSkeleton.jl index 8b172bb..1e43947 100644 --- a/src/ITensorPkgSkeleton.jl +++ b/src/ITensorPkgSkeleton.jl @@ -12,6 +12,7 @@ using Git: git using LibGit2: LibGit2 using PkgSkeleton: PkgSkeleton using Preferences: Preferences +using Suppressor: @suppress # Configure `Git.jl`/`Git_jll.jl` to # use the local installation of git. @@ -57,8 +58,10 @@ function set_remote_url(path, pkgname, ghuser) url = "git@github.com:$ghuser/$pkgname.jl.git" cd(joinpath(path, pkgname)) do try - run(`$(git()) ls-remote -h "$url" HEAD $("&>") /dev/null`) - run(`$(git()) add origin $url`) + @suppress begin + run(`$(git()) ls-remote -h "$url" HEAD $("&>") /dev/null`) + run(`$(git()) add origin $url`) + end catch end return nothing @@ -76,7 +79,9 @@ default_username() = "ITensor developers" default_useremail() = "support@itensor.org" function default_user_replacements() - return (ghuser=default_ghuser(), username=default_username(), useremail=default_useremail()) + return ( + ghuser=default_ghuser(), username=default_username(), useremail=default_useremail() + ) end # See: @@ -179,21 +184,21 @@ julia> using ITensorPkgSkeleton: ITensorPkgSkeleton; julia> ITensorPkgSkeleton.generate("NewPkg"); -julia> ITensorPkgSkeleton.generate("NewPkg"; path=mkdtempdir()); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir()); -julia> ITensorPkgSkeleton.generate("NewPkg"; templates=ITensorPkgSkeleton.default_templates()); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), templates=ITensorPkgSkeleton.default_templates()); -julia> ITensorPkgSkeleton.generate("NewPkg"; templates=["github"]); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), templates=["github"]); -julia> ITensorPkgSkeleton.generate("NewPkg"; templates=["src", "github"]); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), templates=["src", "github"]); -julia> ITensorPkgSkeleton.generate("NewPkg"; ignore_templates=["src", "github"]); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), ignore_templates=["src", "github"]); -julia> ITensorPkgSkeleton.generate("NewPkg"; ghuser="MyOrg"); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), ghuser="MyOrg"); -julia> ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=["ITensors", "ITensorMPS"]); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), downstreampkgs=["ITensors", "ITensorMPS"]); -julia> ITensorPkgSkeleton.generate("NewPkg"; downstreampkgs=[(user="ITensor", repo="ITensors")]); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir(), downstreampkgs=[(user="ITensor", repo="ITensors")]); ``` # Arguments @@ -230,10 +235,9 @@ function generate( is_new_repo = !is_git_repo(pkgpath) branch_name = default_branch_name() user_replacements_pkgskeleton = to_pkgskeleton(user_replacements) - - @show user_replacements_pkgskeleton - - PkgSkeleton.generate(pkgpath; templates, user_replacements=user_replacements_pkgskeleton) + @suppress PkgSkeleton.generate( + pkgpath; templates, user_replacements=user_replacements_pkgskeleton + ) if is_new_repo # Change the default branch if this is a new repository. change_branch_name(pkgpath, branch_name) diff --git a/test/test_basics.jl b/test/test_basics.jl index a7dcce5..8506b88 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -34,7 +34,6 @@ using Test: @test, @testset ) do io return contains(read(io, String), "- {user: ITensor, repo: DownstreamPkg.jl}") end - @show templates for dir in setdiff(pkgdirs, [".github", ".github/workflows"]) @test isdir(joinpath(path, "NewPkg", dir)) == !isempty(templates) end From 3464783f1e639c00da478ddaea1f6c2238c9dfdd Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 19:23:24 -0500 Subject: [PATCH 06/10] Include docstrings in docs --- docs/make.jl | 2 +- docs/src/reference.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/src/reference.md diff --git a/docs/make.jl b/docs/make.jl index 082855d..6f45e66 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -16,7 +16,7 @@ makedocs(; edit_link="main", assets=String[], ), - pages=["Home" => "index.md"], + pages=["Home" => "index.md", "Reference" => "reference.md"], ) deploydocs(; diff --git a/docs/src/reference.md b/docs/src/reference.md new file mode 100644 index 0000000..d6943b3 --- /dev/null +++ b/docs/src/reference.md @@ -0,0 +1,6 @@ +## Reference + +```@autodocs +Modules = [ITensorPkgSkeleton] +Order = [:constant] +``` From e3cee77b877108c5666860db56cbc61196c2f756 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 19:34:42 -0500 Subject: [PATCH 07/10] Try fixing docs --- docs/src/reference.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/src/reference.md b/docs/src/reference.md index d6943b3..98dea6f 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -1,6 +1,7 @@ ## Reference -```@autodocs -Modules = [ITensorPkgSkeleton] -Order = [:constant] +```@docs +ITensorPkgSkeleton.generate +ITensorPkgSkeleton.default_templates +ITensorPkgSkeleton.all_templates ``` From b71c78bb7be7c2187c122a9a96a51c88707527aa Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 19:35:21 -0500 Subject: [PATCH 08/10] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4b432fc..3bcefaa 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,6 @@ Manifest.toml benchmark/*.json docs/build/ +docs/LocalPreferences.toml examples/LocalPreferences.toml test/LocalPreferences.toml From a974aedd2c46aa349f35ed36b9b38f2a40d9f5c6 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 19:39:50 -0500 Subject: [PATCH 09/10] Docstring formatting --- src/ITensorPkgSkeleton.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ITensorPkgSkeleton.jl b/src/ITensorPkgSkeleton.jl index 1e43947..c139551 100644 --- a/src/ITensorPkgSkeleton.jl +++ b/src/ITensorPkgSkeleton.jl @@ -140,7 +140,7 @@ end """ $(SIGNATURES) -All available templates when constructing a package. Includes the following templates: $(all_templates()) +All available templates when constructing a package. Includes the following templates: `$(all_templates())` """ function all_templates() return [ @@ -161,7 +161,7 @@ end """ $(SIGNATURES) -Default templates when constructing a package. Includes the following templates: $(default_templates()) +Default templates when constructing a package. Includes the following templates: `$(default_templates())` """ default_templates() = all_templates() From 20add1f6b2606a01c209c4f0ba18cc98e05d7eb3 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 25 Nov 2024 20:17:32 -0500 Subject: [PATCH 10/10] Better handling of downstream tests, project template --- src/ITensorPkgSkeleton.jl | 27 ++++++++----------------- templates/{src => project}/Project.toml | 0 test/test_basics.jl | 2 ++ 3 files changed, 10 insertions(+), 19 deletions(-) rename templates/{src => project}/Project.toml (100%) diff --git a/src/ITensorPkgSkeleton.jl b/src/ITensorPkgSkeleton.jl index c139551..4de80eb 100644 --- a/src/ITensorPkgSkeleton.jl +++ b/src/ITensorPkgSkeleton.jl @@ -142,21 +142,7 @@ $(SIGNATURES) All available templates when constructing a package. Includes the following templates: `$(all_templates())` """ -function all_templates() - return [ - "benchmark", - "docs", - "examples", - "formatter", - "github", - "gitignore", - "license", - "precommit", - "readme", - "src", - "test", - ] -end +all_templates() = readdir(joinpath(pkgdir(ITensorPkgSkeleton), "templates")) """ $(SIGNATURES) @@ -182,7 +168,7 @@ Generate a package template for a package, by default in the ITensor organizatio ```jldoctest julia> using ITensorPkgSkeleton: ITensorPkgSkeleton; -julia> ITensorPkgSkeleton.generate("NewPkg"); +julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir()); julia> ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir()); @@ -226,9 +212,12 @@ function generate( # Process downstream package information. user_replacements = format_downstreampkgs(user_replacements) templates = setdiff(templates, ignore_templates) - # Set default values. - if haskey(user_replacements, :downstreampkgs) - templates = [templates; "downstreampkgs"] + # Check if there are downstream tests. + if haskey(user_replacements, :downstreampkgs) && + !isempty(user_replacements.downstreampkgs) + templates = [templates; ["downstreampkgs"]] + else + templates = setdiff(templates, ["downstreampkgs"]) end # Fill in default path if missing. templates = set_default_template_path.(templates) diff --git a/templates/src/Project.toml b/templates/project/Project.toml similarity index 100% rename from templates/src/Project.toml rename to templates/project/Project.toml diff --git a/test/test_basics.jl b/test/test_basics.jl index 8506b88..9e6f46c 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -17,9 +17,11 @@ using Test: @test, @testset path = mktempdir() ITensorPkgSkeleton.generate("NewPkg"; path) @test isdir(joinpath(path, "NewPkg")) + @test isfile(joinpath(path, "NewPkg", "Project.toml")) for dir in pkgdirs @test isdir(joinpath(path, "NewPkg", dir)) end + @test !isfile(joinpath(path, "NewPkg", ".github", "workflows", "Downstream.yml")) end @testset "generate with downstream tests" begin for templates in (ITensorPkgSkeleton.default_templates(), [])