Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for downstream tests #17

Merged
merged 2 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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" => "support@itensor.org",
])
PkgSkeleton.generate(pkg_path; templates=[template_dir], user_replacements)
default_user() = "ITensor"

function default_user_replacements()
return (
GHUSER=default_user(), USERNAME="ITensor developers", USEREMAIL="support@itensor.org"
)
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
Loading