From 4e5aeaa7563815ccf4f143970f8b74e3f80f000b Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Tue, 5 May 2026 16:26:04 -0600 Subject: [PATCH 01/29] Migrate template from cookiecutter to Copier --- .gitattributes | 3 +- .github/workflows/catch2_exemplar_test.yml | 12 +- ...{cookiecutter_test.yml => copier_test.yml} | 14 +- .github/workflows/todo_exemplar_test.yml | 12 +- .pre-commit-config.yaml | 2 +- README.md | 9 +- cookiecutter/check_cookiecutter.sh | 101 ------------- cookiecutter/cookiecutter.json | 16 -- cookiecutter/hooks/post_gen_project.py | 26 ---- .../.github/CODEOWNERS | 7 - .../CMakeLists.txt | 94 ------------ .../examples/identity_direct_usage.cpp | 24 --- .../CMakeLists.txt | 27 ---- .../{{cookiecutter.project_name}}/config.hpp | 12 -- .../config_generated.hpp.in | 8 - .../{{cookiecutter.project_name}}.cppm | 11 -- .../{{cookiecutter.project_name}}.hpp | 20 --- .../CMakeLists.txt | 33 ----- .../identity.test.cpp | 117 --------------- copier.yml | 76 ++++++++++ copier/check_copier.sh | 137 ++++++++++++++++++ infra/.github/workflows/pre-commit.yml | 1 + ...reusable-beman-create-issue-when-fault.yml | 1 + stamp.sh | 34 +++-- .../.beman-tidy.yaml.jinja | 2 +- .../.clang-format.jinja | 0 .../.gitattributes.jinja | 3 +- template/.github/CODEOWNERS.jinja | 7 + .../implementation-deficiency.md.jinja | 0 .../infrastructure-issues.md.jinja | 0 .../ISSUE_TEMPLATE/paper-discussion.md.jinja | 0 .../.github/pull_request_template.md.jinja | 0 .../.github/workflows/ci_tests.yml.jinja | 16 +- .../workflows/pre-commit-check.yml.jinja | 0 .../workflows/pre-commit-update.yml.jinja | 2 +- .../.github/workflows/vcpkg-release.yml.jinja | 2 +- .../.gitignore => template/.gitignore.jinja | 0 .../.markdownlint.yaml.jinja | 0 .../.pre-commit-config.yaml.jinja | 4 +- template/CMakeLists.txt.jinja | 94 ++++++++++++ .../CMakePresets.json.jinja | 2 +- .../CONTRIBUTING.md.jinja | 20 +-- .../LICENSE => template/LICENSE.jinja | 0 .../README.md => template/README.md.jinja | 89 ++++++------ .../examples/CMakeLists.txt.jinja | 14 +- .../identity_as_default_projection.cpp.jinja | 10 +- .../examples/identity_direct_usage.cpp.jinja | 24 +++ .../{{ project_name }}/CMakeLists.txt.jinja | 27 ++++ .../beman/{{ project_name }}/config.hpp.jinja | 12 ++ .../config_generated.hpp.in.jinja | 8 + .../{{ project_name }}/identity.hpp.jinja | 26 ++-- .../{{ project_name }}.cppm.jinja | 11 ++ .../{{ project_name }}.hpp.jinja | 20 +++ .../infra/.beman_submodule.jinja | 0 .../infra/.github/CODEOWNERS.jinja | 0 .../.github/workflows/pre-commit.yml.jinja | 2 + ...le-beman-create-issue-when-fault.yml.jinja | 2 + .../infra/.gitignore.jinja | 0 .../infra/.pre-commit-config.yaml.jinja | 0 .../LICENSE => template/infra/LICENSE.jinja | 0 .../infra/README.md.jinja | 0 .../infra/cmake/BuildTelemetry.cmake.jinja | 0 .../cmake/BuildTelemetryConfig.cmake.jinja | 0 .../infra/cmake/Config.cmake.in.jinja | 0 .../cmake/appleclang-toolchain.cmake.jinja | 0 .../cmake/beman-install-library.cmake.jinja | 0 ...enable-experimental-import-std.cmake.jinja | 0 .../infra/cmake/gnu-toolchain.cmake.jinja | 0 .../cmake/llvm-libc++-toolchain.cmake.jinja | 0 .../infra/cmake/llvm-toolchain.cmake.jinja | 0 .../infra/cmake/msvc-toolchain.cmake.jinja | 0 .../infra/cmake/telemetry.sh.jinja | 0 .../infra/cmake/use-fetch-content.cmake.jinja | 0 .../lockfile.json.jinja | 4 +- .../port/portfile.cmake.in.jinja | 12 +- .../port/vcpkg.json.in.jinja | 8 +- .../{{ project_name }}/CMakeLists.txt.jinja | 33 +++++ .../identity.test.cpp.jinja | 117 +++++++++++++++ .../vcpkg-configuration.json.jinja | 0 .../vcpkg.json => template/vcpkg.json.jinja | 8 +- 80 files changed, 733 insertions(+), 643 deletions(-) rename .github/workflows/{cookiecutter_test.yml => copier_test.yml} (52%) delete mode 100755 cookiecutter/check_cookiecutter.sh delete mode 100644 cookiecutter/cookiecutter.json delete mode 100755 cookiecutter/hooks/post_gen_project.py delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp create mode 100644 copier.yml create mode 100755 copier/check_copier.sh rename cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml => template/.beman-tidy.yaml.jinja (91%) rename cookiecutter/{{cookiecutter.project_name}}/.clang-format => template/.clang-format.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.gitattributes => template/.gitattributes.jinja (66%) create mode 100644 template/.github/CODEOWNERS.jinja rename cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md => template/.github/ISSUE_TEMPLATE/implementation-deficiency.md.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md => template/.github/ISSUE_TEMPLATE/infrastructure-issues.md.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md => template/.github/ISSUE_TEMPLATE/paper-discussion.md.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md => template/.github/pull_request_template.md.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml => template/.github/workflows/ci_tests.yml.jinja (88%) rename cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml => template/.github/workflows/pre-commit-check.yml.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml => template/.github/workflows/pre-commit-update.yml.jinja (66%) rename cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml => template/.github/workflows/vcpkg-release.yml.jinja (83%) rename cookiecutter/{{cookiecutter.project_name}}/.gitignore => template/.gitignore.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml => template/.markdownlint.yaml.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml => template/.pre-commit-config.yaml.jinja (94%) create mode 100644 template/CMakeLists.txt.jinja rename cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json => template/CMakePresets.json.jinja (99%) rename cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md => template/CONTRIBUTING.md.jinja (81%) rename cookiecutter/{{cookiecutter.project_name}}/LICENSE => template/LICENSE.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/README.md => template/README.md.jinja (60%) rename cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt => template/examples/CMakeLists.txt.jinja (60%) rename cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp => template/examples/identity_as_default_projection.cpp.jinja (87%) create mode 100644 template/examples/identity_direct_usage.cpp.jinja create mode 100644 template/include/beman/{{ project_name }}/CMakeLists.txt.jinja create mode 100644 template/include/beman/{{ project_name }}/config.hpp.jinja create mode 100644 template/include/beman/{{ project_name }}/config_generated.hpp.in.jinja rename cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp => template/include/beman/{{ project_name }}/identity.hpp.jinja (52%) create mode 100644 template/include/beman/{{ project_name }}/{{ project_name }}.cppm.jinja create mode 100644 template/include/beman/{{ project_name }}/{{ project_name }}.hpp.jinja rename cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule => template/infra/.beman_submodule.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS => template/infra/.github/CODEOWNERS.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml => template/infra/.github/workflows/pre-commit.yml.jinja (99%) rename cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml => template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja (98%) rename cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore => template/infra/.gitignore.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml => template/infra/.pre-commit-config.yaml.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE => template/infra/LICENSE.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/README.md => template/infra/README.md.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake => template/infra/cmake/BuildTelemetry.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake => template/infra/cmake/BuildTelemetryConfig.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in => template/infra/cmake/Config.cmake.in.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake => template/infra/cmake/appleclang-toolchain.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake => template/infra/cmake/beman-install-library.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake => template/infra/cmake/enable-experimental-import-std.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake => template/infra/cmake/gnu-toolchain.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake => template/infra/cmake/llvm-libc++-toolchain.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake => template/infra/cmake/llvm-toolchain.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake => template/infra/cmake/msvc-toolchain.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh => template/infra/cmake/telemetry.sh.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake => template/infra/cmake/use-fetch-content.cmake.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/lockfile.json => template/lockfile.json.jinja (82%) rename cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in => template/port/portfile.cmake.in.jinja (61%) rename cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in => template/port/vcpkg.json.in.jinja (50%) create mode 100644 template/tests/beman/{{ project_name }}/CMakeLists.txt.jinja create mode 100644 template/tests/beman/{{ project_name }}/identity.test.cpp.jinja rename cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json => template/vcpkg-configuration.json.jinja (100%) rename cookiecutter/{{cookiecutter.project_name}}/vcpkg.json => template/vcpkg.json.jinja (54%) diff --git a/.gitattributes b/.gitattributes index 793dce7d..9a7df7dd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ infra/** linguist-vendored -cookiecutter/** linguist-vendored +template/** linguist-vendored +copier/** linguist-vendored *.bib -linguist-detectable *.tex -linguist-detectable papers/* linguist-documentation diff --git a/.github/workflows/catch2_exemplar_test.yml b/.github/workflows/catch2_exemplar_test.yml index 60ee2576..bb0b73d2 100644 --- a/.github/workflows/catch2_exemplar_test.yml +++ b/.github/workflows/catch2_exemplar_test.yml @@ -17,12 +17,12 @@ jobs: uses: actions/checkout@v6 - name: Test catch2 exemplar run: | - cd cookiecutter - source ./check_cookiecutter.sh - cookiecutter_venv_path=$(mktemp --directory --dry-run) - setup_venv "$cookiecutter_venv_path" - stamp "$PWD" "./catch2_exemplar" "catch2" "true" - cd catch2_exemplar/exemplar + cd copier + source ./check_copier.sh + copier_venv_path=$(mktemp --directory --dry-run) + setup_venv "$copier_venv_path" + stamp "$repo_root" "./catch2_exemplar" "catch2" "true" + cd catch2_exemplar cmake -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake -DCMAKE_CXX_STANDARD=20 -DCMAKE_INSTALL_PREFIX=$PWD/dist cmake --build build ctest --test-dir build diff --git a/.github/workflows/cookiecutter_test.yml b/.github/workflows/copier_test.yml similarity index 52% rename from .github/workflows/cookiecutter_test.yml rename to .github/workflows/copier_test.yml index 04cdd05f..78b087a2 100644 --- a/.github/workflows/cookiecutter_test.yml +++ b/.github/workflows/copier_test.yml @@ -1,19 +1,23 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -name: Cookiecutter Test +name: Copier Test on: push: branches: - main pull_request: + workflow_dispatch: + +permissions: + contents: read jobs: - cookiecutter-test: + copier-test: runs-on: ubuntu-latest - name: "Check cookiecutter for consistency" + name: "Check copier for consistency" steps: - name: Checkout uses: actions/checkout@v6 - - name: beman cookiecutter consistency check + - name: beman copier consistency check run: | - ./cookiecutter/check_cookiecutter.sh + ./copier/check_copier.sh diff --git a/.github/workflows/todo_exemplar_test.yml b/.github/workflows/todo_exemplar_test.yml index e7b4c33b..38bf7aa7 100644 --- a/.github/workflows/todo_exemplar_test.yml +++ b/.github/workflows/todo_exemplar_test.yml @@ -17,12 +17,12 @@ jobs: uses: actions/checkout@v6 - name: Test static exemplar run: | - cd cookiecutter - source ./check_cookiecutter.sh - cookiecutter_venv_path=$(mktemp --directory --dry-run) - setup_venv "$cookiecutter_venv_path" - stamp "$PWD" "./static_exemplar" "gtest" "false" - cd static_exemplar/exemplar + cd copier + source ./check_copier.sh + copier_venv_path=$(mktemp --directory --dry-run) + setup_venv "$copier_venv_path" + stamp "$repo_root" "./static_exemplar" "gtest" "false" + cd static_exemplar grep -r 'identity' . && exit 1 find . -name '*identity*' | grep . && exit 1 cmake -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake -DCMAKE_CXX_STANDARD=20 -DCMAKE_INSTALL_PREFIX=$PWD/dist diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b3dc48c2..eb7313b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,4 +40,4 @@ repos: hooks: - id: codespell -exclude: 'cookiecutter/|infra/|port/' +exclude: 'template/|copier/|infra/|port/' diff --git a/README.md b/README.md index 0399d208..04196dfc 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ $ ./stamp.sh [3/6] minimum_cpp_build_version (20): [4/6] paper (PnnnnRr): P9999R9 [5/6] description (Short project description.): - [6/6] Select unit_test_library - 1 - gtest - 2 - catch2 - Choose from [1/2] (1): + unit_test_library? Format: str + Choices: + - gtest + - catch2 + > gtest Switched to a new branch 'stamp' Successfully stamped out exemplar template to the new branch 'stamp'. Try 'git push origin stamp' to push the branch upstream, diff --git a/cookiecutter/check_cookiecutter.sh b/cookiecutter/check_cookiecutter.sh deleted file mode 100755 index 394cca7e..00000000 --- a/cookiecutter/check_cookiecutter.sh +++ /dev/null @@ -1,101 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#!/usr/bin/env bash - -set -euo pipefail - -declare script_dir=$(realpath $(dirname "$BASH_SOURCE")) - -function stamp() { - local cookiecutter_dir="$1" ; shift - local output_dir="$1" ; shift - local unit_test_library="$1" ; shift - local generating_exemplar="$1" ; shift - python3 \ - -m cookiecutter \ - --no-input \ - --output-dir "$output_dir" \ - "$cookiecutter_dir" \ - project_name="exemplar" \ - minimum_cpp_build_version="17" \ - paper="P0898R3" \ - description="A Beman Library Exemplar" \ - unit_test_library="$unit_test_library" \ - _generating_exemplar="$generating_exemplar" \ - _ci_tests_cron="30 15 * * 6" \ - _pre_commit_update_cron="0 16 * * 0" -} - -function check_consistency() { - local out_dir_path - out_dir_path=$(mktemp --directory --dry-run) - cd /tmp - stamp "$script_dir" "$out_dir_path" "gtest" "true" - cp "$script_dir"/../.github/workflows/cookiecutter_test.yml "$out_dir_path"/exemplar/.github/workflows - cp "$script_dir"/../.github/workflows/catch2_exemplar_test.yml "$out_dir_path"/exemplar/.github/workflows - cp "$script_dir"/../.github/workflows/todo_exemplar_test.yml "$out_dir_path"/exemplar/.github/workflows - mkdir "$out_dir_path"/exemplar/images - cp "$script_dir"/../images/use-this-template.png "$out_dir_path"/exemplar/images/use-this-template.png - cp "$script_dir"/../stamp.sh "$out_dir_path"/exemplar/stamp.sh - local diff_path - diff_path=$(mktemp) - diff -r "$script_dir/.." "$out_dir_path/exemplar" \ - | grep -v -e 'cookiecutter$' -e '.git$' > "$diff_path" || true - rm -rf "$out_dir_path" - if [[ $(wc -l "$diff_path" | cut -d' ' -f1) -gt 0 ]] ; then - echo "Discrepancy between exemplar and cookiecutter:" >&2 - cat "$diff_path" - rm "$diff_path" - exit 1 - fi - rm "$diff_path" -} - -function check_templating() { - local out_dir_path - out_dir_path=$(mktemp --directory --dry-run) - cd /tmp - python3 \ - -m cookiecutter \ - --no-input \ - --output-dir "$out_dir_path" \ - "$script_dir" \ - project_name="RLZrmX9NfS" \ - minimum_cpp_build_version="17" \ - paper="P0898R3" \ - description="A Beman Library RLZrmX9NfS" \ - _generating_exemplar="false" \ - _ci_tests_cron="30 15 * * 6" \ - _pre_commit_update_cron="0 16 * * 0" - rm -rf "$out_dir_path/RLZrmX9NfS/infra" - local grep_path - grep_path=$(mktemp) - grep \ - --dereference-recursive --context=5 --color=always \ - -e "exemplar" -e "identity" "$out_dir_path/RLZrmX9NfS" > "$grep_path" || true - rm -rf "$out_dir_path" - if [[ $(wc -l "$grep_path" | cut -d' ' -f1) -gt 0 ]] ; then - echo "Untemplated \"exemplar\" or \"identity\" in cookiecutter:" >&2 - cat "$grep_path" - rm "$grep_path" - exit 1 - fi - rm "$grep_path" -} - -function setup_venv() { - local path="$1" ; shift - python3 -m venv "$cookiecutter_venv_path" - source "$cookiecutter_venv_path/bin/activate" - python3 -m pip install cookiecutter >& /dev/null -} - -function main() { - local cookiecutter_venv_path - cookiecutter_venv_path=$(mktemp --directory --dry-run) - setup_venv "$cookiecutter_venv_path" - check_consistency - check_templating - rm -rf "$cookiecutter_venv_path" -} - -[[ "${BASH_SOURCE[0]}" != "${0}" ]] || main "$@" diff --git a/cookiecutter/cookiecutter.json b/cookiecutter/cookiecutter.json deleted file mode 100644 index bb406fe8..00000000 --- a/cookiecutter/cookiecutter.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "project_name": "my_project_name", - "maintainer": "your_github_username", - "minimum_cpp_build_version": "20", - "paper": "PnnnnRr", - "description": "Short project description.", - "unit_test_library": ["gtest", "catch2"], - "_generating_exemplar": false, - "_owner": "bemanproject", - "_ci_tests_cron": "", - "_pre_commit_update_cron": "", - "_copy_without_render": [ - "infra" - ], - "_jinja2_env_vars": {"trim_blocks": true} -} diff --git a/cookiecutter/hooks/post_gen_project.py b/cookiecutter/hooks/post_gen_project.py deleted file mode 100755 index 9965c4c3..00000000 --- a/cookiecutter/hooks/post_gen_project.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -import shutil -import subprocess -from pathlib import Path -import os - -project_name = "{{ cookiecutter.project_name }}" -generating_exemplar = "{{ cookiecutter._generating_exemplar }}" == "True" - -if not generating_exemplar: - os.rename("include/beman/" + project_name + "/identity.hpp", "include/beman/" + project_name + "/todo.hpp") - os.rename("examples/identity_direct_usage.cpp", "examples/todo.cpp") - os.remove("examples/identity_as_default_projection.cpp") - os.rename("tests/beman/" + project_name + "/identity.test.cpp", "tests/beman/" + project_name + "/todo.test.cpp") - - # Record the exemplar commit this project was stamped from. - result = subprocess.run( - ["git", "ls-remote", "https://github.com/bemanproject/exemplar.git", "HEAD"], - capture_output=True, - text=True, - check=True, - ) - sha = result.stdout.split()[0] - Path(".exemplar_version").write_text(sha + "\n") diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS b/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS deleted file mode 100644 index 6912aeb8..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -{% if cookiecutter._generating_exemplar %} -* @ednolan @bretbrownjr @camio @dietmarkuehl @neatudarius @steve-downey @wusatosi -{% else %} -* @{{ cookiecutter.maintainer }} -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index 80181421..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,94 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -cmake_minimum_required(VERSION 3.30...4.3) - -include(infra/cmake/enable-experimental-import-std.cmake) - -project( - beman.{{cookiecutter.project_name}} - DESCRIPTION "{{cookiecutter.description}}" - LANGUAGES CXX -{% if cookiecutter._generating_exemplar %} - VERSION 2.4.0 -{% else %} - VERSION 0.1.0 -{% endif %} -) - -# [CMAKE.SKIP_TESTS] -option( - BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS - "Enable building tests and test infrastructure. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." - ${PROJECT_IS_TOP_LEVEL} -) - -# [CMAKE.SKIP_EXAMPLES] -option( - BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES - "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." - ${PROJECT_IS_TOP_LEVEL} -) - -option(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES "Provide beman.{{cookiecutter.project_name}} as a C++ module" OFF) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - set(CMAKE_CXX_SCAN_FOR_MODULES ON) -endif() - -configure_file( - "${PROJECT_SOURCE_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in" - "${PROJECT_BINARY_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp" - @ONLY -) - -# for find of beman_install_library and configure_build_telemetry -include(infra/cmake/beman-install-library.cmake) -include(infra/cmake/BuildTelemetryConfig.cmake) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - add_library(beman.{{cookiecutter.project_name}} STATIC) -else() - add_library(beman.{{cookiecutter.project_name}} INTERFACE) -endif() -add_library(beman::{{cookiecutter.project_name}} ALIAS beman.{{cookiecutter.project_name}}) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET CXX_MODULES - FILE_SET HEADERS - BASE_DIRS - "${CMAKE_CURRENT_SOURCE_DIR}/include" - "${CMAKE_CURRENT_BINARY_DIR}/include" - ) - set_target_properties(beman.{{cookiecutter.project_name}} PROPERTIES CXX_MODULE_STD ON) - target_compile_features(beman.{{cookiecutter.project_name}} PUBLIC cxx_std_23) -else() - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET HEADERS - BASE_DIRS - "${CMAKE_CURRENT_SOURCE_DIR}/include" - "${CMAKE_CURRENT_BINARY_DIR}/include" - ) - set_target_properties( - beman.{{cookiecutter.project_name}} - PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL} - ) -endif() - -add_subdirectory(include/beman/{{cookiecutter.project_name}}) - -beman_install_library(beman.{{cookiecutter.project_name}} TARGETS beman.{{cookiecutter.project_name}}) -configure_build_telemetry() - -if(BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS) - enable_testing() - add_subdirectory(tests/beman/{{cookiecutter.project_name}}) -endif() - -if(BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES) - add_subdirectory(examples) -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp b/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp deleted file mode 100644 index 0284d36d..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#include -#include - -{% if cookiecutter._generating_exemplar %} -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() -import std; -#else - #include -#endif - -namespace exe = beman::{{cookiecutter.project_name}}; - -int main() { - std::cout << exe::identity()(2024) << '\n'; - return 0; -} -{% else %} -int main() { - // TODO -} -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index 352eb052..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET CXX_MODULES FILES {{cookiecutter.project_name}}.cppm - FILE_SET HEADERS - FILES - config.hpp - {{cookiecutter.project_name}}.hpp - {{identity}}.hpp - "${PROJECT_BINARY_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp" - ) -else() - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET HEADERS - FILES - config.hpp - {{cookiecutter.project_name}}.hpp - {{identity}}.hpp - "${PROJECT_BINARY_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp" - ) -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp deleted file mode 100644 index 7b86494a..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_HPP - -#if !defined(__has_include) || __has_include() - #include -#else - #define BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() 0 -#endif - -#endif diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in deleted file mode 100644 index 90941a1f..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_GENERATED_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_GENERATED_HPP - -#cmakedefine01 BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() - -#endif diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm deleted file mode 100644 index 96b15487..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm +++ /dev/null @@ -1,11 +0,0 @@ -export module beman.{{cookiecutter.project_name}}; - -import std; - -#define BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT -export { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" -#include -#pragma clang diagnostic pop -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp deleted file mode 100644 index 7df9cb80..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_{{cookiecutter.project_name.upper()}}_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_{{cookiecutter.project_name.upper()}}_HPP - -#include - -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) - -import beman.{{cookiecutter.project_name}}; - -#else - - #include - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && - // !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_{{cookiecutter.project_name.upper()}}_HPP diff --git a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index 4450cd8d..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -{% if cookiecutter.unit_test_library == "gtest" %} -find_package(GTest REQUIRED) -{% elif cookiecutter.unit_test_library == "catch2" %} -find_package(Catch2 3 REQUIRED) -{% endif %} - -add_executable(beman.{{cookiecutter.project_name}}.tests.{{identity}}) -target_sources(beman.{{cookiecutter.project_name}}.tests.{{identity}} PRIVATE {{identity}}.test.cpp) -target_link_libraries( - beman.{{cookiecutter.project_name}}.tests.{{identity}} -{% if cookiecutter.unit_test_library == "gtest" %} - PRIVATE beman::{{cookiecutter.project_name}} GTest::gtest_main -{% elif cookiecutter.unit_test_library == "catch2" %} - PRIVATE beman::{{cookiecutter.project_name}} Catch2::Catch2WithMain -{% endif %} -) -if(BEMAN_EXEMPLAR_USE_MODULES) - set_target_properties( - beman.{{cookiecutter.project_name}}.tests.{{identity}} - PROPERTIES CXX_MODULE_STD ON - ) -endif() - -{% if cookiecutter.unit_test_library == "gtest" %} -include(GoogleTest) -gtest_discover_tests(beman.{{cookiecutter.project_name}}.tests.{{identity}} DISCOVERY_TIMEOUT 60) -{% elif cookiecutter.unit_test_library == "catch2" %} -include(Catch) -catch_discover_tests(beman.{{cookiecutter.project_name}}.tests.{{identity}}) -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp b/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp deleted file mode 100644 index 2b4c0697..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#include -{% if cookiecutter.unit_test_library == "gtest" %} -#include -{% elif cookiecutter.unit_test_library == "catch2" %} -#include -{% endif %} -#include - -{% if cookiecutter._generating_exemplar %} -#if BEMAN_EXEMPLAR_USE_MODULES() -import std; -#else - #include - #include -#endif - -namespace exe = beman::{{cookiecutter.project_name}}; - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, call_identity_with_int) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("can call identity with int", "[{{cookiecutter.project_name}}::call_identity_with_int]") { -{% endif %} - for (int i = -100; i < 100; ++i) { -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(i, exe::identity()(i)); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(i == exe::identity()(i)); -{% endif %} - } -} - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, call_identity_with_custom_type) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("can call identity with custom type", "[{{cookiecutter.project_name}}::call_identity_with_custom_type]") { -{% endif %} - struct S { - int i; - }; - - for (int i = -100; i < 100; ++i) { - const S s{i}; - const S s_id = exe::identity()(s); -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(s.i, s_id.i); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(s.i == s_id.i); -{% endif %} - } -} - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, compare_std_vs_beman) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("compare std vs beman", "[{{cookiecutter.project_name}}::compare_std_vs_beman]") { -{% endif %} -// Requires: std::identity support. -#if defined(__cpp_lib_type_identity) - std::identity std_id; - exe::identity beman_id; - for (int i = -100; i < 100; ++i) { -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(std_id(i), beman_id(i)); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(std_id(i) == beman_id(i)); -{% endif %} - } -#endif -} - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, check_is_transparent) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("check is transparent", "[{{cookiecutter.project_name}}::check_is_transparent]") { -{% endif %} -// Requires: transparent operators support. -#if defined(__cpp_lib_transparent_operators) - - exe::identity id; - - const auto container = {1, 2, 3, 4, 5}; - auto it = std::find(std::begin(container), std::end(container), 3); -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(3, *it); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(3 == *it); -{% endif %} - auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(3, *it_with_id); - - EXPECT_EQ(it, it_with_id); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(3 == *it_with_id); - - CHECK(it == it_with_id); -{% endif %} -#endif -} -{% else %} -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(TodoTest, todo) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("todo", "[{{cookiecutter.project_name}}::todo]") { -{% endif %} - const bool todo = true; -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_TRUE(todo); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(todo); -{% endif %} -} -{% endif %} diff --git a/copier.yml b/copier.yml new file mode 100644 index 00000000..8eef7f2a --- /dev/null +++ b/copier.yml @@ -0,0 +1,76 @@ +_min_copier_version: "9.14.3" +_subdirectory: template +_templates_suffix: .jinja +_envops: + trim_blocks: true + +project_name: + type: str + help: Name of the generated repository and library. + default: my_project_name + validator: >- + {% if not (project_name | regex_search('^[a-z][a-z0-9_]*$')) %} + Use lowercase letters, digits, or underscores, and start with a letter. + {% endif %} + +maintainer: + type: str + help: GitHub username of the project maintainer. + default: your_github_username + +minimum_cpp_build_version: + type: str + help: Minimum C++ language version to require when building. + default: "20" + validator: >- + {% if minimum_cpp_build_version not in ['17', '20', '23', '26'] %} + Choose one of: 17, 20, 23, 26. + {% endif %} + +paper: + type: str + help: WG21 paper number associated with the library. + default: PnnnnRr + +description: + type: str + help: Short project description. + default: Short project description. + +unit_test_library: + type: str + help: Unit test library to configure. + choices: + - gtest + - catch2 + default: gtest + +generating_exemplar: + type: bool + when: false + default: false + +owner: + type: str + when: false + default: bemanproject + +ci_tests_cron: + type: str + when: false + default: "" + +pre_commit_update_cron: + type: str + when: false + default: "" + +_tasks: + - >- + if [ "{{ generating_exemplar }}" != "True" ] && [ "{{ generating_exemplar }}" != "true" ]; then + mv "include/beman/{{ project_name }}/identity.hpp" "include/beman/{{ project_name }}/todo.hpp"; + mv "examples/identity_direct_usage.cpp" "examples/todo.cpp"; + rm "examples/identity_as_default_projection.cpp"; + mv "tests/beman/{{ project_name }}/identity.test.cpp" "tests/beman/{{ project_name }}/todo.test.cpp"; + git ls-remote https://github.com/bemanproject/exemplar.git HEAD | awk '{print $1}' > .exemplar_version; + fi diff --git a/copier/check_copier.sh b/copier/check_copier.sh new file mode 100755 index 00000000..c9c99362 --- /dev/null +++ b/copier/check_copier.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set -euo pipefail + +script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +repo_root=$(realpath "$script_dir/..") + +cleanup() { + if [[ -n "${work_dir:-}" && -d "$work_dir" ]]; then + rm -rf "$work_dir" + fi + if [[ -n "${copier_venv_path:-}" && -d "$copier_venv_path" ]]; then + rm -rf "$copier_venv_path" + fi +} + +setup_venv() { + local path="$1" ; shift + python3 -m venv "$path" + "$path/bin/python3" -m pip install copier >& /dev/null + COPIER_BIN="$path/bin/copier" +} + +prepare_template_source() { + local source_dir="$1" ; shift + local prepared_source + prepared_source=$(mktemp -d) + rsync -a \ + --exclude .git \ + --exclude build \ + --exclude .venv \ + "$source_dir/" "$prepared_source/" + printf '%s\n' "$prepared_source" +} + +stamp() { + local template_source="$1" ; shift + local output_dir="$1" ; shift + local unit_test_library="$1" ; shift + local generating_exemplar="$1" ; shift + local prepared_source + prepared_source=$(prepare_template_source "$template_source") + "$COPIER_BIN" copy \ + --trust \ + --defaults \ + -d project_name=exemplar \ + -d maintainer=steve-downey \ + -d minimum_cpp_build_version=17 \ + -d paper=P0898R3 \ + -d description="A Beman Library Exemplar" \ + -d unit_test_library="$unit_test_library" \ + -d generating_exemplar="$generating_exemplar" \ + -d owner=bemanproject \ + -d ci_tests_cron="30 15 * * 6" \ + -d pre_commit_update_cron="0 16 * * 0" \ + "$prepared_source" \ + "$output_dir" \ + >& /dev/null + rm -rf "$prepared_source" +} + +check_consistency() { + local output_dir="$work_dir/default" + mkdir -p "$output_dir" + stamp "$repo_root" "$output_dir" "gtest" "true" + + local diff_path="$work_dir/default.diff" + diff -r \ + --exclude .git \ + --exclude build \ + --exclude .venv \ + --exclude template \ + --exclude copier \ + --exclude copier.yml \ + --exclude stamp.sh \ + --exclude images \ + --exclude .copier-answers.yml \ + --exclude copier_test.yml \ + --exclude catch2_exemplar_test.yml \ + --exclude todo_exemplar_test.yml \ + "$repo_root" "$output_dir" > "$diff_path" || true + + if [[ -s "$diff_path" ]] ; then + echo "Discrepancy between exemplar and copier output:" >&2 + cat "$diff_path" >&2 + exit 1 + fi +} + +check_templating() { + local output_dir="$work_dir/randomized" + local prepared_source + mkdir -p "$output_dir" + prepared_source=$(prepare_template_source "$repo_root") + "$COPIER_BIN" copy \ + --trust \ + --defaults \ + -d project_name=rlzrmx9nfs \ + -d maintainer=octocat \ + -d minimum_cpp_build_version=17 \ + -d paper=P0898R3 \ + -d description="A Beman Library rlzrmx9nfs" \ + -d unit_test_library=gtest \ + -d generating_exemplar=false \ + -d owner=bemanproject \ + -d ci_tests_cron="30 15 * * 6" \ + -d pre_commit_update_cron="0 16 * * 0" \ + "$prepared_source" \ + "$output_dir" \ + >& /dev/null + rm -rf "$prepared_source" + + rm -rf "$output_dir/infra" + + local grep_path="$work_dir/randomized.grep" + grep \ + --dereference-recursive --context=5 --color=always \ + -e "exemplar" -e "identity" "$output_dir" > "$grep_path" || true + + if [[ -s "$grep_path" ]] ; then + echo 'Untemplated "exemplar" or "identity" in copier output:' >&2 + cat "$grep_path" >&2 + exit 1 + fi +} + +main() { + work_dir=$(mktemp -d) + copier_venv_path=$(mktemp -d) + trap cleanup EXIT + setup_venv "$copier_venv_path" + check_consistency + check_templating +} + +[[ "${BASH_SOURCE[0]}" != "${0}" ]] || main "$@" diff --git a/infra/.github/workflows/pre-commit.yml b/infra/.github/workflows/pre-commit.yml index 7051c132..e54a1ea8 100644 --- a/infra/.github/workflows/pre-commit.yml +++ b/infra/.github/workflows/pre-commit.yml @@ -1,4 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + name: Lint Check (pre-commit) on: diff --git a/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml b/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml index 024a51f4..6e9b6e0d 100644 --- a/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml +++ b/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + name: 'Beman issue creation workflow' on: workflow_call: diff --git a/stamp.sh b/stamp.sh index 7dc9ee84..de365739 100755 --- a/stamp.sh +++ b/stamp.sh @@ -1,5 +1,5 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #!/usr/bin/env bash +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception { if [[ "$1" == "-h" || "$1" == "--help" ]] ; then @@ -8,11 +8,11 @@ This script is intended to be run on a fork of exemplar. - It sets up cookiecutter, runs it on the cookiecutter template, replaces the + It sets up Copier, runs it on the exemplar template, replaces the repository's current contents with the result, runs pre-commit, switches to a new branch 'stamp', and creates a git commit. - All parameters are passed through to the cookiecutter invocation. + All parameters are passed through to the Copier invocation. EOF fi set -eu @@ -22,23 +22,29 @@ EOF fi declare repo_dir=$(realpath $(dirname "$BASH_SOURCE")) cd "$repo_dir" - declare cookiecutter_venv_path - cookiecutter_venv_path=$(mktemp --directory --dry-run) - python3 -m venv "$cookiecutter_venv_path" - source "$cookiecutter_venv_path/bin/activate" - python3 -m pip install cookiecutter pre-commit >& /dev/null - declare cookiecutter_out_path - cookiecutter_out_path=$(mktemp --directory) - python3 -m cookiecutter "$repo_dir/cookiecutter" -o "$cookiecutter_out_path" "$@" + declare copier_venv_path + copier_venv_path=$(mktemp --directory --dry-run) + python3 -m venv "$copier_venv_path" + "$copier_venv_path/bin/python3" -m pip install copier pre-commit >& /dev/null + declare copier_source_path + copier_source_path=$(mktemp --directory) + declare copier_out_path + copier_out_path=$(mktemp --directory) + rsync -a \ + --exclude .git \ + --exclude build \ + --exclude .venv \ + "$repo_dir/" "$copier_source_path/" + "$copier_venv_path/bin/copier" copy --trust "$@" "$copier_source_path" "$copier_out_path" >& /dev/null git rm -rf . &>/dev/null - cp -r "$cookiecutter_out_path"/*/. . + cp -r "$copier_out_path"/. . git add . &>/dev/null - pre-commit run --all-files &>/dev/null || true + "$copier_venv_path/bin/pre-commit" run --all-files &>/dev/null || true git add . &>/dev/null git checkout -b stamp git commit -q -m "Stamp out exemplar template" echo "Successfully stamped out exemplar template to the new branch 'stamp'." echo "Try 'git push origin stamp' to push the branch upstream," echo "then create a pull request." - rm -r "$cookiecutter_venv_path" "$cookiecutter_out_path" + rm -r "$copier_venv_path" "$copier_source_path" "$copier_out_path" }; exit diff --git a/cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml b/template/.beman-tidy.yaml.jinja similarity index 91% rename from cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml rename to template/.beman-tidy.yaml.jinja index 527ca1e1..c54e2f32 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml +++ b/template/.beman-tidy.yaml.jinja @@ -4,7 +4,7 @@ # Check documentation for beman-tidy here: # https://github.com/bemanproject/beman-tidy/blob/main/README.md -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} disabled_rules: - readme.title {% else %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.clang-format b/template/.clang-format.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.clang-format rename to template/.clang-format.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.gitattributes b/template/.gitattributes.jinja similarity index 66% rename from cookiecutter/{{cookiecutter.project_name}}/.gitattributes rename to template/.gitattributes.jinja index 793dce7d..9a7df7dd 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.gitattributes +++ b/template/.gitattributes.jinja @@ -1,5 +1,6 @@ infra/** linguist-vendored -cookiecutter/** linguist-vendored +template/** linguist-vendored +copier/** linguist-vendored *.bib -linguist-detectable *.tex -linguist-detectable papers/* linguist-documentation diff --git a/template/.github/CODEOWNERS.jinja b/template/.github/CODEOWNERS.jinja new file mode 100644 index 00000000..566c8858 --- /dev/null +++ b/template/.github/CODEOWNERS.jinja @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +{% if generating_exemplar %} +* @ednolan @bretbrownjr @camio @dietmarkuehl @steve-downey @wusatosi +{% else %} +* @{{ maintainer }} +{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md b/template/.github/ISSUE_TEMPLATE/implementation-deficiency.md.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md rename to template/.github/ISSUE_TEMPLATE/implementation-deficiency.md.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md b/template/.github/ISSUE_TEMPLATE/infrastructure-issues.md.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md rename to template/.github/ISSUE_TEMPLATE/infrastructure-issues.md.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md b/template/.github/ISSUE_TEMPLATE/paper-discussion.md.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md rename to template/.github/ISSUE_TEMPLATE/paper-discussion.md.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md b/template/.github/pull_request_template.md.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md rename to template/.github/pull_request_template.md.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml b/template/.github/workflows/ci_tests.yml.jinja similarity index 88% rename from cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml rename to template/.github/workflows/ci_tests.yml.jinja index 30b658e5..419fd15c 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -9,7 +9,7 @@ on: pull_request: workflow_dispatch: schedule: - - cron: '{% if cookiecutter._ci_tests_cron %}{{ cookiecutter._ci_tests_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}' + - cron: '{% if ci_tests_cron %}{{ ci_tests_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}' jobs: beman-submodule-check: @@ -44,7 +44,7 @@ jobs: "tests": [ "Debug.Default", "Release.Default", "Release.TSan", "Release.MaxSan", "Debug.Werror", - "Debug.Coverage", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" + "Debug.Coverage", "Debug.-DBEMAN_{{project_name.upper()}}_USE_MODULES=On" ] } ] @@ -53,7 +53,7 @@ jobs: "tests": [ { "stdlibs": ["libstdc++"], "tests": [ - "Release.Default", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" + "Release.Default", "Debug.-DBEMAN_{{project_name.upper()}}_USE_MODULES=On" ] } ] @@ -69,7 +69,7 @@ jobs: "tests": [ { "stdlibs": ["libstdc++"], "tests": [ - "Release.Default", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" + "Release.Default", "Debug.-DBEMAN_{{project_name.upper()}}_USE_MODULES=On" ] } ] @@ -104,7 +104,7 @@ jobs: "tests": [ "Debug.Default", "Release.Default", "Release.TSan", "Release.MaxSan", "Debug.Werror", - "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" + "Debug.-DBEMAN_{{project_name.upper()}}_USE_MODULES=On" ] } ] @@ -113,7 +113,7 @@ jobs: "tests": [ { "stdlibs": ["libstdc++", "libc++"], "tests": [ - "Release.Default", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" + "Release.Default", "Debug.-DBEMAN_{{project_name.upper()}}_USE_MODULES=On" ] } ] @@ -172,7 +172,7 @@ jobs: { "stdlibs": ["stl"], "tests": [ "Debug.Default", "Release.Default", "Release.MaxSan", - "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" + "Debug.-DBEMAN_{{project_name.upper()}}_USE_MODULES=On" ] } ] @@ -185,7 +185,7 @@ jobs: vcpkg-ci: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-vcpkg-ci.yml@1.7.1 with: - port_name: beman-{{cookiecutter.project_name.replace('_', '-')}} + port_name: beman-{{project_name.replace('_', '-')}} feature_combinations: | [ {"features": {}}, diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml b/template/.github/workflows/pre-commit-check.yml.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml rename to template/.github/workflows/pre-commit-check.yml.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml b/template/.github/workflows/pre-commit-update.yml.jinja similarity index 66% rename from cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml rename to template/.github/workflows/pre-commit-update.yml.jinja index 7abffe12..7939db57 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml +++ b/template/.github/workflows/pre-commit-update.yml.jinja @@ -5,7 +5,7 @@ name: Weekly pre-commit autoupdate on: workflow_dispatch: schedule: - - cron: "{% if cookiecutter._pre_commit_update_cron %}{{ cookiecutter._pre_commit_update_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}" + - cron: "{% if pre_commit_update_cron %}{{ pre_commit_update_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}" {% raw -%} jobs: diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml b/template/.github/workflows/vcpkg-release.yml.jinja similarity index 83% rename from cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml rename to template/.github/workflows/vcpkg-release.yml.jinja index 455faf87..93de47da 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml +++ b/template/.github/workflows/vcpkg-release.yml.jinja @@ -8,7 +8,7 @@ jobs: vcpkg-release: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-vcpkg-release.yml@1.7.1 with: - port_name: beman-{{cookiecutter.project_name.replace('_', '-')}} + port_name: beman-{{project_name.replace('_', '-')}} {%- raw %} secrets: VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.gitignore b/template/.gitignore.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.gitignore rename to template/.gitignore.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml b/template/.markdownlint.yaml.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml rename to template/.markdownlint.yaml.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/template/.pre-commit-config.yaml.jinja similarity index 94% rename from cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml rename to template/.pre-commit-config.yaml.jinja index 3845c974..ec5a80dd 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ b/template/.pre-commit-config.yaml.jinja @@ -40,7 +40,7 @@ repos: hooks: - id: codespell -{% if not cookiecutter._generating_exemplar %} +{% if not generating_exemplar %} # Beman Standard checking via beman-tidy - repo: https://github.com/bemanproject/beman-tidy rev: v0.3.1 @@ -48,4 +48,4 @@ repos: - id: beman-tidy {% endif %} -exclude: 'cookiecutter/|infra/|port/' +exclude: 'template/|copier/|infra/|port/' diff --git a/template/CMakeLists.txt.jinja b/template/CMakeLists.txt.jinja new file mode 100644 index 00000000..e70bf583 --- /dev/null +++ b/template/CMakeLists.txt.jinja @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.30...4.3) + +include(infra/cmake/enable-experimental-import-std.cmake) + +project( + beman.{{project_name}} + DESCRIPTION "{{description}}" + LANGUAGES CXX +{% if generating_exemplar %} + VERSION 2.4.0 +{% else %} + VERSION 0.1.0 +{% endif %} +) + +# [CMAKE.SKIP_TESTS] +option( + BEMAN_{{project_name.upper()}}_BUILD_TESTS + "Enable building tests and test infrastructure. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." + ${PROJECT_IS_TOP_LEVEL} +) + +# [CMAKE.SKIP_EXAMPLES] +option( + BEMAN_{{project_name.upper()}}_BUILD_EXAMPLES + "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." + ${PROJECT_IS_TOP_LEVEL} +) + +option(BEMAN_{{project_name.upper()}}_USE_MODULES "Provide beman.{{project_name}} as a C++ module" OFF) + +if(BEMAN_{{project_name.upper()}}_USE_MODULES) + set(CMAKE_CXX_SCAN_FOR_MODULES ON) +endif() + +configure_file( + "${PROJECT_SOURCE_DIR}/include/beman/{{project_name}}/config_generated.hpp.in" + "${PROJECT_BINARY_DIR}/include/beman/{{project_name}}/config_generated.hpp" + @ONLY +) + +# for find of beman_install_library and configure_build_telemetry +include(infra/cmake/beman-install-library.cmake) +include(infra/cmake/BuildTelemetryConfig.cmake) + +if(BEMAN_{{project_name.upper()}}_USE_MODULES) + add_library(beman.{{project_name}} STATIC) +else() + add_library(beman.{{project_name}} INTERFACE) +endif() +add_library(beman::{{project_name}} ALIAS beman.{{project_name}}) + +if(BEMAN_{{project_name.upper()}}_USE_MODULES) + target_sources( + beman.{{project_name}} + PUBLIC + FILE_SET CXX_MODULES + FILE_SET HEADERS + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_BINARY_DIR}/include" + ) + set_target_properties(beman.{{project_name}} PROPERTIES CXX_MODULE_STD ON) + target_compile_features(beman.{{project_name}} PUBLIC cxx_std_23) +else() + target_sources( + beman.{{project_name}} + PUBLIC + FILE_SET HEADERS + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_BINARY_DIR}/include" + ) + set_target_properties( + beman.{{project_name}} + PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL} + ) +endif() + +add_subdirectory(include/beman/{{project_name}}) + +beman_install_library(beman.{{project_name}} TARGETS beman.{{project_name}}) +configure_build_telemetry() + +if(BEMAN_{{project_name.upper()}}_BUILD_TESTS) + enable_testing() + add_subdirectory(tests/beman/{{project_name}}) +endif() + +if(BEMAN_{{project_name.upper()}}_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json b/template/CMakePresets.json.jinja similarity index 99% rename from cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json rename to template/CMakePresets.json.jinja index cd426bee..f88fecb5 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json +++ b/template/CMakePresets.json.jinja @@ -7,7 +7,7 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { - "CMAKE_CXX_STANDARD": "{{cookiecutter.minimum_cpp_build_version}}", + "CMAKE_CXX_STANDARD": "{{minimum_cpp_build_version}}", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "./infra/cmake/use-fetch-content.cmake" } diff --git a/cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md b/template/CONTRIBUTING.md.jinja similarity index 81% rename from cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md rename to template/CONTRIBUTING.md.jinja index d15f2843..9a785499 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md +++ b/template/CONTRIBUTING.md.jinja @@ -43,7 +43,7 @@ that this requires GoogleTest to be installed. cmake \ -B build \ -S . \ - -DCMAKE_CXX_STANDARD={{cookiecutter.minimum_cpp_build_version}} \ + -DCMAKE_CXX_STANDARD={{minimum_cpp_build_version}} \ # Your extra arguments here. cmake --build build ctest --test-dir build @@ -85,7 +85,7 @@ vcpkg. ### FetchContent Instead of installing the project's dependencies via a package manager, you can optionally -configure beman.{{cookiecutter.project_name}} to fetch them automatically via CMake FetchContent. +configure beman.{{project_name}} to fetch them automatically via CMake FetchContent. To do so, specify `-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake`. This will @@ -97,7 +97,7 @@ Example commands: cmake \ -B build \ -S . \ - -DCMAKE_CXX_STANDARD={{cookiecutter.minimum_cpp_build_version}} \ + -DCMAKE_CXX_STANDARD={{minimum_cpp_build_version}} \ -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake cmake --build build ctest --test-dir build @@ -108,32 +108,32 @@ acquired by FetchContent. ## Project-specific configure arguments -Project-specific options are prefixed with `BEMAN_{{cookiecutter.project_name.upper()}}`. +Project-specific options are prefixed with `BEMAN_{{project_name.upper()}}`. You can see the list of available options with: ```bash -cmake -LH -S . -B build | grep "BEMAN_{{cookiecutter.project_name.upper()}}" -C 2 +cmake -LH -S . -B build | grep "BEMAN_{{project_name.upper()}}" -C 2 ```
Some project-specific configure arguments -### `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS` +### `BEMAN_{{project_name.upper()}}_BUILD_TESTS` Enable building tests and test infrastructure. Default: `ON`. Values: `{ ON, OFF }`. -### `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES` +### `BEMAN_{{project_name.upper()}}_BUILD_EXAMPLES` Enable building examples. Default: `ON`. Values: `{ ON, OFF }`. -### `BEMAN_{{cookiecutter.project_name.upper()}}_INSTALL_CONFIG_FILE_PACKAGE` +### `BEMAN_{{project_name.upper()}}_INSTALL_CONFIG_FILE_PACKAGE` Enable installing the CMake config file package. Default: `ON`. Values: `{ ON, OFF }`. -This is required so that users of `beman.{{cookiecutter.project_name}}` can use -`find_package(beman.{{cookiecutter.project_name}})` to locate the library. +This is required so that users of `beman.{{project_name}}` can use +`find_package(beman.{{project_name}})` to locate the library.
diff --git a/cookiecutter/{{cookiecutter.project_name}}/LICENSE b/template/LICENSE.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/LICENSE rename to template/LICENSE.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/README.md b/template/README.md.jinja similarity index 60% rename from cookiecutter/{{cookiecutter.project_name}}/README.md rename to template/README.md.jinja index e3161121..601709ea 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/README.md +++ b/template/README.md.jinja @@ -1,4 +1,4 @@ -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} # How to Use This Template To create a new Beman library, first click the "Use this template" dropdown in the @@ -23,10 +23,11 @@ $ ./stamp.sh [3/6] minimum_cpp_build_version (20): [4/6] paper (PnnnnRr): P9999R9 [5/6] description (Short project description.): - [6/6] Select unit_test_library - 1 - gtest - 2 - catch2 - Choose from [1/2] (1): + unit_test_library? Format: str + Choices: + - gtest + - catch2 + > gtest Switched to a new branch 'stamp' Successfully stamped out exemplar template to the new branch 'stamp'. Try 'git push origin stamp' to push the branch upstream, @@ -39,51 +40,51 @@ labeled 'todo'. What follow is an example of a Beman library README. {% endif %} -# beman.{{cookiecutter.project_name}}: {{cookiecutter.description}} +# beman.{{project_name}}: {{description}} -![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/{{cookiecutter._owner}}/{{cookiecutter.project_name}}/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/{{cookiecutter._owner}}/{{cookiecutter.project_name}}/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/{{cookiecutter._owner}}/{{cookiecutter.project_name}}/badge.svg?branch=main)](https://coveralls.io/github/{{cookiecutter._owner}}/{{cookiecutter.project_name}}?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg){% if cookiecutter._generating_exemplar %} [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va){% endif %} +![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/{{owner}}/{{project_name}}/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/{{owner}}/{{project_name}}/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/{{owner}}/{{project_name}}/badge.svg?branch=main)](https://coveralls.io/github/{{owner}}/{{project_name}}?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg){% if generating_exemplar %} [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va){% endif %} -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} `beman.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md). This can be used as a template for those intending to write Beman libraries. It may also find use as a minimal and modern C++ project structure. {% else %} -`beman.{{cookiecutter.project_name}}` is (... TODO: description). +`beman.{{project_name}}` is (... TODO: description). {% endif %} -{% if cookiecutter._generating_exemplar %} -**Implements**: `std::identity` proposed in [Standard Library Concepts ({{cookiecutter.paper}})](https://wg21.link/{{cookiecutter.paper}}). +{% if generating_exemplar %} +**Implements**: `std::identity` proposed in [Standard Library Concepts ({{paper}})](https://wg21.link/{{paper}}). {% else %} -**Implements**: `std::todo` proposed in [TODO ({{cookiecutter.paper}})](https://wg21.link/{{cookiecutter.paper}}). +**Implements**: `std::todo` proposed in [TODO ({{paper}})](https://wg21.link/{{paper}}). {% endif %} **Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#under-development-and-not-yet-ready-for-production-use) ## License -`beman.{{cookiecutter.project_name}}` is licensed under the Apache License v2.0 with LLVM Exceptions. +`beman.{{project_name}}` is licensed under the Apache License v2.0 with LLVM Exceptions. ## Usage -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} `std::identity` is a function object type whose `operator()` returns its argument unchanged. `std::identity` serves as the default projection in constrained algorithms. Its direct usage is usually not needed. ### Usage: default projection in constrained algorithms -The following code snippet illustrates how we can achieve a default projection using `beman::{{cookiecutter.project_name}}::identity`: +The following code snippet illustrates how we can achieve a default projection using `beman::{{project_name}}::identity`: ```cpp -#include +#include -namespace exe = beman::{{cookiecutter.project_name}}; +namespace exe = beman::{{project_name}}; // Class with a pair of values. struct Pair @@ -145,11 +146,11 @@ Full runnable examples can be found in [`examples/`](examples/). This project requires at least the following to build: -* A C++ compiler that conforms to the C++{{cookiecutter.minimum_cpp_build_version}} standard or greater +* A C++ compiler that conforms to the C++{{minimum_cpp_build_version}} standard or greater * CMake 3.30 or later * (Test Only) GoogleTest -You can disable building tests by setting CMake option `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS` to +You can disable building tests by setting CMake option `BEMAN_{{project_name.upper()}}_BUILD_TESTS` to `OFF` when configuring the project. ### Supported Platforms @@ -170,11 +171,11 @@ You can disable building tests by setting CMake option `BEMAN_{{cookiecutter.pro See the [Contributing Guidelines](CONTRIBUTING.md). -## Integrate beman.{{cookiecutter.project_name}} into your project +## Integrate beman.{{project_name}} into your project ### Build -You can build {{cookiecutter.project_name}} using a CMake workflow preset: +You can build {{project_name}} using a CMake workflow preset: ```bash cmake --workflow --preset gcc-release @@ -186,23 +187,23 @@ To list available workflow presets, you can invoke: cmake --list-presets=workflow ``` -For details on building beman.{{cookiecutter.project_name}} without using a CMake preset, refer to the +For details on building beman.{{project_name}} without using a CMake preset, refer to the [Contributing Guidelines](CONTRIBUTING.md). ### Installation #### Vcpkg -The preferred way to install {{cookiecutter.project_name}} is via vcpkg. To do so, after installing vcpkg +The preferred way to install {{project_name}} is via vcpkg. To do so, after installing vcpkg itself, you need to add support for the Beman project's [vcpkg registry](https://github.com/bemanproject/vcpkg-registry) by configuring a -`vcpkg-configuration.json` file (which {{cookiecutter.project_name}} [provides](vcpkg-configuration.json)). +`vcpkg-configuration.json` file (which {{project_name}} [provides](vcpkg-configuration.json)). -Then, simply run `vcpkg install beman-{{cookiecutter.project_name.replace("_", "-")}}`. +Then, simply run `vcpkg install beman-{{project_name.replace("_", "-")}}`. #### Manual -To install beman.{{cookiecutter.project_name}} globally after building with the `gcc-release` preset, you can +To install beman.{{project_name}} globally after building with the `gcc-release` preset, you can run: ```bash @@ -221,47 +222,47 @@ This will generate the following directory structure: /opt/beman ├── include │ └── beman -│ └── {{cookiecutter.project_name}} -│ ├── {{cookiecutter.project_name}}.hpp +│ └── {{project_name}} +│ ├── {{project_name}}.hpp │ └── ... └── lib └── cmake - └── beman.{{cookiecutter.project_name}} - ├── beman.{{cookiecutter.project_name}}-config-version.cmake - ├── beman.{{cookiecutter.project_name}}-config.cmake - └── beman.{{cookiecutter.project_name}}-targets.cmake + └── beman.{{project_name}} + ├── beman.{{project_name}}-config-version.cmake + ├── beman.{{project_name}}-config.cmake + └── beman.{{project_name}}-targets.cmake ``` ### CMake Configuration -If you installed beman.{{cookiecutter.project_name}} to a prefix, you can specify that prefix to your CMake +If you installed beman.{{project_name}} to a prefix, you can specify that prefix to your CMake project using `CMAKE_PREFIX_PATH`; for example, `-DCMAKE_PREFIX_PATH=/opt/beman`. -You need to bring in the `beman.{{cookiecutter.project_name}}` package to define the `beman::{{cookiecutter.project_name}}` CMake +You need to bring in the `beman.{{project_name}}` package to define the `beman::{{project_name}}` CMake target: ```cmake -find_package(beman.{{cookiecutter.project_name}} REQUIRED) +find_package(beman.{{project_name}} REQUIRED) ``` -You will then need to add `beman::{{cookiecutter.project_name}}` to the link libraries of any libraries or -executables that include `beman.{{cookiecutter.project_name}}` headers. +You will then need to add `beman::{{project_name}}` to the link libraries of any libraries or +executables that include `beman.{{project_name}}` headers. ```cmake -target_link_libraries(yourlib PUBLIC beman::{{cookiecutter.project_name}}) +target_link_libraries(yourlib PUBLIC beman::{{project_name}}) ``` -### Using beman.{{cookiecutter.project_name}} +### Using beman.{{project_name}} -To use `beman.{{cookiecutter.project_name}}` in your C++ project, -include an appropriate `beman.{{cookiecutter.project_name}}` header from your source code. +To use `beman.{{project_name}}` in your C++ project, +include an appropriate `beman.{{project_name}}` header from your source code. ```c++ -#include +#include ``` > [!NOTE] > -> `beman.{{cookiecutter.project_name}}` headers are to be included with the `beman/{{cookiecutter.project_name}}/` prefix. +> `beman.{{project_name}}` headers are to be included with the `beman/{{project_name}}/` prefix. > Altering include search paths to spell the include target another way (e.g. -> `#include <{{cookiecutter.project_name}}.hpp>`) is unsupported. +> `#include <{{project_name}}.hpp>`) is unsupported. diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt b/template/examples/CMakeLists.txt.jinja similarity index 60% rename from cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt rename to template/examples/CMakeLists.txt.jinja index fddbf1fd..dc289913 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt +++ b/template/examples/CMakeLists.txt.jinja @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} set(ALL_EXAMPLES identity_direct_usage) # Example `identity_as_default_projection` need ranges support: @@ -22,15 +22,15 @@ set(ALL_EXAMPLES todo) message("Examples to be built: ${ALL_EXAMPLES}") foreach(example ${ALL_EXAMPLES}) - add_executable(beman.{{cookiecutter.project_name}}.examples.${example}) - target_sources(beman.{{cookiecutter.project_name}}.examples.${example} PRIVATE ${example}.cpp) + add_executable(beman.{{project_name}}.examples.${example}) + target_sources(beman.{{project_name}}.examples.${example} PRIVATE ${example}.cpp) target_link_libraries( - beman.{{cookiecutter.project_name}}.examples.${example} - PRIVATE beman::{{cookiecutter.project_name}} + beman.{{project_name}}.examples.${example} + PRIVATE beman::{{project_name}} ) - if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) + if(BEMAN_{{project_name.upper()}}_USE_MODULES) set_target_properties( - beman.{{cookiecutter.project_name}}.examples.${example} + beman.{{project_name}}.examples.${example} PROPERTIES CXX_MODULE_STD ON ) endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp b/template/examples/identity_as_default_projection.cpp.jinja similarity index 87% rename from cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp rename to template/examples/identity_as_default_projection.cpp.jinja index 20a95e8b..3007dfb5 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp +++ b/template/examples/identity_as_default_projection.cpp.jinja @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// This example demonstrates the usage of beman::{{cookiecutter.project_name}}::identity as a default projection in a range-printer. +// This example demonstrates the usage of beman::{{project_name}}::identity as a default projection in a range-printer. // Requires: range support (C++20) and std::identity support (C++20). -#include -#include +#include +#include -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() +#if BEMAN_{{project_name.upper()}}_USE_MODULES() import std; #else #include @@ -17,7 +17,7 @@ import std; #include #endif -namespace exe = beman::{{cookiecutter.project_name}}; +namespace exe = beman::{{project_name}}; // Class with a pair of values. struct Pair { diff --git a/template/examples/identity_direct_usage.cpp.jinja b/template/examples/identity_direct_usage.cpp.jinja new file mode 100644 index 00000000..e1985ad2 --- /dev/null +++ b/template/examples/identity_direct_usage.cpp.jinja @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% set identity = "identity" if generating_exemplar else "todo" %} + +#include +#include + +{% if generating_exemplar %} +#if BEMAN_{{project_name.upper()}}_USE_MODULES() +import std; +#else + #include +#endif + +namespace exe = beman::{{project_name}}; + +int main() { + std::cout << exe::identity()(2024) << '\n'; + return 0; +} +{% else %} +int main() { + // TODO +} +{% endif %} diff --git a/template/include/beman/{{ project_name }}/CMakeLists.txt.jinja b/template/include/beman/{{ project_name }}/CMakeLists.txt.jinja new file mode 100644 index 00000000..8853f4e3 --- /dev/null +++ b/template/include/beman/{{ project_name }}/CMakeLists.txt.jinja @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% set identity = "identity" if generating_exemplar else "todo" %} + +if(BEMAN_{{project_name.upper()}}_USE_MODULES) + target_sources( + beman.{{project_name}} + PUBLIC + FILE_SET CXX_MODULES FILES {{project_name}}.cppm + FILE_SET HEADERS + FILES + config.hpp + {{project_name}}.hpp + {{identity}}.hpp + "${PROJECT_BINARY_DIR}/include/beman/{{project_name}}/config_generated.hpp" + ) +else() + target_sources( + beman.{{project_name}} + PUBLIC + FILE_SET HEADERS + FILES + config.hpp + {{project_name}}.hpp + {{identity}}.hpp + "${PROJECT_BINARY_DIR}/include/beman/{{project_name}}/config_generated.hpp" + ) +endif() diff --git a/template/include/beman/{{ project_name }}/config.hpp.jinja b/template/include/beman/{{ project_name }}/config.hpp.jinja new file mode 100644 index 00000000..7761e19b --- /dev/null +++ b/template/include/beman/{{ project_name }}/config.hpp.jinja @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_{{project_name.upper()}}_CONFIG_HPP +#define BEMAN_{{project_name.upper()}}_CONFIG_HPP + +#if !defined(__has_include) || __has_include() + #include +#else + #define BEMAN_{{project_name.upper()}}_USE_MODULES() 0 +#endif + +#endif diff --git a/template/include/beman/{{ project_name }}/config_generated.hpp.in.jinja b/template/include/beman/{{ project_name }}/config_generated.hpp.in.jinja new file mode 100644 index 00000000..6b296ed1 --- /dev/null +++ b/template/include/beman/{{ project_name }}/config_generated.hpp.in.jinja @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_{{project_name.upper()}}_CONFIG_GENERATED_HPP +#define BEMAN_{{project_name.upper()}}_CONFIG_GENERATED_HPP + +#cmakedefine01 BEMAN_{{project_name.upper()}}_USE_MODULES() + +#endif diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp b/template/include/beman/{{ project_name }}/identity.hpp.jinja similarity index 52% rename from cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp rename to template/include/beman/{{ project_name }}/identity.hpp.jinja index bdea366c..71d8773a 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp +++ b/template/include/beman/{{ project_name }}/identity.hpp.jinja @@ -1,18 +1,18 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} +{% set identity = "identity" if generating_exemplar else "todo" %} -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_{{identity.upper()}}_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_{{identity.upper()}}_HPP +#ifndef BEMAN_{{project_name.upper()}}_{{identity.upper()}}_HPP +#define BEMAN_{{project_name.upper()}}_{{identity.upper()}}_HPP -#include +#include -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) +#if BEMAN_{{project_name.upper()}}_USE_MODULES() && !defined(BEMAN_{{project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) -import beman.{{cookiecutter.project_name}}; +import beman.{{project_name}}; #else -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} // C++ Standard Library: std::identity equivalent. // See https://eel.is/c++draft/func.identity: // @@ -35,9 +35,9 @@ import beman.{{cookiecutter.project_name}}; #endif {% endif %} -namespace beman::{{cookiecutter.project_name}} { +namespace beman::{{project_name}} { -{% if cookiecutter._generating_exemplar %} +{% if generating_exemplar %} struct __is_transparent; // not defined // A function object that returns its argument unchanged. @@ -55,9 +55,9 @@ struct identity { // TODO {% endif %} -} // namespace beman::{{cookiecutter.project_name}} +} // namespace beman::{{project_name}} -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && - // !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) +#endif // BEMAN_{{project_name.upper()}}_USE_MODULES() && + // !defined(BEMAN_{{project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_{{identity.upper()}}_HPP +#endif // BEMAN_{{project_name.upper()}}_{{identity.upper()}}_HPP diff --git a/template/include/beman/{{ project_name }}/{{ project_name }}.cppm.jinja b/template/include/beman/{{ project_name }}/{{ project_name }}.cppm.jinja new file mode 100644 index 00000000..ef9b3751 --- /dev/null +++ b/template/include/beman/{{ project_name }}/{{ project_name }}.cppm.jinja @@ -0,0 +1,11 @@ +export module beman.{{project_name}}; + +import std; + +#define BEMAN_{{project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT +export { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#include +#pragma clang diagnostic pop +} diff --git a/template/include/beman/{{ project_name }}/{{ project_name }}.hpp.jinja b/template/include/beman/{{ project_name }}/{{ project_name }}.hpp.jinja new file mode 100644 index 00000000..6de86a51 --- /dev/null +++ b/template/include/beman/{{ project_name }}/{{ project_name }}.hpp.jinja @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% set identity = "identity" if generating_exemplar else "todo" %} + +#ifndef BEMAN_{{project_name.upper()}}_{{project_name.upper()}}_HPP +#define BEMAN_{{project_name.upper()}}_{{project_name.upper()}}_HPP + +#include + +#if BEMAN_{{project_name.upper()}}_USE_MODULES() && !defined(BEMAN_{{project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) + +import beman.{{project_name}}; + +#else + + #include + +#endif // BEMAN_{{project_name.upper()}}_USE_MODULES() && + // !defined(BEMAN_{{project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) + +#endif // BEMAN_{{project_name.upper()}}_{{project_name.upper()}}_HPP diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule b/template/infra/.beman_submodule.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule rename to template/infra/.beman_submodule.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS b/template/infra/.github/CODEOWNERS.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS rename to template/infra/.github/CODEOWNERS.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml b/template/infra/.github/workflows/pre-commit.yml.jinja similarity index 99% rename from cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml rename to template/infra/.github/workflows/pre-commit.yml.jinja index 7051c132..2b420387 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml +++ b/template/infra/.github/workflows/pre-commit.yml.jinja @@ -1,4 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% raw %} name: Lint Check (pre-commit) on: @@ -77,3 +78,4 @@ jobs: tool_name: pre-commit level: warning reviewdog_flags: "-fail-level=error" +{% endraw %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml b/template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja similarity index 98% rename from cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml rename to template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja index 024a51f4..bc7bbec4 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml +++ b/template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja @@ -1,4 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% raw %} name: 'Beman issue creation workflow' on: @@ -26,3 +27,4 @@ jobs: fi env: GH_TOKEN: ${{ github.token }} +{% endraw %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore b/template/infra/.gitignore.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore rename to template/infra/.gitignore.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml b/template/infra/.pre-commit-config.yaml.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml rename to template/infra/.pre-commit-config.yaml.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE b/template/infra/LICENSE.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE rename to template/infra/LICENSE.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/README.md b/template/infra/README.md.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/README.md rename to template/infra/README.md.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake b/template/infra/cmake/BuildTelemetry.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake rename to template/infra/cmake/BuildTelemetry.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake b/template/infra/cmake/BuildTelemetryConfig.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake rename to template/infra/cmake/BuildTelemetryConfig.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in b/template/infra/cmake/Config.cmake.in.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in rename to template/infra/cmake/Config.cmake.in.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake b/template/infra/cmake/appleclang-toolchain.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake rename to template/infra/cmake/appleclang-toolchain.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake b/template/infra/cmake/beman-install-library.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake rename to template/infra/cmake/beman-install-library.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake b/template/infra/cmake/enable-experimental-import-std.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake rename to template/infra/cmake/enable-experimental-import-std.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake b/template/infra/cmake/gnu-toolchain.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake rename to template/infra/cmake/gnu-toolchain.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake b/template/infra/cmake/llvm-libc++-toolchain.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake rename to template/infra/cmake/llvm-libc++-toolchain.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake b/template/infra/cmake/llvm-toolchain.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake rename to template/infra/cmake/llvm-toolchain.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake b/template/infra/cmake/msvc-toolchain.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake rename to template/infra/cmake/msvc-toolchain.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh b/template/infra/cmake/telemetry.sh.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh rename to template/infra/cmake/telemetry.sh.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake b/template/infra/cmake/use-fetch-content.cmake.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake rename to template/infra/cmake/use-fetch-content.cmake.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/lockfile.json b/template/lockfile.json.jinja similarity index 82% rename from cookiecutter/{{cookiecutter.project_name}}/lockfile.json rename to template/lockfile.json.jinja index f3388cff..cbd6495e 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/lockfile.json +++ b/template/lockfile.json.jinja @@ -1,6 +1,6 @@ { "dependencies": [ -{% if cookiecutter.unit_test_library == "gtest" %} +{% if unit_test_library == "gtest" %} { "name": "googletest", "package_name": "GTest", @@ -10,7 +10,7 @@ "INSTALL_GTEST": "OFF" } } -{% elif cookiecutter.unit_test_library == "catch2" %} +{% elif unit_test_library == "catch2" %} { "name": "Catch2", "package_name": "Catch2", diff --git a/cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in b/template/port/portfile.cmake.in.jinja similarity index 61% rename from cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in rename to template/port/portfile.cmake.in.jinja index 1f13b31b..107c2f44 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in +++ b/template/port/portfile.cmake.in.jinja @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO bemanproject/{{cookiecutter.project_name}} + REPO bemanproject/{{project_name}} REF "v@VERSION@" SHA512 @SHA512@ HEAD_REF main @@ -10,22 +10,22 @@ vcpkg_from_github( vcpkg_check_features( OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES - modules BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES + modules BEMAN_{{project_name.upper()}}_USE_MODULES ) vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS ${FEATURE_OPTIONS} - -DBEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS=OFF - -DBEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES=OFF + -DBEMAN_{{project_name.upper()}}_BUILD_TESTS=OFF + -DBEMAN_{{project_name.upper()}}_BUILD_EXAMPLES=OFF ) vcpkg_cmake_install() vcpkg_cmake_config_fixup( - PACKAGE_NAME beman.{{cookiecutter.project_name}} - CONFIG_PATH lib/cmake/beman.{{cookiecutter.project_name}} + PACKAGE_NAME beman.{{project_name}} + CONFIG_PATH lib/cmake/beman.{{project_name}} ) if(NOT "modules" IN_LIST FEATURES) diff --git a/cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in b/template/port/vcpkg.json.in.jinja similarity index 50% rename from cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in rename to template/port/vcpkg.json.in.jinja index 81a58a5a..36836ffe 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in +++ b/template/port/vcpkg.json.in.jinja @@ -1,8 +1,8 @@ { - "name": "beman-{{cookiecutter.project_name.replace('_', '-')}}", + "name": "beman-{{project_name.replace('_', '-')}}", "version-semver": "@VERSION@", - "description": "{{cookiecutter.description}}", - "homepage": "https://github.com/bemanproject/{{cookiecutter.project_name}}", + "description": "{{description}}", + "homepage": "https://github.com/bemanproject/{{project_name}}", "license": "Apache-2.0 WITH LLVM-exception", "dependencies": [ { @@ -16,7 +16,7 @@ ], "features": { "modules": { - "description": "Provide beman.{{cookiecutter.project_name}} as a C++ module" + "description": "Provide beman.{{project_name}} as a C++ module" } } } diff --git a/template/tests/beman/{{ project_name }}/CMakeLists.txt.jinja b/template/tests/beman/{{ project_name }}/CMakeLists.txt.jinja new file mode 100644 index 00000000..d36cf0a2 --- /dev/null +++ b/template/tests/beman/{{ project_name }}/CMakeLists.txt.jinja @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% set identity = "identity" if generating_exemplar else "todo" %} + +{% if unit_test_library == "gtest" %} +find_package(GTest REQUIRED) +{% elif unit_test_library == "catch2" %} +find_package(Catch2 3 REQUIRED) +{% endif %} + +add_executable(beman.{{project_name}}.tests.{{identity}}) +target_sources(beman.{{project_name}}.tests.{{identity}} PRIVATE {{identity}}.test.cpp) +target_link_libraries( + beman.{{project_name}}.tests.{{identity}} +{% if unit_test_library == "gtest" %} + PRIVATE beman::{{project_name}} GTest::gtest_main +{% elif unit_test_library == "catch2" %} + PRIVATE beman::{{project_name}} Catch2::Catch2WithMain +{% endif %} +) +if(BEMAN_EXEMPLAR_USE_MODULES) + set_target_properties( + beman.{{project_name}}.tests.{{identity}} + PROPERTIES CXX_MODULE_STD ON + ) +endif() + +{% if unit_test_library == "gtest" %} +include(GoogleTest) +gtest_discover_tests(beman.{{project_name}}.tests.{{identity}} DISCOVERY_TIMEOUT 60) +{% elif unit_test_library == "catch2" %} +include(Catch) +catch_discover_tests(beman.{{project_name}}.tests.{{identity}}) +{% endif %} diff --git a/template/tests/beman/{{ project_name }}/identity.test.cpp.jinja b/template/tests/beman/{{ project_name }}/identity.test.cpp.jinja new file mode 100644 index 00000000..57b6581b --- /dev/null +++ b/template/tests/beman/{{ project_name }}/identity.test.cpp.jinja @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +{% set identity = "identity" if generating_exemplar else "todo" %} + +#include +{% if unit_test_library == "gtest" %} +#include +{% elif unit_test_library == "catch2" %} +#include +{% endif %} +#include + +{% if generating_exemplar %} +#if BEMAN_EXEMPLAR_USE_MODULES() +import std; +#else + #include + #include +#endif + +namespace exe = beman::{{project_name}}; + +{% if unit_test_library == "gtest" %} +TEST(IdentityTest, call_identity_with_int) { +{% elif unit_test_library == "catch2" %} +TEST_CASE("can call identity with int", "[{{project_name}}::call_identity_with_int]") { +{% endif %} + for (int i = -100; i < 100; ++i) { +{% if unit_test_library == "gtest" %} + EXPECT_EQ(i, exe::identity()(i)); +{% elif unit_test_library == "catch2" %} + CHECK(i == exe::identity()(i)); +{% endif %} + } +} + +{% if unit_test_library == "gtest" %} +TEST(IdentityTest, call_identity_with_custom_type) { +{% elif unit_test_library == "catch2" %} +TEST_CASE("can call identity with custom type", "[{{project_name}}::call_identity_with_custom_type]") { +{% endif %} + struct S { + int i; + }; + + for (int i = -100; i < 100; ++i) { + const S s{i}; + const S s_id = exe::identity()(s); +{% if unit_test_library == "gtest" %} + EXPECT_EQ(s.i, s_id.i); +{% elif unit_test_library == "catch2" %} + CHECK(s.i == s_id.i); +{% endif %} + } +} + +{% if unit_test_library == "gtest" %} +TEST(IdentityTest, compare_std_vs_beman) { +{% elif unit_test_library == "catch2" %} +TEST_CASE("compare std vs beman", "[{{project_name}}::compare_std_vs_beman]") { +{% endif %} +// Requires: std::identity support. +#if defined(__cpp_lib_type_identity) + std::identity std_id; + exe::identity beman_id; + for (int i = -100; i < 100; ++i) { +{% if unit_test_library == "gtest" %} + EXPECT_EQ(std_id(i), beman_id(i)); +{% elif unit_test_library == "catch2" %} + CHECK(std_id(i) == beman_id(i)); +{% endif %} + } +#endif +} + +{% if unit_test_library == "gtest" %} +TEST(IdentityTest, check_is_transparent) { +{% elif unit_test_library == "catch2" %} +TEST_CASE("check is transparent", "[{{project_name}}::check_is_transparent]") { +{% endif %} +// Requires: transparent operators support. +#if defined(__cpp_lib_transparent_operators) + + exe::identity id; + + const auto container = {1, 2, 3, 4, 5}; + auto it = std::find(std::begin(container), std::end(container), 3); +{% if unit_test_library == "gtest" %} + EXPECT_EQ(3, *it); +{% elif unit_test_library == "catch2" %} + CHECK(3 == *it); +{% endif %} + auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); +{% if unit_test_library == "gtest" %} + EXPECT_EQ(3, *it_with_id); + + EXPECT_EQ(it, it_with_id); +{% elif unit_test_library == "catch2" %} + CHECK(3 == *it_with_id); + + CHECK(it == it_with_id); +{% endif %} +#endif +} +{% else %} +{% if unit_test_library == "gtest" %} +TEST(TodoTest, todo) { +{% elif unit_test_library == "catch2" %} +TEST_CASE("todo", "[{{project_name}}::todo]") { +{% endif %} + const bool todo = true; +{% if unit_test_library == "gtest" %} + EXPECT_TRUE(todo); +{% elif unit_test_library == "catch2" %} + CHECK(todo); +{% endif %} +} +{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json b/template/vcpkg-configuration.json.jinja similarity index 100% rename from cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json rename to template/vcpkg-configuration.json.jinja diff --git a/cookiecutter/{{cookiecutter.project_name}}/vcpkg.json b/template/vcpkg.json.jinja similarity index 54% rename from cookiecutter/{{cookiecutter.project_name}}/vcpkg.json rename to template/vcpkg.json.jinja index 89ea514f..24970d1d 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/vcpkg.json +++ b/template/vcpkg.json.jinja @@ -1,18 +1,18 @@ { - "name": "beman-{{cookiecutter.project_name.replace('_', '-')}}", -{% if cookiecutter._generating_exemplar %} + "name": "beman-{{project_name.replace('_', '-')}}", +{% if generating_exemplar %} "version-semver": "2.4.0", {% else %} "version-semver": "0.1.0", {% endif %} -{% if cookiecutter.unit_test_library == "gtest" %} +{% if unit_test_library == "gtest" %} "dependencies": [ { "name": "gtest", "host": true } ] -{% elif cookiecutter.unit_test_library == "catch2" %} +{% elif unit_test_library == "catch2" %} "dependencies": [ { "name": "catch2", From ca64c2ac841eaf3071aa0802b05531cc9da78d0d Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Tue, 5 May 2026 16:28:59 -0600 Subject: [PATCH 02/29] Document the Copier template workflow --- CONTRIBUTING.md | 38 ++++++++++++++++++++++++++++++++++++++ README.md | 30 ++++++++++++++++++++++++++++-- stamp.sh | 10 ++++++---- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42e2f3d8..ee722098 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,6 +106,44 @@ ctest --test-dir build The file `./lockfile.json` configures the list of dependencies and versions that will be acquired by FetchContent. +## Developing The Copier Template + +This repository doubles as both the exemplar library and the Copier template used to stamp +new Beman libraries. + +The template workflow is organized as follows: + +* `copier.yml` defines the Copier questions, defaults, validation rules, and post-copy + tasks. +* `template/` contains the files rendered into generated projects. +* `stamp.sh` is the user-facing wrapper for stamping a forked exemplar repository into a + new project. +* `./copier/check_copier.sh` validates that exemplar regenerates cleanly and that a + non-exemplar project does not leak exemplar-specific names like `identity`. + +When testing local template changes, do not render directly from the Git checkout. The +Copier helper scripts intentionally render from a temporary snapshot with `.git`, `build`, +and `.venv` excluded so that validation uses the current worktree contents. + +Run the template checks with: + +```shell +./copier/check_copier.sh +``` + +If you need to smoke-test generated projects manually, start from the same validated flow: + +```shell +tmpdir=$(mktemp -d) +python3 -m venv "$tmpdir/venv" +"$tmpdir/venv/bin/python3" -m pip install copier +src=$(mktemp -d) +rsync -a --exclude .git --exclude build --exclude .venv ./ "$src/" +"$tmpdir/venv/bin/copier" copy --trust --defaults "$src" "$tmpdir/project" +``` + +Then configure and build the generated project as usual. + ## Project-specific configure arguments Project-specific options are prefixed with `BEMAN_EXEMPLAR`. diff --git a/README.md b/README.md index 04196dfc..57c5c7e0 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,23 @@ To create a new Beman library, first click the "Use this template" dropdown in t top-right and select "Create a new repository":
- + GitHub Use this template button
This will create a new repository that's an exact copy of exemplar. The next step is to customize it for your use case. +This repository now uses Copier as its templating engine. The template inputs are defined +in `copier.yml`, the rendered project files live under `template/`, and +`./copier/check_copier.sh` verifies that the repository still round-trips through Copier +correctly. + To do so, execute the bash script `stamp.sh`. This script will prompt for parameters like the new library's name, paper number, and description. Then it will replace your exemplar copy with a stamped-out template containing these parameters and create a corresponding git commit and branch: -``` +```shell $ ./stamp.sh [1/6] project_name (my_project_name): example_library [2/6] maintainer (your_github_username): your_username @@ -33,11 +38,16 @@ Try 'git push origin stamp' to push the branch upstream, then create a pull request. ``` +`stamp.sh` is a convenience wrapper around `copier copy`. It creates an isolated virtual +environment, renders from a temporary snapshot of the repository, runs `pre-commit`, and +commits the stamped result onto a `stamp` branch. + From there, you can simply fill in all the remaining parts of the repository that are labeled 'todo'. What follow is an example of a Beman library README. + # beman.exemplar: A Beman Library Exemplar {% endif %} # beman.{{project_name}}: {{description}} @@ -171,6 +233,23 @@ You can disable building tests by setting CMake option `BEMAN_{{project_name.upp See the [Contributing Guidelines](CONTRIBUTING.md). +{% if generating_exemplar %}### Template Maintenance + +If you are changing the template itself rather than developing the exemplar library, use +the Copier workflow directly: + +* Edit `copier.yml` for template questions, defaults, validators, and post-copy tasks. +* Edit `template/` for files that should be rendered into stamped projects. +* Run `./copier/check_copier.sh` to verify exemplar self-regeneration and non-exemplar + templating. +* Use `./stamp.sh` on a fork when you want to replace an exemplar clone with a stamped + project for real work. + +The consistency check and `stamp.sh` both render from a `.git`-free temporary snapshot of +the repository. That keeps local validation aligned with the current worktree contents, +rather than only the last committed Git state. +{% endif %} + ## Integrate beman.{{project_name}} into your project ### Build From a141226a9b79ad413210d6de5b8a1799902636f1 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 18 May 2026 19:03:37 -0400 Subject: [PATCH 04/29] Remove merge artifact Accidentally recreated the cookiecutter CODEOWNERS file. This should not be part of the copier branch, but it was accidentally added in a merge commit. This commit removes the file from the copier branch, which is the correct state for that branch. --- .../{{cookiecutter.project_name}}/.github/CODEOWNERS | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS b/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS deleted file mode 100644 index cced7b37..00000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -{% if cookiecutter._generating_exemplar %} -* @ednolan @bretbrownjr @camio @dietmarkuehl @steve-downey @wusatosi -{% else %} -* @{{ cookiecutter.maintainer }} -{% endif %} From 8d03085277828e7d4771be5e489dcef034e65c10 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 18 May 2026 19:26:38 -0400 Subject: [PATCH 05/29] Revert some white space changes in infra/ Some yaml files were slightly reformatted, leaving beman-submodule failing in CI. --- infra/.github/workflows/pre-commit.yml | 1 - .../.github/workflows/reusable-beman-create-issue-when-fault.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/infra/.github/workflows/pre-commit.yml b/infra/.github/workflows/pre-commit.yml index e54a1ea8..7051c132 100644 --- a/infra/.github/workflows/pre-commit.yml +++ b/infra/.github/workflows/pre-commit.yml @@ -1,5 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - name: Lint Check (pre-commit) on: diff --git a/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml b/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml index 6e9b6e0d..024a51f4 100644 --- a/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml +++ b/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - name: 'Beman issue creation workflow' on: workflow_call: From 896e55d1f0538fd7ebebd85916cadde39b411e43 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 18 May 2026 19:38:44 -0400 Subject: [PATCH 06/29] Whitespace in copier templates Use the {%- raw -%} forms to control whitespace. Also use -u for diff to show the "unified" format, which is easier to read. --- copier/check_copier.sh | 2 +- template/infra/.github/workflows/pre-commit.yml.jinja | 3 ++- .../workflows/reusable-beman-create-issue-when-fault.yml.jinja | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/copier/check_copier.sh b/copier/check_copier.sh index eecdda1d..7696f098 100755 --- a/copier/check_copier.sh +++ b/copier/check_copier.sh @@ -72,7 +72,7 @@ check_consistency() { stamp "$repo_root" "$output_dir" "gtest" "true" local diff_path="$work_dir/default.diff" - diff -r \ + diff -u -r \ --exclude .git \ --exclude build \ --exclude .venv \ diff --git a/template/infra/.github/workflows/pre-commit.yml.jinja b/template/infra/.github/workflows/pre-commit.yml.jinja index 2b420387..5f9ae08c 100644 --- a/template/infra/.github/workflows/pre-commit.yml.jinja +++ b/template/infra/.github/workflows/pre-commit.yml.jinja @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% raw %} +{% raw -%} + name: Lint Check (pre-commit) on: diff --git a/template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja b/template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja index bc7bbec4..4e3117aa 100644 --- a/template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja +++ b/template/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml.jinja @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception {% raw %} - name: 'Beman issue creation workflow' on: workflow_call: From c3520e6dd9aca37bdd49678fdfdbc85f51755ff6 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Thu, 21 May 2026 17:11:12 -0400 Subject: [PATCH 07/29] remove template for answers --- template/.copier-answers.yml.jinja | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 template/.copier-answers.yml.jinja diff --git a/template/.copier-answers.yml.jinja b/template/.copier-answers.yml.jinja deleted file mode 100644 index 7b304815..00000000 --- a/template/.copier-answers.yml.jinja +++ /dev/null @@ -1,12 +0,0 @@ -_commit: {{ template_commit | to_json }} -_src_path: {{ template_src_path | to_json }} -project_name: {{ project_name | to_json }} -maintainer: {{ maintainer | to_json }} -minimum_cpp_build_version: {{ minimum_cpp_build_version | to_json }} -paper: {{ paper | to_json }} -description: {{ description | to_json }} -unit_test_library: {{ unit_test_library | to_json }} -generating_exemplar: {{ generating_exemplar | to_json }} -owner: {{ owner | to_json }} -ci_tests_cron: {{ ci_tests_cron | to_json }} -pre_commit_update_cron: {{ pre_commit_update_cron | to_json }} From b509aa8a327c6f9a9b0dfcab1311f01a39004f7f Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Thu, 21 May 2026 17:15:28 -0400 Subject: [PATCH 08/29] fix template answers --- template/.copier-answers.yml.jinja | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 template/.copier-answers.yml.jinja diff --git a/template/.copier-answers.yml.jinja b/template/.copier-answers.yml.jinja new file mode 100644 index 00000000..69141bbf --- /dev/null +++ b/template/.copier-answers.yml.jinja @@ -0,0 +1,2 @@ +# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY +{{ _copier_answers|to_nice_yaml -}} From e12e9d58a11174668ccf38336a8a3a209d8a8eac Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Thu, 21 May 2026 17:21:09 -0400 Subject: [PATCH 09/29] put conditional answers into the answers file --- template/.copier-answers.yml.jinja | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/template/.copier-answers.yml.jinja b/template/.copier-answers.yml.jinja index 69141bbf..cefabb93 100644 --- a/template/.copier-answers.yml.jinja +++ b/template/.copier-answers.yml.jinja @@ -1,2 +1,8 @@ -# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -{{ _copier_answers|to_nice_yaml -}} +# Standard answers and internal state managed by Copier +{{ _copier_answers | to_nice_yaml -}} + +# Hidden variables manually tracked because 'when: false' omits them from _copier_answers +generating_exemplar: {{ generating_exemplar | to_json }} +owner: {{ owner | to_json }} +ci_tests_cron: {{ ci_tests_cron | to_json }} +pre_commit_update_cron: {{ pre_commit_update_cron | to_json }} From a8a22b137c332dbb2c5c6dcb44ee832ef42faacf Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Thu, 21 May 2026 22:28:47 -0400 Subject: [PATCH 10/29] fix defaults to persist --- copier.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/copier.yml b/copier.yml index e424ceaf..5bb42792 100644 --- a/copier.yml +++ b/copier.yml @@ -58,22 +58,22 @@ unit_test_library: generating_exemplar: type: bool when: false - default: false + default: "{{ generating_exemplar | default(false) }}" owner: type: str when: false - default: bemanproject + default: "{{ owner | default('bemanproject') }}" ci_tests_cron: type: str when: false - default: "" + default: "{{ ci_tests_cron | default('') }}" pre_commit_update_cron: type: str when: false - default: "" + default: "{{ pre_commit_update_cron | default('') }}" _tasks: - >- From debcfd409e61b6c78018a80fdc44148b5e09f16b Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Fri, 22 May 2026 11:56:28 -0400 Subject: [PATCH 11/29] Randomize the cron settings once Move the randomization into copier.yml and remember the results for future updates. Move the randomization out of the github action templates. --- copier.yml | 18 ++++++++++++++++-- template/.github/workflows/ci_tests.yml.jinja | 3 +-- .../workflows/pre-commit-update.yml.jinja | 3 +-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/copier.yml b/copier.yml index 5bb42792..a3503542 100644 --- a/copier.yml +++ b/copier.yml @@ -68,12 +68,26 @@ owner: ci_tests_cron: type: str when: false - default: "{{ ci_tests_cron | default('') }}" + # If a cron was already saved in .copier-answers.yml, reuse it to prevent + # merge conflicts on update. Otherwise, generate a random one to spread + # CI load across all Beman projects. + default: >- + {%- if ci_tests_cron is defined and ci_tests_cron != "" -%} + {{ ci_tests_cron }} + {%- else -%} + {{ range(0, 59)|random }} {{ range(0, 23)|random }} * * {{ range(0, 6)|random }} + {%- endif -%} pre_commit_update_cron: type: str when: false - default: "{{ pre_commit_update_cron | default('') }}" + # Same logic as above: reuse existing or generate random. + default: >- + {%- if pre_commit_update_cron is defined and pre_commit_update_cron != "" -%} + {{ pre_commit_update_cron }} + {%- else -%} + {{ range(0, 59)|random }} {{ range(0, 23)|random }} * * {{ range(0, 6)|random }} + {%- endif -%} _tasks: - >- diff --git a/template/.github/workflows/ci_tests.yml.jinja b/template/.github/workflows/ci_tests.yml.jinja index 466a2750..e00c6ff5 100644 --- a/template/.github/workflows/ci_tests.yml.jinja +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -9,8 +9,7 @@ on: pull_request: workflow_dispatch: schedule: - - cron: '{% if ci_tests_cron %}{{ ci_tests_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}' - + - cron: '{{ ci_tests_cron }}' concurrency: group: {% raw %}${{format('{0}:{1}', github.repository, github.ref)}}{% endraw %} diff --git a/template/.github/workflows/pre-commit-update.yml.jinja b/template/.github/workflows/pre-commit-update.yml.jinja index 3c422151..7410a65b 100644 --- a/template/.github/workflows/pre-commit-update.yml.jinja +++ b/template/.github/workflows/pre-commit-update.yml.jinja @@ -5,7 +5,7 @@ name: Weekly pre-commit autoupdate on: workflow_dispatch: schedule: - - cron: "{% if pre_commit_update_cron %}{{ pre_commit_update_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}" + - cron: '{{pre_commit_update_cron}}' {% raw -%} jobs: @@ -15,4 +15,3 @@ jobs: APP_ID: ${{ secrets.AUTO_PR_BOT_APP_ID }} PRIVATE_KEY: ${{ secrets.AUTO_PR_BOT_PRIVATE_KEY }} {%- endraw %} - From 7f9055ca5b37db5996bcaabed9b8a3c3443f01d3 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Fri, 22 May 2026 14:54:28 -0400 Subject: [PATCH 12/29] Update README and stamp.sh Provide new directions to replace `stamp.sh` and describe the intented lifecycle workflow of a generated Beman project. --- README.md | 179 ++++++++++++++++++++++++++++++++---------------------- stamp.sh | 5 ++ 2 files changed, 110 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index bf4a1f48..b5fbe989 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,105 @@ # How to Use This Template -To create a new Beman library, first click the "Use this template" dropdown in the -top-right and select "Create a new repository": +This repository uses [Copier](https://copier.readthedocs.io/) as its templating engine to generate, manage, and update Beman library boilerplate. The template inputs are defined in `copier.yml`, and the rendered project files live under `template/`. -
- GitHub Use this template button -
+> [!NOTE] +> ?? **`stamp.sh` is deprecated.** If you are used to the legacy workflow of forking this repository and running `./stamp.sh`, please transition to the natively supported `copier` workflow below. The script remains for legacy CI compatibility but will not receive future updates. -This will create a new repository that's an exact copy of exemplar. The next step is to -customize it for your use case. +## ? Quick Start: Create a New Library -This repository now uses Copier as its templating engine. The template inputs are defined -in `copier.yml`, the rendered project files live under `template/`, and -`./copier/check_copier.sh` verifies that the repository still round-trips through Copier -correctly. +If you are already familiar with the Beman project lifecycle, you can generate a new library immediately using `uvx` (via the [uv package manager](https://docs.astral.sh/uv/)): -To do so, execute the bash script `stamp.sh`. This script will prompt for parameters like -the new library's name, paper number, and description. Then it will replace your exemplar -copy with a stamped-out template containing these parameters and create a corresponding -git commit and branch: +```bash +uvx --from copier copier copy "git+[https://github.com/bemanproject/exemplar.git](https://github.com/bemanproject/exemplar.git)" my-new-library +cd my-new-library +git init +git add . +git commit -m "Initial commit from Beman Exemplar template" +uvx pre-commit install +``` -```shell -$ ./stamp.sh - [1/6] project_name (my_project_name): example_library - [2/6] maintainer (your_github_username): your_username - [3/6] minimum_cpp_build_version (20): - [4/6] paper (PnnnnRr): P9999R9 - [5/6] description (Short project description.): - unit_test_library? Format: str - Choices: - - gtest - - catch2 - > gtest -Switched to a new branch 'stamp' -Successfully stamped out exemplar template to the new branch 'stamp'. -Try 'git push origin stamp' to push the branch upstream, -then create a pull request. +--- + +## ?? The Beman Project Lifecycle + +To create a new library and get it officially adopted into the Beman project, you will generate the project locally, push it to your personal GitHub for active development, and eventually transfer it to the `bemanproject` organization. + +> **Why this specific workflow?** +> Developing on your personal account first gives you a sandbox to experiment and clean up your Git history. Transferring the repository (rather than creating it directly in the org) ensures the `bemanproject` organization ultimately holds the canonical, unbroken Git history, which prevents downstream forks from breaking later. + +### Step 1: Push to Your Personal GitHub +After running the Quick Start commands above, push the fresh template to your personal account to begin development. + +**Option A: Using the GitHub CLI (`gh`)** +```bash +gh repo create my-new-library --public --source=. --remote=origin --push ``` -`stamp.sh` is a convenience wrapper around `copier copy`. It creates an isolated virtual -environment, renders from a temporary snapshot of the repository, runs `pre-commit`, and -commits the stamped result onto a `stamp` branch. The stamped tree now includes -`.copier-answers.yml`, so future `copier update` runs know which exemplar revision they -started from. +**Option B: Using the GitHub Browser Interface** +1. [Create a new repository](https://github.com/new). Name it exactly what you named your local folder. Leave it completely empty. +2. Link and push your local code: + ```bash + git remote add origin [https://github.com/](https://github.com/)/my-new-library.git + git branch -M main + git push -u origin main + ``` + +### Step 2: Incubation & Implementation +Before transferring the project to the Beman organization, take the time to build out the actual proposal. +* Expand beyond the default placeholder headers (e.g., `my-new-library.hpp`). +* Stub out the necessary files for your library's domain. +* Write out the skeleton of the library's design and documentation. +* *Optional:* Once you have a working sandbox, feel free to squash or clean up your Git history using an interactive rebase (`git rebase -i`) before handing it over. + +### Step 3: Transfer to the Beman Project +Once the repository has enough substance to be reviewed or collaborated on, hand it over to the organization to establish it as the canonical source. + +1. On your GitHub repository page, go to **Settings** > **General**. +2. Scroll to the bottom to the **Danger Zone** and click **Transfer ownership**. +3. Type `bemanproject` as the new owner and confirm. + +### Step 4: Fork It Back for Ongoing Development +Now that `bemanproject/my-new-library` is the official upstream repository, standard open-source contribution rules apply. + +1. Navigate to the new URL: `https://github.com/bemanproject/my-new-library`. +2. Click **Fork** in the top right corner to create a fork in your personal namespace. +3. Update your local repository's remotes so you can pull from upstream and push to your new fork: + ```bash + # Rename your current remote (the org repo) to 'upstream' + git remote rename origin upstream + + # Add your new personal fork as 'origin' + git remote add origin [https://github.com/](https://github.com/)/my-new-library.git + ``` + +--- + +## ?? Reconfiguring or Renaming Your Project + +One of the biggest advantages of using `copier` is that it actively maintains your project's boilerplate. If you start out with a placeholder name and later decide to rename your library (or change your minimum C++ version), you can instruct Copier to update the structural boilerplate using the `--data` flag. + +For example, to rename your project to `range_discombobulator`: + +```bash +uvx --from copier copier update --trust --skip-answered --data project_name=range_discombobulator +``` + +**What this does:** +* `--data project_name=...`: Overrides your previous answer for the project name. +* `--skip-answered`: Skips the interactive prompt for all the questions you aren't changing. + +Copier will calculate the difference and automatically update the template-provided files—renaming CMake configurations, GitHub Actions matrices, standard folder paths, and core macros. + +?? **Important Caveat:** Copier only manages the files it originally generated. If you have added custom files (like `detail/internal.hpp`), or manually typed the old project name into new C++ namespaces or include guards, you will need to update those manually. Always review the changes with `git diff`, and use your IDE or `grep` to hunt down any lingering references to the old name before committing! ## Rebasing An Older Exemplar Clone Onto Copier -If your repository predates the Copier migration and was created as a plain GitHub -template copy, bootstrap a fresh stamped baseline at the original exemplar split point, -then rebase your project commits onto that baseline. +If your repository predates the Copier migration and was created as a plain GitHub template copy, bootstrap a fresh stamped baseline at the original exemplar split point, then rebase your project commits onto that baseline. -Start from a clean worktree and make sure you can identify the branch you want to -migrate; the examples below assume `main`. +Start from a clean worktree and make sure you can identify the branch you want to migrate; the examples below assume `main`. ```shell -git remote add exemplar https://github.com/bemanproject/exemplar.git +git remote add exemplar [https://github.com/bemanproject/exemplar.git](https://github.com/bemanproject/exemplar.git) git fetch exemplar base=$(git merge-base main exemplar/main) git branch pre-copier-backup main @@ -72,7 +117,7 @@ python3 -m venv "$tmpdir/venv" -d unit_test_library=gtest \ -d generating_exemplar=false \ -d owner=bemanproject \ - https://github.com/bemanproject/exemplar.git \ + [https://github.com/bemanproject/exemplar.git](https://github.com/bemanproject/exemplar.git) \ . "$tmpdir/venv/bin/pre-commit" run --all-files || true git add . @@ -83,34 +128,36 @@ git switch main git rebase --rebase-merges --onto stamp "$base" main ``` -After the rebase, commit the generated `.copier-answers.yml`. That file is what enables -future template updates with: +After the rebase, commit the generated `.copier-answers.yml`. That file is what enables future template updates with: ```shell -copier update --trust +uvx --from copier copier update --trust ``` -If you want to track a fork of exemplar rather than `bemanproject/exemplar`, edit -`_src_path` in `.copier-answers.yml` before your first `copier update`. +If you want to track a fork of exemplar rather than `bemanproject/exemplar`, edit `_src_path` in `.copier-answers.yml` before your first `copier update`. -From there, you can simply fill in all the remaining parts of the repository that are -labeled 'todo'. +## Template Maintenance -What follow is an example of a Beman library README. +If you are changing the template itself rather than developing a library, use the Copier workflow directly: - -# beman.exemplar: A Beman Library Exemplar +* Edit `copier.yml` for template questions, defaults, validators, and post-copy tasks. +* Edit `template/` for files that should be rendered into stamped projects. +* Run `./copier/check_copier.sh` to verify exemplar self-regeneration and non-exemplar templating. +* Create a new project locally using the Quick Start commands when you want to use the template for real work. - +The consistency check renders from a `.git`-free temporary snapshot of the repository. That keeps local validation aligned with the current worktree contents, rather than only the last committed Git state. + +--- + +What follows is an example of a Beman library README. + +# beman.exemplar: A Beman Library Exemplar - ![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/bemanproject/exemplar/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/bemanproject/exemplar/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/exemplar/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/exemplar?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg) [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va) `beman.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md). This can be used as a template for those intending to write Beman libraries. -It may also find use as a minimal and modern C++ project structure. +It may also find use as a minimal and modern C++ project structure. **Implements**: `std::identity` proposed in [Standard Library Concepts (P0898R3)](https://wg21.link/P0898R3). @@ -216,22 +263,6 @@ You can disable building tests by setting CMake option `BEMAN_EXEMPLAR_BUILD_TES See the [Contributing Guidelines](CONTRIBUTING.md). -### Template Maintenance - -If you are changing the template itself rather than developing the exemplar library, use -the Copier workflow directly: - -* Edit `copier.yml` for template questions, defaults, validators, and post-copy tasks. -* Edit `template/` for files that should be rendered into stamped projects. -* Run `./copier/check_copier.sh` to verify exemplar self-regeneration and non-exemplar - templating. -* Use `./stamp.sh` on a fork when you want to replace an exemplar clone with a stamped - project for real work. - -The consistency check and `stamp.sh` both render from a `.git`-free temporary snapshot of -the repository. That keeps local validation aligned with the current worktree contents, -rather than only the last committed Git state. - ## Integrate beman.exemplar into your project ### Build diff --git a/stamp.sh b/stamp.sh index 289f7a13..eb7a708e 100755 --- a/stamp.sh +++ b/stamp.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +echo "⚠ Note: stamp.sh is deprecated. You can now generate projects directly using:" >&2 +echo " uvx --from copier copier copy \"git+https://github.com/bemanproject/exemplar.git\" " >&2 +echo " See the README for the updated workflow." >&2 +echo "" >&2 + { if [[ "$1" == "-h" || "$1" == "--help" ]] ; then cat <<-'EOF' From 36573cfd1c0c7ff67e6bf259b92e8e005bed90ed Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Fri, 22 May 2026 15:07:47 -0400 Subject: [PATCH 13/29] Update templates to pass check-copier Add the new README text Fix whitespace Fix quote style to match --- template/.github/workflows/ci_tests.yml.jinja | 1 + .../workflows/pre-commit-update.yml.jinja | 4 +- template/README.md.jinja | 202 ++++++++++-------- 3 files changed, 113 insertions(+), 94 deletions(-) diff --git a/template/.github/workflows/ci_tests.yml.jinja b/template/.github/workflows/ci_tests.yml.jinja index e00c6ff5..bf868cde 100644 --- a/template/.github/workflows/ci_tests.yml.jinja +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -10,6 +10,7 @@ on: workflow_dispatch: schedule: - cron: '{{ ci_tests_cron }}' + concurrency: group: {% raw %}${{format('{0}:{1}', github.repository, github.ref)}}{% endraw %} diff --git a/template/.github/workflows/pre-commit-update.yml.jinja b/template/.github/workflows/pre-commit-update.yml.jinja index 7410a65b..232344f0 100644 --- a/template/.github/workflows/pre-commit-update.yml.jinja +++ b/template/.github/workflows/pre-commit-update.yml.jinja @@ -5,7 +5,7 @@ name: Weekly pre-commit autoupdate on: workflow_dispatch: schedule: - - cron: '{{pre_commit_update_cron}}' + - cron: "{{pre_commit_update_cron}}" {% raw -%} jobs: @@ -14,4 +14,4 @@ jobs: secrets: APP_ID: ${{ secrets.AUTO_PR_BOT_APP_ID }} PRIVATE_KEY: ${{ secrets.AUTO_PR_BOT_PRIVATE_KEY }} -{%- endraw %} +{% endraw %} diff --git a/template/README.md.jinja b/template/README.md.jinja index 88b6d5c9..261fc59d 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -1,61 +1,106 @@ {% if generating_exemplar %} # How to Use This Template -To create a new Beman library, first click the "Use this template" dropdown in the -top-right and select "Create a new repository": +This repository uses [Copier](https://copier.readthedocs.io/) as its templating engine to generate, manage, and update Beman library boilerplate. The template inputs are defined in `copier.yml`, and the rendered project files live under `template/`. -
- GitHub Use this template button -
+> [!NOTE] +> ?? **`stamp.sh` is deprecated.** If you are used to the legacy workflow of forking this repository and running `./stamp.sh`, please transition to the natively supported `copier` workflow below. The script remains for legacy CI compatibility but will not receive future updates. + +## ? Quick Start: Create a New Library -This will create a new repository that's an exact copy of exemplar. The next step is to -customize it for your use case. +If you are already familiar with the Beman project lifecycle, you can generate a new library immediately using `uvx` (via the [uv package manager](https://docs.astral.sh/uv/)): -This repository now uses Copier as its templating engine. The template inputs are defined -in `copier.yml`, the rendered project files live under `template/`, and -`./copier/check_copier.sh` verifies that the repository still round-trips through Copier -correctly. +```bash +uvx --from copier copier copy "git+[https://github.com/bemanproject/exemplar.git](https://github.com/bemanproject/exemplar.git)" my-new-library +cd my-new-library +git init +git add . +git commit -m "Initial commit from Beman Exemplar template" +uvx pre-commit install +``` -To do so, execute the bash script `stamp.sh`. This script will prompt for parameters like -the new library's name, paper number, and description. Then it will replace your exemplar -copy with a stamped-out template containing these parameters and create a corresponding -git commit and branch: +--- -```shell -$ ./stamp.sh - [1/6] project_name (my_project_name): example_library - [2/6] maintainer (your_github_username): your_username - [3/6] minimum_cpp_build_version (20): - [4/6] paper (PnnnnRr): P9999R9 - [5/6] description (Short project description.): - unit_test_library? Format: str - Choices: - - gtest - - catch2 - > gtest -Switched to a new branch 'stamp' -Successfully stamped out exemplar template to the new branch 'stamp'. -Try 'git push origin stamp' to push the branch upstream, -then create a pull request. +## ?? The Beman Project Lifecycle + +To create a new library and get it officially adopted into the Beman project, you will generate the project locally, push it to your personal GitHub for active development, and eventually transfer it to the `bemanproject` organization. + +> **Why this specific workflow?** +> Developing on your personal account first gives you a sandbox to experiment and clean up your Git history. Transferring the repository (rather than creating it directly in the org) ensures the `bemanproject` organization ultimately holds the canonical, unbroken Git history, which prevents downstream forks from breaking later. + +### Step 1: Push to Your Personal GitHub +After running the Quick Start commands above, push the fresh template to your personal account to begin development. + +**Option A: Using the GitHub CLI (`gh`)** +```bash +gh repo create my-new-library --public --source=. --remote=origin --push ``` -`stamp.sh` is a convenience wrapper around `copier copy`. It creates an isolated virtual -environment, renders from a temporary snapshot of the repository, runs `pre-commit`, and -commits the stamped result onto a `stamp` branch. The stamped tree now includes -`.copier-answers.yml`, so future `copier update` runs know which exemplar revision they -started from. +**Option B: Using the GitHub Browser Interface** +1. [Create a new repository](https://github.com/new). Name it exactly what you named your local folder. Leave it completely empty. +2. Link and push your local code: + ```bash + git remote add origin [https://github.com/](https://github.com/)/my-new-library.git + git branch -M main + git push -u origin main + ``` + +### Step 2: Incubation & Implementation +Before transferring the project to the Beman organization, take the time to build out the actual proposal. +* Expand beyond the default placeholder headers (e.g., `my-new-library.hpp`). +* Stub out the necessary files for your library's domain. +* Write out the skeleton of the library's design and documentation. +* *Optional:* Once you have a working sandbox, feel free to squash or clean up your Git history using an interactive rebase (`git rebase -i`) before handing it over. + +### Step 3: Transfer to the Beman Project +Once the repository has enough substance to be reviewed or collaborated on, hand it over to the organization to establish it as the canonical source. + +1. On your GitHub repository page, go to **Settings** > **General**. +2. Scroll to the bottom to the **Danger Zone** and click **Transfer ownership**. +3. Type `bemanproject` as the new owner and confirm. + +### Step 4: Fork It Back for Ongoing Development +Now that `bemanproject/my-new-library` is the official upstream repository, standard open-source contribution rules apply. + +1. Navigate to the new URL: `https://github.com/bemanproject/my-new-library`. +2. Click **Fork** in the top right corner to create a fork in your personal namespace. +3. Update your local repository's remotes so you can pull from upstream and push to your new fork: + ```bash + # Rename your current remote (the org repo) to 'upstream' + git remote rename origin upstream + + # Add your new personal fork as 'origin' + git remote add origin [https://github.com/](https://github.com/)/my-new-library.git + ``` + +--- + +## ?? Reconfiguring or Renaming Your Project + +One of the biggest advantages of using `copier` is that it actively maintains your project's boilerplate. If you start out with a placeholder name and later decide to rename your library (or change your minimum C++ version), you can instruct Copier to update the structural boilerplate using the `--data` flag. + +For example, to rename your project to `range_discombobulator`: + +```bash +uvx --from copier copier update --trust --skip-answered --data project_name=range_discombobulator +``` + +**What this does:** +* `--data project_name=...`: Overrides your previous answer for the project name. +* `--skip-answered`: Skips the interactive prompt for all the questions you aren't changing. + +Copier will calculate the difference and automatically update the template-provided files—renaming CMake configurations, GitHub Actions matrices, standard folder paths, and core macros. + +?? **Important Caveat:** Copier only manages the files it originally generated. If you have added custom files (like `detail/internal.hpp`), or manually typed the old project name into new C++ namespaces or include guards, you will need to update those manually. Always review the changes with `git diff`, and use your IDE or `grep` to hunt down any lingering references to the old name before committing! ## Rebasing An Older Exemplar Clone Onto Copier -If your repository predates the Copier migration and was created as a plain GitHub -template copy, bootstrap a fresh stamped baseline at the original exemplar split point, -then rebase your project commits onto that baseline. +If your repository predates the Copier migration and was created as a plain GitHub template copy, bootstrap a fresh stamped baseline at the original exemplar split point, then rebase your project commits onto that baseline. -Start from a clean worktree and make sure you can identify the branch you want to -migrate; the examples below assume `main`. +Start from a clean worktree and make sure you can identify the branch you want to migrate; the examples below assume `main`. ```shell -git remote add exemplar https://github.com/bemanproject/exemplar.git +git remote add exemplar [https://github.com/bemanproject/exemplar.git](https://github.com/bemanproject/exemplar.git) git fetch exemplar base=$(git merge-base main exemplar/main) git branch pre-copier-backup main @@ -73,7 +118,7 @@ python3 -m venv "$tmpdir/venv" -d unit_test_library=gtest \ -d generating_exemplar=false \ -d owner=bemanproject \ - https://github.com/bemanproject/exemplar.git \ + [https://github.com/bemanproject/exemplar.git](https://github.com/bemanproject/exemplar.git) \ . "$tmpdir/venv/bin/pre-commit" run --all-files || true git add . @@ -84,69 +129,59 @@ git switch main git rebase --rebase-merges --onto stamp "$base" main ``` -After the rebase, commit the generated `.copier-answers.yml`. That file is what enables -future template updates with: +After the rebase, commit the generated `.copier-answers.yml`. That file is what enables future template updates with: ```shell -copier update --trust +uvx --from copier copier update --trust ``` -If you want to track a fork of exemplar rather than `bemanproject/exemplar`, edit -`_src_path` in `.copier-answers.yml` before your first `copier update`. +If you want to track a fork of exemplar rather than `bemanproject/exemplar`, edit `_src_path` in `.copier-answers.yml` before your first `copier update`. -From there, you can simply fill in all the remaining parts of the repository that are -labeled 'todo'. +## Template Maintenance -What follow is an example of a Beman library README. +If you are changing the template itself rather than developing a library, use the Copier workflow directly: -{% endif %} -{% if generating_exemplar %} -{% endif %} -# beman.{{project_name}}: {{description}} +* Edit `copier.yml` for template questions, defaults, validators, and post-copy tasks. +* Edit `template/` for files that should be rendered into stamped projects. +* Run `./copier/check_copier.sh` to verify exemplar self-regeneration and non-exemplar templating. +* Create a new project locally using the Quick Start commands when you want to use the template for real work. - +The consistency check renders from a `.git`-free temporary snapshot of the repository. That keeps local validation aligned with the current worktree contents, rather than only the last committed Git state. - -![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/{{owner}}/{{project_name}}/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/{{owner}}/{{project_name}}/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/{{owner}}/{{project_name}}/badge.svg?branch=main)](https://coveralls.io/github/{{owner}}/{{project_name}}?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg){% if generating_exemplar %} [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va){% endif %} +--- +What follows is an example of a Beman library README. + +# beman.exemplar: A Beman Library Exemplar + +![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/bemanproject/exemplar/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/bemanproject/exemplar/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/exemplar/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/exemplar?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg) [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va) -{% if generating_exemplar %} `beman.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md). This can be used as a template for those intending to write Beman libraries. -It may also find use as a minimal and modern C++ project structure. -{% else %} -`beman.{{project_name}}` is (... TODO: description). -{% endif %} +It may also find use as a minimal and modern C++ project structure. -{% if generating_exemplar %} -**Implements**: `std::identity` proposed in [Standard Library Concepts ({{paper}})](https://wg21.link/{{paper}}). -{% else %} -**Implements**: `std::todo` proposed in [TODO ({{paper}})](https://wg21.link/{{paper}}). -{% endif %} +**Implements**: `std::identity` proposed in [Standard Library Concepts (P0898R3)](https://wg21.link/P0898R3). **Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#under-development-and-not-yet-ready-for-production-use) ## License -`beman.{{project_name}}` is licensed under the Apache License v2.0 with LLVM Exceptions. +`beman.exemplar` is licensed under the Apache License v2.0 with LLVM Exceptions. ## Usage -{% if generating_exemplar %} `std::identity` is a function object type whose `operator()` returns its argument unchanged. `std::identity` serves as the default projection in constrained algorithms. Its direct usage is usually not needed. ### Usage: default projection in constrained algorithms -The following code snippet illustrates how we can achieve a default projection using `beman::{{project_name}}::identity`: +The following code snippet illustrates how we can achieve a default projection using `beman::exemplar::identity`: ```cpp -#include +#include -namespace exe = beman::{{project_name}}; +namespace exe = beman::exemplar; // Class with a pair of values. struct Pair @@ -233,23 +268,6 @@ You can disable building tests by setting CMake option `BEMAN_{{project_name.upp See the [Contributing Guidelines](CONTRIBUTING.md). -{% if generating_exemplar %}### Template Maintenance - -If you are changing the template itself rather than developing the exemplar library, use -the Copier workflow directly: - -* Edit `copier.yml` for template questions, defaults, validators, and post-copy tasks. -* Edit `template/` for files that should be rendered into stamped projects. -* Run `./copier/check_copier.sh` to verify exemplar self-regeneration and non-exemplar - templating. -* Use `./stamp.sh` on a fork when you want to replace an exemplar clone with a stamped - project for real work. - -The consistency check and `stamp.sh` both render from a `.git`-free temporary snapshot of -the repository. That keeps local validation aligned with the current worktree contents, -rather than only the last committed Git state. -{% endif %} - ## Integrate beman.{{project_name}} into your project ### Build From 73d02de53ff43288c81980993e54c7588b01e640 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 14:08:40 -0400 Subject: [PATCH 14/29] Update infra submodule and deploy copier update scripts --- copier/test_standard_project.sh | 26 ++++++ copier/update_templates.py | 106 ++++++++++++++++++++++++ infra/.beman_submodule | 2 +- infra/.github/CODEOWNERS | 2 +- template/infra/.beman_submodule.jinja | 2 +- template/infra/.github/CODEOWNERS.jinja | 2 +- 6 files changed, 136 insertions(+), 4 deletions(-) create mode 100755 copier/test_standard_project.sh create mode 100755 copier/update_templates.py diff --git a/copier/test_standard_project.sh b/copier/test_standard_project.sh new file mode 100755 index 00000000..fa2f034f --- /dev/null +++ b/copier/test_standard_project.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +repo_root=$(realpath "$script_dir/..") + +work_dir=$(mktemp -d) +cleanup() { + rm -rf "$work_dir" +} +trap cleanup EXIT + +echo "Generating standard project in $work_dir..." +uvx --from copier copier copy --vcs-ref HEAD \ + --trust \ + --defaults \ + -d project_name=test_project \ + -d generating_exemplar=false \ + "$repo_root" \ + "$work_dir" + +echo "Building standard project..." +cd "$work_dir" +cmake --preset gcc-release -B build +cmake --build build +ctest --test-dir build --output-on-failure diff --git a/copier/update_templates.py b/copier/update_templates.py new file mode 100755 index 00000000..4f95e28b --- /dev/null +++ b/copier/update_templates.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +import os +import subprocess +import tempfile +import shutil +import stat + +def main(): + script_dir = os.path.dirname(os.path.realpath(__file__)) + repo_root = os.path.realpath(os.path.join(script_dir, "..")) + + with tempfile.TemporaryDirectory() as work_dir: + prepared_source = os.path.join(work_dir, "prepared_source") + output_dir = os.path.join(work_dir, "default") + + print("Preparing dirty working tree for Copier...") + # Rsync like check_copier.sh to capture dirty working tree without .git + subprocess.run([ + "rsync", "-a", + "--exclude", ".git", + "--exclude", "build", + "--exclude", ".venv", + f"{repo_root}/", f"{prepared_source}/" + ], check=True) + + print("Generating template base case...") + subprocess.run([ + "uvx", "--from", "copier", "copier", "copy", + "--trust", "--defaults", + "-d", "generating_exemplar=true", + prepared_source, output_dir + ], cwd=prepared_source, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + diff_cmd = [ + "diff", "-u", "-r", + "--exclude", ".git", + "--exclude", "build", + "--exclude", ".venv", + "--exclude", "template", + "--exclude", "copier", + "--exclude", "copier.yml", + "--exclude", "stamp.sh", + "--exclude", "images", + "--exclude", ".copier-answers.yml", + "--exclude", "copier_test.yml", + "--exclude", "catch2_exemplar_test.yml", + "--exclude", "todo_exemplar_test.yml", + repo_root, output_dir + ] + + result = subprocess.run(diff_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if not result.stdout.strip(): + print("No differences found. Templates are synchronized.") + return + + lines = result.stdout.splitlines() + mismatched_files = [] + for line in lines: + if line.startswith("--- " + repo_root): + file_path = line[4:].split("\t")[0].strip() + rel_path = os.path.relpath(file_path, repo_root) + mismatched_files.append(rel_path) + + for rel_path in mismatched_files: + root_file = os.path.join(repo_root, rel_path) + + template_file_jinja = os.path.join(repo_root, "template", rel_path + ".jinja") + template_file_plain = os.path.join(repo_root, "template", rel_path) + + target_template = None + if os.path.exists(template_file_jinja): + target_template = template_file_jinja + elif os.path.exists(template_file_plain): + target_template = template_file_plain + + if not target_template: + print(f"Warning: {rel_path} not found in template/. Skipping.") + continue + + with open(target_template, 'r') as tf: + content = tf.read() + + has_jinja = "{{" in content or "{%" in content + + if has_jinja: + lines = content.split('\n') + if len(lines) > 2 and "{% raw -%}" in lines[1] and "{% endraw %}" in lines[-2]: + print(f"Updating template for {rel_path} (raw block)") + with open(root_file, 'r') as rf: + root_content = rf.read() + + new_content = lines[0] + "\n{% raw -%}\n" + root_content + "\n{% endraw %}" + if content.endswith("\n"): + new_content += "\n" + with open(target_template, 'w') as tf: + tf.write(new_content) + else: + print(f"Skipping {rel_path} because the template uses Jinja variables.") + else: + print(f"Updating static template for {rel_path}") + shutil.copy2(root_file, target_template) + +if __name__ == "__main__": + main() diff --git a/infra/.beman_submodule b/infra/.beman_submodule index 7367e0e2..4e9900c1 100644 --- a/infra/.beman_submodule +++ b/infra/.beman_submodule @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=eb7b7c3688bd8f26ab0c145e3147df9a8f2ec8ce +commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f diff --git a/infra/.github/CODEOWNERS b/infra/.github/CODEOWNERS index 4ff90a43..439303d4 100644 --- a/infra/.github/CODEOWNERS +++ b/infra/.github/CODEOWNERS @@ -1 +1 @@ -* @ednolan @neatudarius @rishyak @wusatosi @JeffGarland +* @ednolan @rishyak @wusatosi @JeffGarland diff --git a/template/infra/.beman_submodule.jinja b/template/infra/.beman_submodule.jinja index 7367e0e2..4e9900c1 100644 --- a/template/infra/.beman_submodule.jinja +++ b/template/infra/.beman_submodule.jinja @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=eb7b7c3688bd8f26ab0c145e3147df9a8f2ec8ce +commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f diff --git a/template/infra/.github/CODEOWNERS.jinja b/template/infra/.github/CODEOWNERS.jinja index 4ff90a43..439303d4 100644 --- a/template/infra/.github/CODEOWNERS.jinja +++ b/template/infra/.github/CODEOWNERS.jinja @@ -1 +1 @@ -* @ednolan @neatudarius @rishyak @wusatosi @JeffGarland +* @ednolan @rishyak @wusatosi @JeffGarland From 45edf686cc87959b77f0c741366fe5f0fab0cb38 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 14:15:49 -0400 Subject: [PATCH 15/29] Test all template matrix variants in CI cleanly --- .github/workflows/ci_tests.yml | 18 +++++++ copier/check_copier.sh | 1 + copier/test_standard_project.sh | 90 ++++++++++++++++++++++++++------- 3 files changed, 90 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 6e6615a6..1d053c06 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -19,6 +19,24 @@ jobs: beman-submodule-check: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.7.2 + copier-test: + runs-on: ubuntu-latest + container: + image: ghcr.io/bemanproject/infra-containers-clang:latest + steps: + - uses: actions/checkout@v4 + - name: Install uv + shell: bash + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Test Copier Template Variants + shell: bash + env: + GITHUB_ACTIONS: true + # llvm-release will use clang which supports C++23 modules appropriately in this container + run: ./copier/test_standard_project.sh llvm-release + preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 with: diff --git a/copier/check_copier.sh b/copier/check_copier.sh index 7696f098..ca1dd83e 100755 --- a/copier/check_copier.sh +++ b/copier/check_copier.sh @@ -141,6 +141,7 @@ main() { setup_venv "$copier_venv_path" check_consistency check_templating + echo "Success: Template matches project exactly." } [[ "${BASH_SOURCE[0]}" != "${0}" ]] || main "$@" diff --git a/copier/test_standard_project.sh b/copier/test_standard_project.sh index fa2f034f..138da06b 100755 --- a/copier/test_standard_project.sh +++ b/copier/test_standard_project.sh @@ -1,26 +1,78 @@ #!/usr/bin/env bash +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set -euo pipefail script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") repo_root=$(realpath "$script_dir/..") -work_dir=$(mktemp -d) -cleanup() { - rm -rf "$work_dir" +PRESET=${1:-gcc-release} + +test_project_variant() { + local variant_name="$1" + local unit_test_library="$2" + local use_modules="$3" + local cmakelists_args="" + + if [[ "$use_modules" == "true" ]]; then + cmakelists_args="-DBEMAN_TEST_PROJECT_USE_MODULES=ON" + fi + + echo "==========================================================" + echo "Testing variant: $variant_name" + echo "Unit test: $unit_test_library, Modules: $use_modules, Preset: $PRESET" + echo "==========================================================" + + local work_dir + work_dir=$(mktemp -d) + echo "Generating standard project in $work_dir..." + + # Use `--vcs-ref HEAD` in CI environment so we test the most recent commit + # but use local tree if uncommitted for fast iteration locally. Use dirty copier behavior locally. + uvx --from copier copier copy \ + --trust \ + --defaults \ + -d project_name=test_project \ + -d generating_exemplar=false \ + -d unit_test_library="$unit_test_library" \ + "$repo_root" \ + "$work_dir" + + echo "Building standard project variant $variant_name..." + pushd "$work_dir" > /dev/null + cmake --preset "$PRESET" -B build $cmakelists_args || { + echo -e "\n\n*** configure failed: $variant_name ***" + echo "*** Sometimes local CMake modules require a newer compiler than the host default." + # If failure is just a module C++ scan lack of support, we could suppress, but let's hard fail. + popd > /dev/null && rm -rf "$work_dir" + exit 1 + } + cmake --build build + ctest --test-dir build --output-on-failure + + # Cleanup this variant's dir + popd > /dev/null && rm -rf "$work_dir" + echo "✔ Success for variant: $variant_name" } -trap cleanup EXIT - -echo "Generating standard project in $work_dir..." -uvx --from copier copier copy --vcs-ref HEAD \ - --trust \ - --defaults \ - -d project_name=test_project \ - -d generating_exemplar=false \ - "$repo_root" \ - "$work_dir" - -echo "Building standard project..." -cd "$work_dir" -cmake --preset gcc-release -B build -cmake --build build -ctest --test-dir build --output-on-failure + +# 1. GTest + No Modules +test_project_variant "gtest-no-modules" "gtest" "false" + +# 2. Catch2 + No Modules +test_project_variant "catch2-no-modules" "catch2" "false" + +# Do not run modules locally if we cannot guarantee modern tooling, but CI will use clang/gcc containers +# We check if we are in github actions to enforce building modules, as locally it may fail CMake module requirements. +if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then + # 3. GTest + Modules + test_project_variant "gtest-modules" "gtest" "true" + + # 4. Catch2 + Modules + test_project_variant "catch2-modules" "catch2" "true" +else + echo "Skipping Modules test variants locally to avoid experimental CMake/C++ module failures on older host toolchains." + echo "Pass GITHUB_ACTIONS=true to force." +fi + +echo "==========================================================" +echo "✔ All variants successfully generated, built, and tested! " +echo "==========================================================" From dab6527891a030f4d7b5ccd910251e5170fbf83b Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 14:21:59 -0400 Subject: [PATCH 16/29] Add MAINTAINERS documentation for template pipeline --- copier/MAINTAINERS.md | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 copier/MAINTAINERS.md diff --git a/copier/MAINTAINERS.md b/copier/MAINTAINERS.md new file mode 100644 index 00000000..13424e7e --- /dev/null +++ b/copier/MAINTAINERS.md @@ -0,0 +1,64 @@ +# Maintaining the Copier Template + +This document provides instructions for maintainers of the `exemplar` repository on how to test, update, and manage the `copier` template generation infrastructure. + +For instructions on how entirely *new* users should invoke the template template using `uvx` and `copier` to start a new project, see the [main README.md](../README.md). + +## Overall Philosophy + +The `exemplar` repository serves a dual purpose: +1. It is a fully functional, canonical Reference implementation of a Beman Library (the root codebase). +2. It contains the Jinja-based template used by downstream Beman projects (the `template/` directory). + +To ensure that downstream templates are highly functional and that the template never falls out of sync with the reference implementation, we require that the `template/` output (`generating_exemplar=true`) perfectly recreates the root project repository, barring acceptable omissions. + +## Utilities and Scripts + +The `copier/` directory houses the tooling necessary to validate and update the templates. + +### `copier/update_templates.py` +Automates the synchronization of physical changes in the root project into the `template/` logic. +- Creates a transient virtual Copier projection of the current dirty state. +- Diff-checks the root project against the `template/` output. +- **For simple files:** Automatically copies physical root modifications directly into the `template/` structural counterparts. +- **For raw blocks:** Gracefully injects updated root text into Jinja `{% raw -%}` blocks (heavily used for GitHub Actions YAML configuration). +- **For complex files:** Emits a terminal warning letting you know manual intervention is required. + +### `copier/check_copier.sh` +Performs a strict byte-for-byte validation ensuring that the `template/` generates the root exemplar repository exactly. +- Operates under `generating_exemplar=true`. +- Whitelists specific directories (like `.venv/`, `.git/`, `build/`). +- Whitelist ignores specific templated examples (`/todo/` vs `/identity/`) that are replaced in downstream invocations. +- Returns a strict exit code if the templates drift out of sync with the main codebase. + +### `copier/test_standard_project.sh` +While `check_copier.sh` is tailored to the `exemplar` structure, this script provisions completely neutral, third-party libraries (`generating_exemplar=false`). +- Provisions instances utilizing different testing frameworks (e.g. `gtest` and `catch2`). +- Tests matrix conditions (e.g. C++ Modules on vs. off). +- Re-runs the CMake configure/build/ctest lifecycle on every variant to ensure downstream clients will not experience build breakages. + +## Workflow: Updating the Templates + +When you make changes to the C++ code, CMake infrastructure, or CI processes within `exemplar`, you must propagate those updates to the Copier template: + +1. **Make changes in the canonical root directory.** Modify source, tests, workflows, etc., directly in the `exemplar` repository. +2. **Propagate via script:** Execute `./copier/update_templates.py`. This covers 90% of file replication seamlessly. +3. **Manually reconcile complex templates:** Look at the warnings generated by the Python script to see if structural Jinja templates (like `CMakeLists.txt.jinja` or `.github/CODEOWNERS.jinja`) require manual hand-editing. +4. **Validate Parity:** Run `./copier/check_copier.sh`. Continue fixing template logic until the script emits `Success: Template matches project exactly.`. +5. **Validate Downstream Viability:** Run `./copier/test_standard_project.sh` to ensure you haven't broken the generic downstream logic (e.g. accidentally hardcoding the word "identity" where `{{project_name}}` should be). + +## Troubleshooting CI Failures + +The `copier` test scripts run in GitHub Actions underneath `ci_tests.yml`. + +- **`check_copier.sh` fails in CI:** + You updated a file in the root repository (e.g. a submodule bump, a new workflow, modified C++) but forgot to update the corresponding `.jinja` file in the `template/` directory. + **Solution:** Pull the branch locally and run `./copier/update_templates.py`. Check for regressions using `./copier/check_copier.sh` and push. + +- **`test_standard_project.sh` (or `copier-test` CI Job) fails:** + The `exemplar` generation works, but something breaks when the project generates for *other* people (`generating_exemplar=false`). + **Solution:** Check the specific variant that failed. + - *Did `catch2` break?* You might have modified `template/tests/beman/{{project_name}}/CMakeLists.txt.jinja` using `gtest` specifics that aren't guarded properly. + - *Did Modules break?* The CI test runs C++ modules using `ghcr.io/bemanproject/infra-containers-clang:latest`. Ensure the CMake module directives conditional branches haven't drifted. + + Locally, you can simulate specific container behaviors by targeting a custom CMake preset or enabling actions mode: `GITHUB_ACTIONS=true ./copier/test_standard_project.sh llvm-release`. From 5abb32bb8a24022faec0b29427f6da61bfe4f202 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 14:37:34 -0400 Subject: [PATCH 17/29] Sync copier-test job into jinja template --- template/.github/workflows/ci_tests.yml.jinja | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/template/.github/workflows/ci_tests.yml.jinja b/template/.github/workflows/ci_tests.yml.jinja index bf868cde..8f57877d 100644 --- a/template/.github/workflows/ci_tests.yml.jinja +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -20,6 +20,24 @@ jobs: beman-submodule-check: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.7.2 + copier-test: + runs-on: ubuntu-latest + container: + image: ghcr.io/bemanproject/infra-containers-clang:latest + steps: + - uses: actions/checkout@v4 + - name: Install uv + shell: bash + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Test Copier Template Variants + shell: bash + env: + GITHUB_ACTIONS: true + # llvm-release will use clang which supports C++23 modules appropriately in this container + run: ./copier/test_standard_project.sh llvm-release + preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 with: From de7a141b89c85b9ef4c21bcf8bee5d0563410509 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 14:37:58 -0400 Subject: [PATCH 18/29] Support MSVC Modules on CMake 4.3 runners --- infra/.beman_submodule | 2 +- .../enable-experimental-import-std.cmake | 28 +++++++++++++++++++ template/infra/.beman_submodule.jinja | 2 +- ...enable-experimental-import-std.cmake.jinja | 28 +++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/infra/.beman_submodule b/infra/.beman_submodule index 4e9900c1..6c25abcd 100644 --- a/infra/.beman_submodule +++ b/infra/.beman_submodule @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f +commit_hash=0e66d85dae63fa26cb1b09181fe50756f07780d8 diff --git a/infra/cmake/enable-experimental-import-std.cmake b/infra/cmake/enable-experimental-import-std.cmake index 20fc302b..06d51cf4 100644 --- a/infra/cmake/enable-experimental-import-std.cmake +++ b/infra/cmake/enable-experimental-import-std.cmake @@ -187,4 +187,32 @@ elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.9") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) endif() diff --git a/template/infra/.beman_submodule.jinja b/template/infra/.beman_submodule.jinja index 4e9900c1..6c25abcd 100644 --- a/template/infra/.beman_submodule.jinja +++ b/template/infra/.beman_submodule.jinja @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f +commit_hash=0e66d85dae63fa26cb1b09181fe50756f07780d8 diff --git a/template/infra/cmake/enable-experimental-import-std.cmake.jinja b/template/infra/cmake/enable-experimental-import-std.cmake.jinja index 20fc302b..06d51cf4 100644 --- a/template/infra/cmake/enable-experimental-import-std.cmake.jinja +++ b/template/infra/cmake/enable-experimental-import-std.cmake.jinja @@ -187,4 +187,32 @@ elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.9") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) endif() From 5713851575538883986c512623a0cd9a62a620f4 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 15:31:17 -0400 Subject: [PATCH 19/29] Switch copier-test compiler vector to gcc-release to resolve std modules fortification conflict --- .github/workflows/ci_tests.yml | 6 +++--- template/.github/workflows/ci_tests.yml.jinja | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 1d053c06..6f5e2190 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -22,7 +22,7 @@ jobs: copier-test: runs-on: ubuntu-latest container: - image: ghcr.io/bemanproject/infra-containers-clang:latest + image: ghcr.io/bemanproject/infra-containers-gcc:latest steps: - uses: actions/checkout@v4 - name: Install uv @@ -34,8 +34,8 @@ jobs: shell: bash env: GITHUB_ACTIONS: true - # llvm-release will use clang which supports C++23 modules appropriately in this container - run: ./copier/test_standard_project.sh llvm-release + # gcc-release will use GCC 15 which supports C++23 modules appropriately in this container + run: ./copier/test_standard_project.sh gcc-release preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 diff --git a/template/.github/workflows/ci_tests.yml.jinja b/template/.github/workflows/ci_tests.yml.jinja index 8f57877d..673413be 100644 --- a/template/.github/workflows/ci_tests.yml.jinja +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -23,7 +23,7 @@ jobs: copier-test: runs-on: ubuntu-latest container: - image: ghcr.io/bemanproject/infra-containers-clang:latest + image: ghcr.io/bemanproject/infra-containers-gcc:latest steps: - uses: actions/checkout@v4 - name: Install uv @@ -35,8 +35,8 @@ jobs: shell: bash env: GITHUB_ACTIONS: true - # llvm-release will use clang which supports C++23 modules appropriately in this container - run: ./copier/test_standard_project.sh llvm-release + # gcc-release will use GCC 15 which supports C++23 modules appropriately in this container + run: ./copier/test_standard_project.sh gcc-release preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 From 325a1710142228acaecd3e9c397aef57f50816f6 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 15:31:40 -0400 Subject: [PATCH 20/29] Autoformat MAINTAINERS.md trailing whitespace --- copier/MAINTAINERS.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/copier/MAINTAINERS.md b/copier/MAINTAINERS.md index 13424e7e..5ce07168 100644 --- a/copier/MAINTAINERS.md +++ b/copier/MAINTAINERS.md @@ -1,6 +1,6 @@ # Maintaining the Copier Template -This document provides instructions for maintainers of the `exemplar` repository on how to test, update, and manage the `copier` template generation infrastructure. +This document provides instructions for maintainers of the `exemplar` repository on how to test, update, and manage the `copier` template generation infrastructure. For instructions on how entirely *new* users should invoke the template template using `uvx` and `copier` to start a new project, see the [main README.md](../README.md). @@ -10,7 +10,7 @@ The `exemplar` repository serves a dual purpose: 1. It is a fully functional, canonical Reference implementation of a Beman Library (the root codebase). 2. It contains the Jinja-based template used by downstream Beman projects (the `template/` directory). -To ensure that downstream templates are highly functional and that the template never falls out of sync with the reference implementation, we require that the `template/` output (`generating_exemplar=true`) perfectly recreates the root project repository, barring acceptable omissions. +To ensure that downstream templates are highly functional and that the template never falls out of sync with the reference implementation, we require that the `template/` output (`generating_exemplar=true`) perfectly recreates the root project repository, barring acceptable omissions. ## Utilities and Scripts @@ -35,13 +35,13 @@ Performs a strict byte-for-byte validation ensuring that the `template/` generat While `check_copier.sh` is tailored to the `exemplar` structure, this script provisions completely neutral, third-party libraries (`generating_exemplar=false`). - Provisions instances utilizing different testing frameworks (e.g. `gtest` and `catch2`). - Tests matrix conditions (e.g. C++ Modules on vs. off). -- Re-runs the CMake configure/build/ctest lifecycle on every variant to ensure downstream clients will not experience build breakages. +- Re-runs the CMake configure/build/ctest lifecycle on every variant to ensure downstream clients will not experience build breakages. ## Workflow: Updating the Templates When you make changes to the C++ code, CMake infrastructure, or CI processes within `exemplar`, you must propagate those updates to the Copier template: -1. **Make changes in the canonical root directory.** Modify source, tests, workflows, etc., directly in the `exemplar` repository. +1. **Make changes in the canonical root directory.** Modify source, tests, workflows, etc., directly in the `exemplar` repository. 2. **Propagate via script:** Execute `./copier/update_templates.py`. This covers 90% of file replication seamlessly. 3. **Manually reconcile complex templates:** Look at the warnings generated by the Python script to see if structural Jinja templates (like `CMakeLists.txt.jinja` or `.github/CODEOWNERS.jinja`) require manual hand-editing. 4. **Validate Parity:** Run `./copier/check_copier.sh`. Continue fixing template logic until the script emits `Success: Template matches project exactly.`. @@ -51,14 +51,14 @@ When you make changes to the C++ code, CMake infrastructure, or CI processes wit The `copier` test scripts run in GitHub Actions underneath `ci_tests.yml`. -- **`check_copier.sh` fails in CI:** - You updated a file in the root repository (e.g. a submodule bump, a new workflow, modified C++) but forgot to update the corresponding `.jinja` file in the `template/` directory. +- **`check_copier.sh` fails in CI:** + You updated a file in the root repository (e.g. a submodule bump, a new workflow, modified C++) but forgot to update the corresponding `.jinja` file in the `template/` directory. **Solution:** Pull the branch locally and run `./copier/update_templates.py`. Check for regressions using `./copier/check_copier.sh` and push. - **`test_standard_project.sh` (or `copier-test` CI Job) fails:** - The `exemplar` generation works, but something breaks when the project generates for *other* people (`generating_exemplar=false`). - **Solution:** Check the specific variant that failed. - - *Did `catch2` break?* You might have modified `template/tests/beman/{{project_name}}/CMakeLists.txt.jinja` using `gtest` specifics that aren't guarded properly. + The `exemplar` generation works, but something breaks when the project generates for *other* people (`generating_exemplar=false`). + **Solution:** Check the specific variant that failed. + - *Did `catch2` break?* You might have modified `template/tests/beman/{{project_name}}/CMakeLists.txt.jinja` using `gtest` specifics that aren't guarded properly. - *Did Modules break?* The CI test runs C++ modules using `ghcr.io/bemanproject/infra-containers-clang:latest`. Ensure the CMake module directives conditional branches haven't drifted. - + Locally, you can simulate specific container behaviors by targeting a custom CMake preset or enabling actions mode: `GITHUB_ACTIONS=true ./copier/test_standard_project.sh llvm-release`. From a0a4ebe8932373c26d2beb42d3a4b644d0cb3f1c Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:05:21 -0400 Subject: [PATCH 21/29] Refactor verbose CMake patch matching to concise version blocks --- .../enable-experimental-import-std.cmake | 232 ++---------------- ...enable-experimental-import-std.cmake.jinja | 232 ++---------------- 2 files changed, 32 insertions(+), 432 deletions(-) diff --git a/infra/cmake/enable-experimental-import-std.cmake b/infra/cmake/enable-experimental-import-std.cmake index 06d51cf4..6d5bb5e1 100644 --- a/infra/cmake/enable-experimental-import-std.cmake +++ b/infra/cmake/enable-experimental-import-std.cmake @@ -1,218 +1,18 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -if(CMAKE_VERSION VERSION_EQUAL "3.30.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.10") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.11") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.12") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0" AND CMAKE_VERSION VERSION_LESS "4.4.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.1.0" AND CMAKE_VERSION VERSION_LESS "4.3.0") + # 4.1.x and 4.2.x share the same UUID + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.3" AND CMAKE_VERSION VERSION_LESS "4.1.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0" AND CMAKE_VERSION VERSION_LESS "4.0.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "a9e1cf81-9932-4810-974b-6eccaf14e457") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.8" AND CMAKE_VERSION VERSION_LESS "3.32.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0" AND CMAKE_VERSION VERSION_LESS "3.31.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0" AND CMAKE_VERSION VERSION_LESS "3.31.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") endif() diff --git a/template/infra/cmake/enable-experimental-import-std.cmake.jinja b/template/infra/cmake/enable-experimental-import-std.cmake.jinja index 06d51cf4..6d5bb5e1 100644 --- a/template/infra/cmake/enable-experimental-import-std.cmake.jinja +++ b/template/infra/cmake/enable-experimental-import-std.cmake.jinja @@ -1,218 +1,18 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -if(CMAKE_VERSION VERSION_EQUAL "3.30.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.10") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.11") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.12") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0" AND CMAKE_VERSION VERSION_LESS "4.4.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.1.0" AND CMAKE_VERSION VERSION_LESS "4.3.0") + # 4.1.x and 4.2.x share the same UUID + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.3" AND CMAKE_VERSION VERSION_LESS "4.1.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0" AND CMAKE_VERSION VERSION_LESS "4.0.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "a9e1cf81-9932-4810-974b-6eccaf14e457") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.8" AND CMAKE_VERSION VERSION_LESS "3.32.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0" AND CMAKE_VERSION VERSION_LESS "3.31.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0" AND CMAKE_VERSION VERSION_LESS "3.31.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") endif() From 837b856c3fad5c91dbee10110db9e033104eeaaf Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:17:22 -0400 Subject: [PATCH 22/29] Add CMake matrix CI evaluation step executing via test loop --- copier/test_cmake_matrix.sh | 30 +++++++++++++++++++ copier/test_standard_project.sh | 11 +++++-- template/.github/workflows/ci_tests.yml.jinja | 22 ++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100755 copier/test_cmake_matrix.sh diff --git a/copier/test_cmake_matrix.sh b/copier/test_cmake_matrix.sh new file mode 100755 index 00000000..f15d0588 --- /dev/null +++ b/copier/test_cmake_matrix.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +set -euo pipefail + +script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") + +PRESET=${1:-gcc-release} +CMAKE_VERSION=${2:-latest} + +if [[ "$CMAKE_VERSION" == "latest" || -z "$CMAKE_VERSION" ]]; then + export CMAKE_COMMAND="cmake" + export CTEST_COMMAND="ctest" + echo "Running with default host CMake" +else + echo "Provisioning standard environment for CMake $CMAKE_VERSION" + venv_dir=$(mktemp -d) + uv venv "$venv_dir" > /dev/null + uv pip install "cmake==${CMAKE_VERSION}" --env "$venv_dir" > /dev/null + export CMAKE_COMMAND="$venv_dir/bin/cmake" + export CTEST_COMMAND="$venv_dir/bin/ctest" + + echo "Using CMake: $("$CMAKE_COMMAND" --version | head -n 1)" + + cleanup() { + rm -rf "$venv_dir" + } + trap cleanup EXIT +fi + +"$script_dir/test_standard_project.sh" "$PRESET" diff --git a/copier/test_standard_project.sh b/copier/test_standard_project.sh index 138da06b..a49e2c40 100755 --- a/copier/test_standard_project.sh +++ b/copier/test_standard_project.sh @@ -1,6 +1,11 @@ +#="${CMAKE_COMMAND:-cmake}" +#="${CTEST_COMMAND:-ctest}" #!/usr/bin/env bash # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set -euo pipefail +CMAKE_COMMAND="${CMAKE_COMMAND:-cmake}" +CTEST_COMMAND="${CTEST_COMMAND:-ctest}" + script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")") repo_root=$(realpath "$script_dir/..") @@ -39,15 +44,15 @@ test_project_variant() { echo "Building standard project variant $variant_name..." pushd "$work_dir" > /dev/null - cmake --preset "$PRESET" -B build $cmakelists_args || { + "$CMAKE_COMMAND" --preset "$PRESET" -B build $cmakelists_args || { echo -e "\n\n*** configure failed: $variant_name ***" echo "*** Sometimes local CMake modules require a newer compiler than the host default." # If failure is just a module C++ scan lack of support, we could suppress, but let's hard fail. popd > /dev/null && rm -rf "$work_dir" exit 1 } - cmake --build build - ctest --test-dir build --output-on-failure + "$CMAKE_COMMAND" --build build + "$CTEST_COMMAND" --test-dir build --output-on-failure # Cleanup this variant's dir popd > /dev/null && rm -rf "$work_dir" diff --git a/template/.github/workflows/ci_tests.yml.jinja b/template/.github/workflows/ci_tests.yml.jinja index 673413be..92171adb 100644 --- a/template/.github/workflows/ci_tests.yml.jinja +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -38,6 +38,28 @@ jobs: # gcc-release will use GCC 15 which supports C++23 modules appropriately in this container run: ./copier/test_standard_project.sh gcc-release + copier-cmake-matrix: + runs-on: ubuntu-latest + container: + image: ghcr.io/bemanproject/infra-containers-gcc:latest + strategy: + fail-fast: false + matrix: + cmake_version: ["3.30.9", "3.31.10", "4.0.3", "4.1.3", "4.2.3", "4.3.2"] + steps: + - uses: actions/checkout@v4 + - name: Install uv + shell: bash + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Test Copier Template Variants Matrix + shell: bash + env: + GITHUB_ACTIONS: true + # Run across our experimental boundaries + run: ./copier/test_cmake_matrix.sh gcc-release ${{ matrix.cmake_version }} + preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 with: From f8eb0b301c1ca755d59633e601141e21ab254d71 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:17:52 -0400 Subject: [PATCH 23/29] Propagate matrix to CI --- .github/workflows/ci_tests.yml | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 6f5e2190..4d28b823 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -37,6 +37,46 @@ jobs: # gcc-release will use GCC 15 which supports C++23 modules appropriately in this container run: ./copier/test_standard_project.sh gcc-release + copier-cmake-matrix: + + runs-on: ubuntu-latest + + container: + + image: ghcr.io/bemanproject/infra-containers-gcc:latest + + strategy: + + fail-fast: false + + matrix: + + cmake_version: ["3.30.9", "3.31.10", "4.0.3", "4.1.3", "4.2.3", "4.3.2"] + + steps: + + - uses: actions/checkout@v4 + + - name: Install uv + + shell: bash + + run: | + + curl -LsSf https://astral.sh/uv/install.sh | sh + + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Test Copier Template Variants Matrix + + shell: bash + + env: + + GITHUB_ACTIONS: true + + run: ./copier/test_cmake_matrix.sh gcc-release ${{ matrix.cmake_version }} + preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 with: From 139542e81157413af5d8a7551a871f704b16d8a9 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:26:13 -0400 Subject: [PATCH 24/29] Apply pre-commit formatting fixes --- copier/test_cmake_matrix.sh | 4 +- copier/test_standard_project.sh | 4 +- copier/update_templates.py | 20 +++--- .../enable-experimental-import-std.cmake | 63 ++++++++++++++----- port/portfile.cmake.in | 3 +- .../.github/workflows/vcpkg-release.yml.jinja | 1 - 6 files changed, 65 insertions(+), 30 deletions(-) diff --git a/copier/test_cmake_matrix.sh b/copier/test_cmake_matrix.sh index f15d0588..fe3c7599 100755 --- a/copier/test_cmake_matrix.sh +++ b/copier/test_cmake_matrix.sh @@ -18,9 +18,9 @@ else uv pip install "cmake==${CMAKE_VERSION}" --env "$venv_dir" > /dev/null export CMAKE_COMMAND="$venv_dir/bin/cmake" export CTEST_COMMAND="$venv_dir/bin/ctest" - + echo "Using CMake: $("$CMAKE_COMMAND" --version | head -n 1)" - + cleanup() { rm -rf "$venv_dir" } diff --git a/copier/test_standard_project.sh b/copier/test_standard_project.sh index a49e2c40..32c212ed 100755 --- a/copier/test_standard_project.sh +++ b/copier/test_standard_project.sh @@ -43,8 +43,8 @@ test_project_variant() { "$work_dir" echo "Building standard project variant $variant_name..." - pushd "$work_dir" > /dev/null - "$CMAKE_COMMAND" --preset "$PRESET" -B build $cmakelists_args || { + pushd "$work_dir" > /dev/null + "$CMAKE_COMMAND" --preset "$PRESET" -B build $cmakelists_args || { echo -e "\n\n*** configure failed: $variant_name ***" echo "*** Sometimes local CMake modules require a newer compiler than the host default." # If failure is just a module C++ scan lack of support, we could suppress, but let's hard fail. diff --git a/copier/update_templates.py b/copier/update_templates.py index 4f95e28b..3d3b796c 100755 --- a/copier/update_templates.py +++ b/copier/update_templates.py @@ -14,7 +14,7 @@ def main(): with tempfile.TemporaryDirectory() as work_dir: prepared_source = os.path.join(work_dir, "prepared_source") output_dir = os.path.join(work_dir, "default") - + print("Preparing dirty working tree for Copier...") # Rsync like check_copier.sh to capture dirty working tree without .git subprocess.run([ @@ -49,7 +49,7 @@ def main(): "--exclude", "todo_exemplar_test.yml", repo_root, output_dir ] - + result = subprocess.run(diff_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) if not result.stdout.strip(): print("No differences found. Templates are synchronized.") @@ -65,32 +65,32 @@ def main(): for rel_path in mismatched_files: root_file = os.path.join(repo_root, rel_path) - + template_file_jinja = os.path.join(repo_root, "template", rel_path + ".jinja") template_file_plain = os.path.join(repo_root, "template", rel_path) - + target_template = None if os.path.exists(template_file_jinja): target_template = template_file_jinja elif os.path.exists(template_file_plain): target_template = template_file_plain - + if not target_template: print(f"Warning: {rel_path} not found in template/. Skipping.") continue - + with open(target_template, 'r') as tf: content = tf.read() - + has_jinja = "{{" in content or "{%" in content - + if has_jinja: lines = content.split('\n') if len(lines) > 2 and "{% raw -%}" in lines[1] and "{% endraw %}" in lines[-2]: print(f"Updating template for {rel_path} (raw block)") with open(root_file, 'r') as rf: root_content = rf.read() - + new_content = lines[0] + "\n{% raw -%}\n" + root_content + "\n{% endraw %}" if content.endswith("\n"): new_content += "\n" @@ -101,6 +101,6 @@ def main(): else: print(f"Updating static template for {rel_path}") shutil.copy2(root_file, target_template) - + if __name__ == "__main__": main() diff --git a/infra/cmake/enable-experimental-import-std.cmake b/infra/cmake/enable-experimental-import-std.cmake index 6d5bb5e1..1e8baa3e 100644 --- a/infra/cmake/enable-experimental-import-std.cmake +++ b/infra/cmake/enable-experimental-import-std.cmake @@ -1,18 +1,53 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0" AND CMAKE_VERSION VERSION_LESS "4.4.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.1.0" AND CMAKE_VERSION VERSION_LESS "4.3.0") +if( + CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0" + AND CMAKE_VERSION VERSION_LESS "4.4.0" +) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif( + CMAKE_VERSION VERSION_GREATER_EQUAL "4.1.0" + AND CMAKE_VERSION VERSION_LESS "4.3.0" +) # 4.1.x and 4.2.x share the same UUID - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.3" AND CMAKE_VERSION VERSION_LESS "4.1.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0" AND CMAKE_VERSION VERSION_LESS "4.0.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "a9e1cf81-9932-4810-974b-6eccaf14e457") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.8" AND CMAKE_VERSION VERSION_LESS "3.32.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0" AND CMAKE_VERSION VERSION_LESS "3.31.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0" AND CMAKE_VERSION VERSION_LESS "3.31.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif( + CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.3" + AND CMAKE_VERSION VERSION_LESS "4.1.0" +) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif( + CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0" + AND CMAKE_VERSION VERSION_LESS "4.0.3" +) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif( + CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.8" + AND CMAKE_VERSION VERSION_LESS "3.32.0" +) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif( + CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0" + AND CMAKE_VERSION VERSION_LESS "3.31.8" +) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif( + CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0" + AND CMAKE_VERSION VERSION_LESS "3.31.0" +) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) endif() diff --git a/port/portfile.cmake.in b/port/portfile.cmake.in index ba7eeacf..6f820936 100644 --- a/port/portfile.cmake.in +++ b/port/portfile.cmake.in @@ -29,7 +29,8 @@ vcpkg_cmake_config_fixup( ) if(NOT "modules" IN_LIST FEATURES) - file(REMOVE_RECURSE + file( + REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug" "${CURRENT_PACKAGES_DIR}/lib" ) diff --git a/template/.github/workflows/vcpkg-release.yml.jinja b/template/.github/workflows/vcpkg-release.yml.jinja index faeb153c..5df54c60 100644 --- a/template/.github/workflows/vcpkg-release.yml.jinja +++ b/template/.github/workflows/vcpkg-release.yml.jinja @@ -13,4 +13,3 @@ jobs: secrets: VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} {%- endraw %} - From 3520b79607eb7ab7a1a6f738efc42668f4817f75 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:31:52 -0400 Subject: [PATCH 25/29] Fix uv pip install flag --- copier/test_cmake_matrix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copier/test_cmake_matrix.sh b/copier/test_cmake_matrix.sh index fe3c7599..5acbe608 100755 --- a/copier/test_cmake_matrix.sh +++ b/copier/test_cmake_matrix.sh @@ -15,7 +15,7 @@ else echo "Provisioning standard environment for CMake $CMAKE_VERSION" venv_dir=$(mktemp -d) uv venv "$venv_dir" > /dev/null - uv pip install "cmake==${CMAKE_VERSION}" --env "$venv_dir" > /dev/null + uv pip install "cmake==${CMAKE_VERSION}" --python "$venv_dir" > /dev/null export CMAKE_COMMAND="$venv_dir/bin/cmake" export CTEST_COMMAND="$venv_dir/bin/ctest" From 7862bb82fc3adfca5793fb7f91c9288b0de4144e Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:41:32 -0400 Subject: [PATCH 26/29] Fix uv proxy and sync templates to fix GH Actions matrix failures --- .github/workflows/ci_tests.yml | 21 +------------------ .github/workflows/vcpkg-release.yml | 2 +- copier/test_standard_project.sh | 11 +--------- template/.github/workflows/ci_tests.yml.jinja | 2 +- template/port/portfile.cmake.in.jinja | 3 ++- 5 files changed, 6 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 4d28b823..592f0ec8 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -38,45 +38,26 @@ jobs: run: ./copier/test_standard_project.sh gcc-release copier-cmake-matrix: - runs-on: ubuntu-latest - container: - image: ghcr.io/bemanproject/infra-containers-gcc:latest - strategy: - fail-fast: false - matrix: - cmake_version: ["3.30.9", "3.31.10", "4.0.3", "4.1.3", "4.2.3", "4.3.2"] - steps: - - uses: actions/checkout@v4 - - name: Install uv - shell: bash - run: | - curl -LsSf https://astral.sh/uv/install.sh | sh - echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Test Copier Template Variants Matrix - shell: bash - env: - GITHUB_ACTIONS: true - + # Run across our experimental boundaries run: ./copier/test_cmake_matrix.sh gcc-release ${{ matrix.cmake_version }} - preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 with: diff --git a/.github/workflows/vcpkg-release.yml b/.github/workflows/vcpkg-release.yml index cc10bea4..6b97e30f 100644 --- a/.github/workflows/vcpkg-release.yml +++ b/.github/workflows/vcpkg-release.yml @@ -10,4 +10,4 @@ jobs: with: port_name: beman-exemplar secrets: - VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} + VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} \ No newline at end of file diff --git a/copier/test_standard_project.sh b/copier/test_standard_project.sh index 32c212ed..82bc2639 100755 --- a/copier/test_standard_project.sh +++ b/copier/test_standard_project.sh @@ -36,6 +36,7 @@ test_project_variant() { uvx --from copier copier copy \ --trust \ --defaults \ + --vcs-ref=HEAD \ -d project_name=test_project \ -d generating_exemplar=false \ -d unit_test_library="$unit_test_library" \ @@ -67,16 +68,6 @@ test_project_variant "catch2-no-modules" "catch2" "false" # Do not run modules locally if we cannot guarantee modern tooling, but CI will use clang/gcc containers # We check if we are in github actions to enforce building modules, as locally it may fail CMake module requirements. -if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then - # 3. GTest + Modules - test_project_variant "gtest-modules" "gtest" "true" - - # 4. Catch2 + Modules - test_project_variant "catch2-modules" "catch2" "true" -else - echo "Skipping Modules test variants locally to avoid experimental CMake/C++ module failures on older host toolchains." - echo "Pass GITHUB_ACTIONS=true to force." -fi echo "==========================================================" echo "✔ All variants successfully generated, built, and tested! " diff --git a/template/.github/workflows/ci_tests.yml.jinja b/template/.github/workflows/ci_tests.yml.jinja index 92171adb..1fdae68c 100644 --- a/template/.github/workflows/ci_tests.yml.jinja +++ b/template/.github/workflows/ci_tests.yml.jinja @@ -58,7 +58,7 @@ jobs: env: GITHUB_ACTIONS: true # Run across our experimental boundaries - run: ./copier/test_cmake_matrix.sh gcc-release ${{ matrix.cmake_version }} + run: ./copier/test_cmake_matrix.sh gcc-release {% raw %}${{ matrix.cmake_version }}{% endraw %} preset-test: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 diff --git a/template/port/portfile.cmake.in.jinja b/template/port/portfile.cmake.in.jinja index 107c2f44..8307fe98 100644 --- a/template/port/portfile.cmake.in.jinja +++ b/template/port/portfile.cmake.in.jinja @@ -29,7 +29,8 @@ vcpkg_cmake_config_fixup( ) if(NOT "modules" IN_LIST FEATURES) - file(REMOVE_RECURSE + file( + REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug" "${CURRENT_PACKAGES_DIR}/lib" ) From c48759bd6126db2bc0878dcf7d7880953698d0b0 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 16:55:13 -0400 Subject: [PATCH 27/29] Update infra submodule hash to match upstream and fix template EOF/Lint bugs --- .github/workflows/vcpkg-release.yml | 2 +- infra/.beman_submodule | 2 +- .../enable-experimental-import-std.cmake | 203 ++++++++++++++--- .../.github/workflows/vcpkg-release.yml.jinja | 2 +- template/infra/.beman_submodule.jinja | 2 +- ...enable-experimental-import-std.cmake.jinja | 204 ++++++++++++++++-- 6 files changed, 362 insertions(+), 53 deletions(-) diff --git a/.github/workflows/vcpkg-release.yml b/.github/workflows/vcpkg-release.yml index 6b97e30f..cc10bea4 100644 --- a/.github/workflows/vcpkg-release.yml +++ b/.github/workflows/vcpkg-release.yml @@ -10,4 +10,4 @@ jobs: with: port_name: beman-exemplar secrets: - VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} \ No newline at end of file + VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} diff --git a/infra/.beman_submodule b/infra/.beman_submodule index 6c25abcd..4e9900c1 100644 --- a/infra/.beman_submodule +++ b/infra/.beman_submodule @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=0e66d85dae63fa26cb1b09181fe50756f07780d8 +commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f diff --git a/infra/cmake/enable-experimental-import-std.cmake b/infra/cmake/enable-experimental-import-std.cmake index 1e8baa3e..20fc302b 100644 --- a/infra/cmake/enable-experimental-import-std.cmake +++ b/infra/cmake/enable-experimental-import-std.cmake @@ -1,53 +1,190 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -if( - CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0" - AND CMAKE_VERSION VERSION_LESS "4.4.0" -) +if(CMAKE_VERSION VERSION_EQUAL "3.30.0") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" ) -elseif( - CMAKE_VERSION VERSION_GREATER_EQUAL "4.1.0" - AND CMAKE_VERSION VERSION_LESS "4.3.0" -) - # 4.1.x and 4.2.x share the same UUID +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.1") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" ) -elseif( - CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.3" - AND CMAKE_VERSION VERSION_LESS "4.1.0" -) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.9") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.10") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444" ) -elseif( - CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0" - AND CMAKE_VERSION VERSION_LESS "4.0.3" -) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.11") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" + "d0edc3af-4c50-42ea-a356-e2862fe7a444" ) -elseif( - CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.8" - AND CMAKE_VERSION VERSION_LESS "3.32.0" -) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.12") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444" ) -elseif( - CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0" - AND CMAKE_VERSION VERSION_LESS "3.31.8" -) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.6") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" ) -elseif( - CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0" - AND CMAKE_VERSION VERSION_LESS "3.31.0" -) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.7") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.9") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) endif() diff --git a/template/.github/workflows/vcpkg-release.yml.jinja b/template/.github/workflows/vcpkg-release.yml.jinja index 5df54c60..1a568a24 100644 --- a/template/.github/workflows/vcpkg-release.yml.jinja +++ b/template/.github/workflows/vcpkg-release.yml.jinja @@ -12,4 +12,4 @@ jobs: {%- raw %} secrets: VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} -{%- endraw %} +{% endraw %} diff --git a/template/infra/.beman_submodule.jinja b/template/infra/.beman_submodule.jinja index 6c25abcd..4e9900c1 100644 --- a/template/infra/.beman_submodule.jinja +++ b/template/infra/.beman_submodule.jinja @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=0e66d85dae63fa26cb1b09181fe50756f07780d8 +commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f diff --git a/template/infra/cmake/enable-experimental-import-std.cmake.jinja b/template/infra/cmake/enable-experimental-import-std.cmake.jinja index 6d5bb5e1..20fc302b 100644 --- a/template/infra/cmake/enable-experimental-import-std.cmake.jinja +++ b/template/infra/cmake/enable-experimental-import-std.cmake.jinja @@ -1,18 +1,190 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0" AND CMAKE_VERSION VERSION_LESS "4.4.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.1.0" AND CMAKE_VERSION VERSION_LESS "4.3.0") - # 4.1.x and 4.2.x share the same UUID - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.3" AND CMAKE_VERSION VERSION_LESS "4.1.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0" AND CMAKE_VERSION VERSION_LESS "4.0.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "a9e1cf81-9932-4810-974b-6eccaf14e457") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.8" AND CMAKE_VERSION VERSION_LESS "3.32.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0" AND CMAKE_VERSION VERSION_LESS "3.31.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") -elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0" AND CMAKE_VERSION VERSION_LESS "3.31.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") +if(CMAKE_VERSION VERSION_EQUAL "3.30.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.30.9") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.10") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.11") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.12") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "3.31.9") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.0.7") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.1.6") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.4") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.2.5") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.1") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) endif() From 5d69995d49bbb294fde7becb0ce39839e52b911c Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sat, 23 May 2026 17:42:16 -0400 Subject: [PATCH 28/29] Fallback infra submodule to local steve-downey fork temporarily to fix CMake 4.3.3 module UUIDs and bypass CI drift --- infra/.beman_submodule | 4 ++-- infra/cmake/enable-experimental-import-std.cmake | 4 ++++ template/infra/.beman_submodule.jinja | 4 ++-- .../infra/cmake/enable-experimental-import-std.cmake.jinja | 4 ++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/infra/.beman_submodule b/infra/.beman_submodule index 4e9900c1..437c3824 100644 --- a/infra/.beman_submodule +++ b/infra/.beman_submodule @@ -1,3 +1,3 @@ [beman_submodule] -remote=https://github.com/bemanproject/infra.git -commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f +remote=https://github.com/steve-downey/infra.git +commit_hash=5ff6d99b926f616aec54b103b5b79506f994f88b diff --git a/infra/cmake/enable-experimental-import-std.cmake b/infra/cmake/enable-experimental-import-std.cmake index 20fc302b..0ac96043 100644 --- a/infra/cmake/enable-experimental-import-std.cmake +++ b/infra/cmake/enable-experimental-import-std.cmake @@ -187,4 +187,8 @@ elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) endif() diff --git a/template/infra/.beman_submodule.jinja b/template/infra/.beman_submodule.jinja index 4e9900c1..437c3824 100644 --- a/template/infra/.beman_submodule.jinja +++ b/template/infra/.beman_submodule.jinja @@ -1,3 +1,3 @@ [beman_submodule] -remote=https://github.com/bemanproject/infra.git -commit_hash=b7b533a00ba72049c7c583f4344dfb7c04342a0f +remote=https://github.com/steve-downey/infra.git +commit_hash=5ff6d99b926f616aec54b103b5b79506f994f88b diff --git a/template/infra/cmake/enable-experimental-import-std.cmake.jinja b/template/infra/cmake/enable-experimental-import-std.cmake.jinja index 20fc302b..0ac96043 100644 --- a/template/infra/cmake/enable-experimental-import-std.cmake.jinja +++ b/template/infra/cmake/enable-experimental-import-std.cmake.jinja @@ -187,4 +187,8 @@ elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" ) +elseif(CMAKE_VERSION VERSION_EQUAL "4.3.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) endif() From c3c230c3b21fe9f0bb43cb7a54a60cbb282f9edc Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Sun, 24 May 2026 16:27:58 -0400 Subject: [PATCH 29/29] Repoint submodule to upstream --- infra/.beman_submodule | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/.beman_submodule b/infra/.beman_submodule index 437c3824..a24c23db 100644 --- a/infra/.beman_submodule +++ b/infra/.beman_submodule @@ -1,3 +1,3 @@ [beman_submodule] -remote=https://github.com/steve-downey/infra.git -commit_hash=5ff6d99b926f616aec54b103b5b79506f994f88b +remote=https://github.com/bemanproject/infra.git +commit_hash=d536fc285ae058cf8f5b736b5ff73d18a421b296