Skip to content

Commit

Permalink
Support for downstream tests (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtfishman authored Nov 22, 2024
1 parent 1c00b95 commit 16d3645
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 24 deletions.
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ ITensorPkgSkeleton.use_system_git!()
If `path` isn't specified, it defaults to `~/.julia/dev`.

````@example index
ITensorPkgSkeleton.generate("NewPkg"; path=tempdir())
ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir())
````

You can generate this README with:
Expand Down
2 changes: 1 addition & 1 deletion examples/README.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ using ITensorPkgSkeleton: ITensorPkgSkeleton
# the version of git installed by `Git.jl`.
ITensorPkgSkeleton.use_system_git!()
# If `path` isn't specified, it defaults to `~/.julia/dev`.
ITensorPkgSkeleton.generate("NewPkg"; path=tempdir())
ITensorPkgSkeleton.generate("NewPkg"; path=mktempdir())

# You can generate this README with:
#=
Expand Down
71 changes: 57 additions & 14 deletions src/ITensorPkgSkeleton.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module ITensorPkgSkeleton

using Git: git
using Git_jll: Git_jll
using PkgSkeleton: PkgSkeleton
using Preferences: Preferences

# Configure `Git.jl`/`Git_jll.jl` to
# use the local installation of git.
using Preferences: Preferences
# Need to load to set the preferences.
using Git_jll: Git_jll
function use_system_git!()
git_path = try
readchomp(`which git`)
Expand All @@ -17,6 +18,7 @@ function use_system_git!()
if !isnothing(git_path)
Preferences.set_preferences!("Git_jll", "git_path" => git_path)
end
return nothing
end

# Get the default branch name.
Expand Down Expand Up @@ -48,21 +50,62 @@ function default_path()
return joinpath(homedir(), ".julia", "dev")
end

function generate(pkg_name; path=default_path())
pkg_path = joinpath(path, pkg_name)
# TODO: Turn this into a keyword argument.
template_dir = joinpath(pkgdir(ITensorPkgSkeleton), "templates", "default")
default_templates() = ["default"]

branch_name = default_branch_name()
## TODO: Allow customization of these, currently
## they are hardcoded in the template.
user_replacements = Dict([
"GHUSER" => "ITensor",
"USERNAME" => "ITensor developers",
"USEREMAIL" => "[email protected]",
])
PkgSkeleton.generate(pkg_path; templates=[template_dir], user_replacements)
default_user() = "ITensor"

function default_user_replacements()
return (
GHUSER=default_user(), USERNAME="ITensor developers", USEREMAIL="[email protected]"
)
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",)))
```
=#
function format_downstream_pkgs(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
# Only the repo was passed as a standalone value.
default_user(), user_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
end
DOWNSTREAMPKGS *= " - {user: $(user), repo: $(repo).jl}\n"
end
DOWNSTREAMPKGS = chop(DOWNSTREAMPKGS)
return merge(user_replacements, (; DOWNSTREAMPKGS))
end

function set_default_template_path(template)
isabspath(template) && return template
return joinpath(pkgdir(ITensorPkgSkeleton), "templates", template)
end

function generate(
pkg_name; path=default_path(), templates=default_templates(), user_replacements=(;)
)
# Set default values.
user_replacements = merge(default_user_replacements(), user_replacements)
# 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)
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)
# Change the default branch.
change_branch_name(pkg_path, branch_name)
return nothing
Expand Down
48 changes: 48 additions & 0 deletions templates/downstream/.github/workflows/Downstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: IntegrationTest
on:
push:
branches: [main]
tags: [v*]
pull_request:

jobs:
test:
name: ${{ matrix.package.repo }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
julia-version: [1]
os: [ubuntu-latest]
package:
{DOWNSTREAMPKGS}

steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.julia-version }}
arch: x64
- uses: julia-actions/julia-buildpkg@latest
- name: Clone Downstream
uses: actions/checkout@v4
with:
repository: ${{ matrix.package.user }}/${{ matrix.package.repo }}
path: downstream
- name: Load this and run the downstream tests
shell: julia --color=yes --project=downstream {0}
run: |
using Pkg
try
# force it to use this PR's version of the package
Pkg.develop(PackageSpec(path=".")) # resolver may fail with main deps
Pkg.update()
Pkg.test(coverage=true) # resolver may fail with test time deps
catch err
err isa Pkg.Resolve.ResolverError || rethrow()
# If we can't resolve that means this is incompatible by SemVer and this is fine
# It means we marked this as a breaking change, so we don't need to worry about
# Mistakenly introducing a breaking change, as we have intentionally made one
@info "Not compatible with this release. No problem." exception=err
exit(0) # Exit immediately, as a success
end
41 changes: 33 additions & 8 deletions test/test_basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,38 @@ using ITensorPkgSkeleton: ITensorPkgSkeleton
using Test: @test, @testset

@testset "ITensorPkgSkeleton" begin
path = tempdir()
@test isnothing(ITensorPkgSkeleton.generate("NewPkg"; path))
@test isdir(joinpath(path, "NewPkg"))
@test isdir(joinpath(path, "NewPkg", ".github"))
@test isdir(joinpath(path, "NewPkg", "benchmark"))
@test isdir(joinpath(path, "NewPkg", "docs"))
@test isdir(joinpath(path, "NewPkg", "src"))
@test isdir(joinpath(path, "NewPkg", "test"))
pkgdirs = [".github", "benchmark", "docs", "src", "test"]
@testset "generate" begin
path = mktempdir()
ITensorPkgSkeleton.generate("NewPkg"; path)
@test isdir(joinpath(path, "NewPkg"))
for dir in pkgdirs
@test isdir(joinpath(path, "NewPkg", dir))
end
end
@testset "generate with downstream tests" begin
for templates in (["downstream"], ["default", "downstream"])
for DOWNSTREAMPKGS in (
("DownstreamPkg",), (repo="DownstreamPkg",), (user="ITensor", repo="DownstreamPkg")
)
path = mktempdir()
templates = ["default", "downstream"]
ITensorPkgSkeleton.generate(
"NewPkg"; path, templates, user_replacements=(; DOWNSTREAMPKGS=("DownstreamPkg",))
)
@test isdir(joinpath(path, "NewPkg"))
@test isdir(joinpath(path, "NewPkg", ".github", "workflows"))
@test isfile(joinpath(path, "NewPkg", ".github", "workflows", "Downstream.yml"))
@test open(
joinpath(path, "NewPkg", ".github", "workflows", "Downstream.yml"), "r"
) 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)
end
end
end
end
end
end

0 comments on commit 16d3645

Please sign in to comment.