From 039a2036a0d51b78991db9c97cae7eb422f1086d Mon Sep 17 00:00:00 2001 From: jainsujan11 Date: Wed, 3 Dec 2025 11:54:20 +0530 Subject: [PATCH] Initial project setup for beman.transform_view_join --- CMakeLists.txt | 29 +- README.md | 388 +------------ cookiecutter/check_cookiecutter.sh | 79 --- cookiecutter/cookiecutter.json | 12 - .../.clang-format | 242 -------- .../.devcontainer/devcontainer.json | 16 - .../.gitattributes | 5 - .../.github/CODEOWNERS | 23 - .../implementation-deficiency.md | 35 -- .../ISSUE_TEMPLATE/infrastructure-issues.md | 29 - .../ISSUE_TEMPLATE/paper-discussion.md | 33 -- .../.github/pull_request_template.md | 5 - .../.github/workflows/ci_tests.yml | 140 ----- .../.github/workflows/pre-commit-check.yml | 13 - .../.github/workflows/pre-commit-update.yml | 15 - .../{{cookiecutter.project_name}}/.gitignore | 12 - .../.markdownlint.yaml | 10 - .../.pre-commit-config.yaml | 42 -- .../CMakeLists.txt | 37 -- .../CMakePresets.json | 373 ------------ .../{{cookiecutter.project_name}}/LICENSE | 219 ------- .../{{cookiecutter.project_name}}/README.md | 387 ------------- .../examples/CMakeLists.txt | 27 - .../identity_as_default_projection.cpp | 75 --- .../examples/identity_direct_usage.cpp | 12 - .../identity.hpp | 42 -- .../infra/.beman_submodule | 3 - .../infra/.github/CODEOWNERS | 1 - .../.github/workflows/beman-submodule.yml | 32 -- .../infra/.github/workflows/beman-tidy.yml | 111 ---- .../infra/.github/workflows/pre-commit.yml | 78 --- ...reusable-beman-create-issue-when-fault.yml | 28 - .../infra/.gitignore | 59 -- .../infra/.pre-commit-config.yaml | 32 -- .../infra/.pre-commit-hooks.yaml | 7 - .../infra/LICENSE | 219 ------- .../infra/README.md | 57 -- .../infra/cmake/appleclang-toolchain.cmake | 44 -- .../cmake/beman-install-library-config.cmake | 169 ------ .../infra/cmake/gnu-toolchain.cmake | 41 -- .../infra/cmake/llvm-libc++-toolchain.cmake | 20 - .../infra/cmake/llvm-toolchain.cmake | 41 -- .../infra/cmake/msvc-toolchain.cmake | 41 -- .../infra/cmake/use-fetch-content.cmake | 187 ------ .../infra/tools/beman-submodule/README.md | 63 -- .../tools/beman-submodule/beman-submodule | 260 --------- .../test/test_beman_submodule.py | 539 ------------------ .../lockfile.json | 10 - .../CMakeLists.txt | 20 - ...ookiecutter.project_name}}-config.cmake.in | 7 - .../identity.cpp | 3 - .../CMakeLists.txt | 13 - .../identity.test.cpp | 55 -- examples/CMakeLists.txt | 23 +- examples/identity_as_default_projection.cpp | 75 --- examples/identity_direct_usage.cpp | 12 - examples/transform_view_join_direct_usage.cpp | 12 + include/beman/exemplar/identity.hpp | 42 -- .../beman/transform_join_view/identity.hpp | 12 + lockfile.json | 8 +- src/beman/exemplar/CMakeLists.txt | 20 - .../exemplar/beman.exemplar-config.cmake.in | 7 - src/beman/exemplar/identity.cpp | 3 - tests/beman/exemplar/CMakeLists.txt | 13 - tests/beman/exemplar/identity.test.cpp | 55 -- .../beman/transform_join_view/CMakeLists.txt | 20 + .../transform_view_join.test.cpp | 13 + 67 files changed, 88 insertions(+), 4667 deletions(-) delete mode 100755 cookiecutter/check_cookiecutter.sh delete mode 100644 cookiecutter/cookiecutter.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.clang-format delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.devcontainer/devcontainer.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.gitattributes delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.gitignore delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/LICENSE delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/README.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-submodule.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-tidy.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-hooks.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/README.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library-config.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/README.md delete mode 100755 cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/beman-submodule delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/test/test_beman_submodule.py delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/lockfile.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/beman.{{cookiecutter.project_name}}-config.cmake.in delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp 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 delete mode 100644 examples/identity_as_default_projection.cpp delete mode 100644 examples/identity_direct_usage.cpp create mode 100644 examples/transform_view_join_direct_usage.cpp delete mode 100644 include/beman/exemplar/identity.hpp create mode 100644 include/beman/transform_join_view/identity.hpp delete mode 100644 src/beman/exemplar/CMakeLists.txt delete mode 100644 src/beman/exemplar/beman.exemplar-config.cmake.in delete mode 100644 src/beman/exemplar/identity.cpp delete mode 100644 tests/beman/exemplar/CMakeLists.txt delete mode 100644 tests/beman/exemplar/identity.test.cpp create mode 100644 tests/beman/transform_join_view/CMakeLists.txt create mode 100644 tests/beman/transform_join_view/transform_view_join.test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c098765..2d17e4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,35 +3,48 @@ cmake_minimum_required(VERSION 3.25) project( - beman.exemplar # CMake Project Name, which is also the name of the top-level + beman.transform_join_view # CMake Project Name, which is also the name of the top-level # targets (e.g., library, executable, etc.). - DESCRIPTION "A Beman Library Exemplar" + DESCRIPTION "Beman transform_join_view library" LANGUAGES CXX VERSION 2.2.1 ) # [CMAKE.SKIP_TESTS] option( - BEMAN_EXEMPLAR_BUILD_TESTS + BEMAN_TRANSFORM_JOIN_VIEW_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_EXEMPLAR_BUILD_EXAMPLES + BEMAN_TRANSFORM_JOIN_VIEW_BUILD_EXAMPLES "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." ${PROJECT_IS_TOP_LEVEL} ) include(CTest) -add_subdirectory(src/beman/exemplar) +# Define header-only library +add_library(beman.transform_join_view INTERFACE) +add_library(beman::transform_join_view ALIAS beman.transform_join_view) + +target_sources( + beman.transform_join_view + INTERFACE + FILE_SET HEADERS + BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/include/beman/transform_join_view/identity.hpp" +) + +target_compile_features(beman.transform_join_view INTERFACE cxx_std_20) -if(BEMAN_EXEMPLAR_BUILD_TESTS) - add_subdirectory(tests/beman/exemplar) +if(BEMAN_TRANSFORM_JOIN_VIEW_BUILD_TESTS) + add_subdirectory(tests/beman/transform_join_view) endif() -if(BEMAN_EXEMPLAR_BUILD_EXAMPLES) +if(BEMAN_TRANSFORM_JOIN_VIEW_BUILD_EXAMPLES) add_subdirectory(examples) endif() diff --git a/README.md b/README.md index cb32dfd..ba931c3 100644 --- a/README.md +++ b/README.md @@ -1,387 +1 @@ -# 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. - -**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.exemplar` is licensed under the Apache License v2.0 with LLVM Exceptions. - -## Usage - -`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::exemplar::identity`: - -```cpp -#include - -namespace exe = beman::exemplar; - -// Class with a pair of values. -struct Pair -{ - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream &operator<<(std::ostream &os, const Pair &p) - { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print(const std::string_view rem, R &&range, Projection projection = exe::identity>) -{ - std::cout << rem << '{'; - std::ranges::for_each( - range, - [O = 0](const auto &o) mutable - { std::cout << (O++ ? ", " : "") << o; }, - projection); - std::cout << "}\n"; -}; - -int main() -{ - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - print("\tpairs with beman: ", pairs); - - return 0; -} - -``` - -Full runnable examples can be found in [`examples/`](examples/). - -## Dependencies - -### Build Environment - -This project requires at least the following to build: - -* A C++ compiler that conforms to the C++17 standard or greater -* CMake 3.25 or later -* (Test Only) GoogleTest - -You can disable building tests by setting CMake option -[`BEMAN_EXEMPLAR_BUILD_TESTS`](#beman_exemplar_build_tests) to `OFF` -when configuring the project. - -Even when tests are being built and run, some of them will not be compiled -unless the provided compiler supports **C++20** ranges. - -> [!TIP] -> -> The logs indicate examples disabled due to lack of compiler support. -> -> For example: -> -> ```txt -> -- Looking for __cpp_lib_ranges -> -- Looking for __cpp_lib_ranges - not found -> CMake Warning at examples/CMakeLists.txt:12 (message): -> Missing range support! Skip: identity_as_default_projection -> -> -> Examples to be built: identity_direct_usage -> ``` - -### Supported Platforms - -This project officially supports: - -* GCC versions 11–15 -* LLVM Clang++ (with libstdc++ or libc++) versions 17–21 -* AppleClang version 17.0.0 (i.e., the [latest version on GitHub-hosted macOS runners](https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md)) -* MSVC version 19.44.35215.0 (i.e., the [latest version on GitHub-hosted Windows runners](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md)) - -> [!NOTE] -> -> Versions outside of this range would likely work as well, -> especially if you're using a version above the given range -> (e.g. HEAD/ nightly). -> These development environments are verified using our CI configuration. - -## Development - -### Develop using GitHub Codespace - -This project supports [GitHub Codespace](https://github.com/features/codespaces) -via [Development Containers](https://containers.dev/), -which allows rapid development and instant hacking in your browser. -We recommend using GitHub codespace to explore this project as it -requires minimal setup. - -Click the following badge to create a codespace: - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/bemanproject/exemplar) - -For more documentation on GitHub codespaces, please see -[this doc](https://docs.github.com/en/codespaces/). - -> [!NOTE] -> -> The codespace container may take up to 5 minutes to build and spin-up; this is normal. - -### Develop locally on your machines - -
- For Linux - -Beman libraries require [recent versions of CMake](#build-environment), -we recommend downloading CMake directly from [CMake's website](https://cmake.org/download/) -or installing it with the [Kitware apt library](https://apt.kitware.com/). - -A [supported compiler](#supported-platforms) should be available from your package manager. - -
- -
- For MacOS - -Beman libraries require [recent versions of CMake](#build-environment). -Use [`Homebrew`](https://brew.sh/) to install the latest version of CMake. - -```bash -brew install cmake -``` - -A [supported compiler](#supported-platforms) is also available from brew. - -For example, you can install the latest major release of Clang as: - -```bash -brew install llvm -``` - -
- -
- For Windows - -To build Beman libraries, you will need the MSVC compiler. MSVC can be obtained -by installing Visual Studio; the free Visual Studio 2022 Community Edition can -be downloaded from -[Microsoft](https://visualstudio.microsoft.com/vs/community/). - -After Visual Studio has been installed, you can launch "Developer PowerShell for -VS 2022" by typing it into Windows search bar. This shell environment will -provide CMake, Ninja, and MSVC, allowing you to build the library and run the -tests. - -Note that you will need to use FetchContent to build GoogleTest. To do so, -please see the instructions in the "Build GoogleTest dependency from github.com" -dropdown in the [Project specific configure -arguments](#project-specific-configure-arguments) section. - -
- -### Configure and Build the Project Using CMake Presets - -This project recommends using [CMake Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) -to configure, build and test the project. -Appropriate presets for major compilers have been included by default. -You can use `cmake --list-presets` to see all available presets. - -Here is an example to invoke the `gcc-debug` preset. - -```shell -cmake --workflow --preset gcc-debug -``` - -Generally, there are two kinds of presets, `debug` and `release`. - -The `debug` presets are designed to aid development, so it has debugging -instrumentation enabled and many sanitizers enabled. - -> [!NOTE] -> -> The sanitizers that are enabled vary from compiler to compiler. -> See the toolchain files under ([`cmake`](cmake/)) to determine the exact configuration used for each preset. - -The `release` presets are designed for production use, and -consequently have the highest optimization turned on (e.g. `O3`). - -### Configure and Build Manually - -If the presets are not suitable for your use-case, a traditional CMake -invocation will provide more configurability. - -To configure, build and test the project with extra arguments, -you can run this set of commands. - -```bash -cmake \ - -B build \ - -S . \ - -DCMAKE_CXX_STANDARD=20 \ - -DCMAKE_PREFIX_PATH=$PWD/infra/cmake \ - # Your extra arguments here. -cmake --build build -ctest --test-dir build -``` - -> [!IMPORTANT] -> -> Beman projects are -> [passive projects](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md#cmake), -> therefore, -> you will need to specify the C++ version via `CMAKE_CXX_STANDARD` -> when manually configuring the project. - -### Finding and Fetching GTest from GitHub - -If you do not have GoogleTest installed on your development system, you may -optionally configure this project to download a known-compatible release of -GoogleTest from source and build it as well. - -Example commands: - -```shell -cmake -B build -S . \ - -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake \ - -DCMAKE_CXX_STANDARD=20 -cmake --build build --target all -cmake --build build --target test -``` - -The precise version of GoogleTest that will be used is maintained in -`./lockfile.json`. - -### Project specific configure arguments - -Project-specific options are prefixed with `BEMAN_EXEMPLAR`. -You can see the list of available options with: - -```bash -cmake -LH -S . -B build | grep "BEMAN_EXEMPLAR" -C 2 -``` - -
- - Details of CMake arguments. - -#### `BEMAN_EXEMPLAR_BUILD_TESTS` - -Enable building tests and test infrastructure. Default: ON. -Values: `{ ON, OFF }`. - -You can configure the project to have this option turned off via: - -```bash -cmake -B build -S . -DCMAKE_CXX_STANDARD=20 -DBEMAN_EXEMPLAR_BUILD_TESTS=OFF -``` - -> [!TIP] -> Because this project requires GoogleTest for running tests, -> disabling `BEMAN_EXEMPLAR_BUILD_TESTS` avoids the project from -> cloning GoogleTest from GitHub. - -#### `BEMAN_EXEMPLAR_BUILD_EXAMPLES` - -Enable building examples. Default: ON. Values: { ON, OFF }. - - -#### `BEMAN_EXEMPLAR_INSTALL_CONFIG_FILE_PACKAGE` - -Enable installing the CMake config file package. Default: ON. -Values: { ON, OFF }. - -This is required so that users of `beman.exemplar` can use -`find_package(beman.exemplar)` to locate the library. - -
- -## Integrate beman.exemplar into your project - -To use `beman.exemplar` in your C++ project, -include an appropriate `beman.exemplar` header from your source code. - -```c++ -#include -``` - -> [!NOTE] -> -> `beman.exemplar` headers are to be included with the `beman/exemplar/` prefix. -> Altering include search paths to spell the include target another way (e.g. -> `#include `) is unsupported. - -The process for incorporating `beman.exemplar` into your project depends on the -build system being used. Instructions for CMake are provided in following sections. - -### Incorporating `beman.exemplar` into your project with CMake - -For CMake based projects, -you will need to use the `beman.exemplar` CMake module -to define the `beman::exemplar` CMake target: - -```cmake -find_package(beman.exemplar REQUIRED) -``` - -You will also need to add `beman::exemplar` to the link libraries of -any libraries or executables that include `beman.exemplar` headers. - -```cmake -target_link_libraries(yourlib PUBLIC beman::exemplar) -``` - -### Produce beman.exemplar static library - -You can include exemplar's headers locally -by producing a static `libbeman.exemplar.a` library. - -```bash -cmake --workflow --preset gcc-release -cmake --install build/gcc-release --prefix /opt/beman -``` - -This will generate the following directory structure at `/opt/beman`. - -```txt -/opt/beman -├── include -│ └── beman -│ └── exemplar -│ └── identity.hpp -└── lib - ├── cmake - │   └── beman.exemplar - │   ├── beman.exemplar-config-version.cmake - │   ├── beman.exemplar-config.cmake - │   ├── beman.exemplar-targets-debug.cmake - │   └── beman.exemplar-targets.cmake - └── libbeman.exemplar.a -``` +# beman.transform_join_view: Beman transform_join_view library \ No newline at end of file diff --git a/cookiecutter/check_cookiecutter.sh b/cookiecutter/check_cookiecutter.sh deleted file mode 100755 index fb5cb04..0000000 --- a/cookiecutter/check_cookiecutter.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -declare script_dir=$(realpath $(dirname "$BASH_SOURCE")) - -function check_consistency() { - 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="exemplar" \ - cpp_build_version="17" \ - paper="P0898R3" \ - owner="bemanproject" \ - description="A Beman Library Exemplar" \ - godbolt_link="https://godbolt.org/z/4qEPK87va" - cp "$script_dir"/../.github/workflows/cookiecutter_test.yml "$out_dir_path"/exemplar/.github/workflows - 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" \ - cpp_build_version="17" \ - paper="P0898R3" \ - owner="bemanproject" \ - description="A Beman Library RLZrmX9NfS" \ - godbolt_link="https://godbolt.org/z/4qEPK87va" - rm -rf "$out_dir_path/RLZrmX9NfS/infra" - local grep_path - grep_path=$(mktemp) - grep \ - --dereference-recursive --context=5 --color=always \ - "exemplar" "$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\" in cookiecutter:" >&2 - cat "$grep_path" - rm "$grep_path" - exit 1 - fi - rm "$grep_path" -} - -function main() { - local 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 >& /dev/null - 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 a33b87b..0000000 --- a/cookiecutter/cookiecutter.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "project_name": "my_project_name", - "cpp_build_version": "26", - "paper": "PnnnnRr", - "owner": "github-user-name", - "description": "Short project description.", - "godbolt_link": "https://www.example.com", - "_copy_without_render": [ - "infra", - ".github/workflows" - ] -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.clang-format b/cookiecutter/{{cookiecutter.project_name}}/.clang-format deleted file mode 100644 index 05baf03..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.clang-format +++ /dev/null @@ -1,242 +0,0 @@ ---- -Language: Cpp -AccessModifierOffset: -2 -AlignAfterOpenBracket: Align -AlignArrayOfStructures: None -AlignConsecutiveAssignments: - Enabled: true - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: true -AlignConsecutiveBitFields: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignConsecutiveDeclarations: - Enabled: true - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: true -AlignConsecutiveMacros: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignConsecutiveShortCaseStatements: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCaseColons: false -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: - Kind: Always - OverEmptyLines: 0 -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Never -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: true -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: Yes -AttributeMacros: - - __capability -BinPackArguments: false -BinPackParameters: false -BitFieldColonSpacing: Both -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterExternBlock: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakAfterAttributes: Never -BreakAfterJavaFieldAnnotations: false -BreakArrays: true -BreakBeforeBinaryOperators: None -BreakBeforeConceptDeclarations: Always -BreakBeforeBraces: Custom -BreakBeforeInlineASMColon: OnlyMultiline -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakInheritanceList: BeforeColon -BreakStringLiterals: true -# Please update .markdownlint.yaml if this line is to be updated -ColumnLimit: 119 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IfMacros: - - KJ_IF_MAYBE -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '$' -IncludeIsMainSourceRegex: '' -IndentAccessModifiers: false -IndentCaseBlocks: false -IndentCaseLabels: false -IndentExternBlock: AfterExternBlock -IndentGotoLabels: true -IndentPPDirectives: None -IndentRequiresClause: true -IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertBraces: false -InsertNewlineAtEOF: false -InsertTrailingCommas: None -IntegerLiteralSeparator: - Binary: 0 - BinaryMinDigits: 0 - Decimal: 0 - DecimalMinDigits: 0 - Hex: 0 - HexMinDigits: 0 -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -KeepEmptyLinesAtEOF: false -LambdaBodyIndentation: Signature -LineEnding: DeriveLF -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 4 -ObjCBreakBeforeNestedBlockParam: true -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PackConstructorInitializers: NextLine -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyIndentedWhitespace: 0 -PenaltyReturnTypeOnItsOwnLine: 60 -PointerAlignment: Left -PPIndentWidth: -1 -QualifierAlignment: Custom -QualifierOrder: - - inline - - static - - constexpr - - const - - volatile - - type -ReferenceAlignment: Pointer -ReflowComments: true -RemoveBracesLLVM: false -RemoveParentheses: Leave -RemoveSemicolon: false -RequiresClausePosition: OwnLine -RequiresExpressionIndentation: OuterScope -SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 1 -SortIncludes: Never -SortJavaStaticImport: Before -SortUsingDeclarations: LexicographicNumeric -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceAroundPointerQualifiers: Default -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeJsonColon: false -SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - AfterRequiresInClause: false - AfterRequiresInExpression: false - BeforeNonEmptyParentheses: false -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: Never -SpacesInContainerLiterals: true -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 -SpacesInParens: Never -SpacesInParensOptions: - InCStyleCasts: false - InConditionalStatements: false - InEmptyParentheses: false - Other: false -SpacesInSquareBrackets: false -Standard: Auto -StatementAttributeLikeMacros: - - Q_EMIT -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 8 -UseTab: Never -VerilogBreakBetweenInstancePorts: true -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE - - NS_SWIFT_NAME - - CF_SWIFT_NAME -... diff --git a/cookiecutter/{{cookiecutter.project_name}}/.devcontainer/devcontainer.json b/cookiecutter/{{cookiecutter.project_name}}/.devcontainer/devcontainer.json deleted file mode 100644 index b0909de..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.devcontainer/devcontainer.json +++ /dev/null @@ -1,16 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/cpp - -{ - "name": "Beman Project Generic Devcontainer", - "image": "ghcr.io/bemanproject/infra-containers-devcontainer-gcc:14", - "postCreateCommand": "pre-commit", - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-vscode.cmake-tools" - ] - } - } -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.gitattributes b/cookiecutter/{{cookiecutter.project_name}}/.gitattributes deleted file mode 100644 index 793dce7..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -infra/** linguist-vendored -cookiecutter/** linguist-vendored -*.bib -linguist-detectable -*.tex -linguist-detectable -papers/* linguist-documentation diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS b/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS deleted file mode 100644 index baa04f0..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Codeowners for reviews on PRs - -# Note(river): -# **Please understand how codeowner file work before uncommenting anything in this section:** -# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners -# -# For projects using {{cookiecutter.project_name}} as a template and intend to reuse its infrastructure, -# River (@wusatosi) helped create most of the original infrastructure under the scope described below, -# they are more than happy to help out with any PRs downstream, -# as well as to sync any useful change upstream to {{cookiecutter.project_name}}. -# -# Github Actions: -# .github/workflows/ @wusatosi # Add other project owners here -# -# Devcontainer: -# .devcontainer/ @wusatosi # Add other project owners here -# -# Pre-commit: -# .pre-commit-config.yaml @wusatosi # Add other project owners here -# .markdownlint.yaml @wusatosi # Add other project owners here - -* @ednolan @bretbrownjr @camio @dietmarkuehl @neatudarius @steve-downey @wusatosi diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md b/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md deleted file mode 100644 index 4a0ee77..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Implementation Deficiency -about: Report a bug or performance issue of our implementation -title: '' -labels: bug -assignees: '' - ---- - - - -## Describe the deficiency - -A clear and concise description of what the deficiency is. -Link all relevant issues. -This could be a bug, or a performance problem. - -## To Reproduce - -```c++ -// Use case -``` - -## Expected Behavior - -A clear and concise description of what you expected to happen. - -## Additional Discussions - -Add any other context about the problem here. -If you believe your issue is platform dependent, -please post your compiler versions here. diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md b/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md deleted file mode 100644 index 11fbd13..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: Infrastructure Issues -about: Report a bug or feature request with our Infrastructure -title: '' -labels: infra -assignees: '' - ---- - - - -## I am attempting to - -Describe what you were attempting to do. - -## Expected Behavior - -A clear and concise description of what you expected to happen. - -## Current Behavior - -A clear and concise description of what actually happened. - -## Additional Discussions - -Add any other context about the problem here. diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md b/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md deleted file mode 100644 index 14c9e4f..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Paper Discussion -about: Provide feedback to current API -title: '' -labels: '' -assignees: '' - ---- - - - -## Use case - -Describe your concerns about adding this change to the C++ Standard Library. - -```c++ -// example snippet -``` - -## What I like - -Let us know what you find positive about current approach / design. - -## What I dislike - -Let us know what you find negative about current approach / design. - -## Discussion - -Let us know if you have any more remarks. diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md b/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md deleted file mode 100644 index 071cb28..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml deleted file mode 100644 index 4ae60bf..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml +++ /dev/null @@ -1,140 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: Continuous Integration Tests - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - schedule: - - cron: '30 15 * * *' - -jobs: - beman-submodule-check: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.1.0 - - preset-test: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.1.0 - with: - matrix_config: > - [ - {"preset": "gcc-debug", "image": "ghcr.io/bemanproject/infra-containers-gcc:latest"}, - {"preset": "gcc-release", "image": "ghcr.io/bemanproject/infra-containers-gcc:latest"}, - {"preset": "llvm-debug", "image": "ghcr.io/bemanproject/infra-containers-clang:latest"}, - {"preset": "llvm-release", "image": "ghcr.io/bemanproject/infra-containers-clang:latest"}, - {"preset": "appleclang-debug", "runner": "macos-latest"}, - {"preset": "appleclang-release", "runner": "macos-latest"}, - {"preset": "msvc-debug", "runner": "windows-latest"}, - {"preset": "msvc-release", "runner": "windows-latest"} - ] - - build-and-test: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-build-and-test.yml@1.1.0 - with: - matrix_config: > - { - "gcc": [ - { "versions": ["15"], - "tests": [ - { "cxxversions": ["c++26"], - "tests": [ - { "stdlibs": ["libstdc++"], - "tests": [ - "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", "Debug.Dynamic", - "Debug.Coverage" - ] - } - ] - }, - { "cxxversions": ["c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - }, - { "versions": ["14", "13"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - }, - { - "versions": ["12", "11"], - "tests": [ - { "cxxversions": ["c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - } - ], - "clang": [ - { "versions": ["21"], - "tests": [ - {"cxxversions": ["c++26"], - "tests": [ - { "stdlibs": ["libstdc++", "libc++"], - "tests": [ - "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", "Debug.Dynamic" - ] - } - ] - }, - { "cxxversions": ["c++23", "c++20", "c++17"], - "tests": [ - {"stdlibs": ["libstdc++", "libc++"], "tests": ["Release.Default"]} - ] - } - ] - }, - { "versions": ["20", "19", "18"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [ - {"stdlibs": ["libstdc++", "libc++"], "tests": ["Release.Default"]} - ] - } - ] - }, - { "versions": ["17"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{"stdlibs": ["libc++"], "tests": ["Release.Default"]}] - }, - { "cxxversions": ["c++20", "c++17"], - "tests": [{"stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - } - ], - "appleclang": [ - { "versions": ["latest"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libc++"], "tests": ["Release.Default"]}] - } - ] - } - ], - "msvc": [ - { "versions": ["latest"], - "tests": [ - { "cxxversions": ["c++23"], - "tests": [ - { "stdlibs": ["stl"], - "tests": ["Debug.Default", "Release.Default", "Release.MaxSan"] - } - ] - } - ] - } - ] - } - - create-issue-when-fault: - needs: [preset-test, build-and-test] - if: failure() && github.event_name == 'schedule' - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-create-issue-when-fault.yml@1.1.0 diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml deleted file mode 100644 index 70895b4..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: Lint Check (pre-commit) - -on: - # We have to use pull_request_target here as pull_request does not grant - # enough permission for reviewdog - pull_request_target: - push: - branches: - - main - -jobs: - pre-commit: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-pre-commit.yml@1.1.0 diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml deleted file mode 100644 index ec7ac74..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: Weekly pre-commit autoupdate - -on: - workflow_dispatch: - schedule: - - cron: "0 16 * * 0" - -jobs: - auto-update-pre-commit: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-update-pre-commit.yml@1.1.0 - secrets: - APP_ID: ${{ secrets.AUTO_PR_BOT_APP_ID }} - PRIVATE_KEY: ${{ secrets.AUTO_PR_BOT_PRIVATE_KEY }} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.gitignore b/cookiecutter/{{cookiecutter.project_name}}/.gitignore deleted file mode 100644 index d293e3b..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -/.cache -/compile_commands.json -/build - -# ignore emacs temp files -*~ -\#*\# - -# ignore vscode settings -.vscode diff --git a/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml b/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml deleted file mode 100644 index 21c2849..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md033.md -# Disable inline html linter is needed for
-MD033: false - -# MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md013.md -# Conforms to .clang-format ColumnLimit -# Update the comment in .clang-format if we no-longer tie these two column limits. -MD013: - line_length: 119 - code_blocks: false diff --git a/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml deleted file mode 100644 index 32f726b..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files - - # Clang-format for C++ - # This brings in a portable version of clang-format. - # See also: https://github.com/ssciwr/clang-format-wheel - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v21.1.6 - hooks: - - id: clang-format - types_or: [c++, c] - - # CMake linting and formatting - - repo: https://github.com/BlankSpruce/gersemi - rev: 0.23.2 - hooks: - - id: gersemi - name: CMake linting - exclude: ^.*/tests/.*/data/ # Exclude test data directories - - # Markdown linting - # Config file: .markdownlint.yaml - # Commented out to disable this by default. Uncomment to enable markdown linting. - # - repo: https://github.com/igorshubovych/markdownlint-cli - # rev: v0.42.0 - # hooks: - # - id: markdownlint - - - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 - hooks: - - id: codespell - -exclude: 'cookiecutter/|infra/' diff --git a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index dcad0c2..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -cmake_minimum_required(VERSION 3.25) - -project( - beman.{{cookiecutter.project_name}} # CMake Project Name, which is also the name of the top-level - # targets (e.g., library, executable, etc.). - DESCRIPTION "{{cookiecutter.description}}" - LANGUAGES CXX - VERSION 2.2.1 -) - -# [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} -) - -include(CTest) - -add_subdirectory(src/beman/{{cookiecutter.project_name}}) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS) - 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}}/CMakePresets.json b/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json deleted file mode 100644 index 483e1a3..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json +++ /dev/null @@ -1,373 +0,0 @@ -{ - "version": 6, - "configurePresets": [ - { - "name": "_root-config", - "hidden": true, - "generator": "Ninja", - "binaryDir": "${sourceDir}/build/${presetName}", - "cacheVariables": { - "CMAKE_CXX_STANDARD": "20", - "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", - "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "./infra/cmake/use-fetch-content.cmake" - } - }, - { - "name": "_debug-base", - "hidden": true, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "BEMAN_BUILDSYS_SANITIZER": "MaxSan" - } - }, - { - "name": "_release-base", - "hidden": true, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" - } - }, - { - "name": "gcc-debug", - "displayName": "GCC Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/gnu-toolchain.cmake" - } - }, - { - "name": "gcc-release", - "displayName": "GCC Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/gnu-toolchain.cmake" - } - }, - { - "name": "llvm-debug", - "displayName": "Clang Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake" - } - }, - { - "name": "llvm-release", - "displayName": "Clang Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake" - } - }, - { - "name": "appleclang-debug", - "displayName": "Appleclang Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/appleclang-toolchain.cmake" - } - }, - { - "name": "appleclang-release", - "displayName": "Appleclang Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/appleclang-toolchain.cmake" - } - }, - { - "name": "msvc-debug", - "displayName": "MSVC Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake" - } - }, - { - "name": "msvc-release", - "displayName": "MSVC Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake" - } - } - ], - "buildPresets": [ - { - "name": "_root-build", - "hidden": true, - "jobs": 0 - }, - { - "name": "gcc-debug", - "configurePreset": "gcc-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "gcc-release", - "configurePreset": "gcc-release", - "inherits": [ - "_root-build" - ] - }, - { - "name": "llvm-debug", - "configurePreset": "llvm-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "llvm-release", - "configurePreset": "llvm-release", - "inherits": [ - "_root-build" - ] - }, - { - "name": "appleclang-debug", - "configurePreset": "appleclang-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "appleclang-release", - "configurePreset": "appleclang-release", - "inherits": [ - "_root-build" - ] - }, - { - "name": "msvc-debug", - "configurePreset": "msvc-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "msvc-release", - "configurePreset": "msvc-release", - "inherits": [ - "_root-build" - ] - } - ], - "testPresets": [ - { - "name": "_test_base", - "hidden": true, - "output": { - "outputOnFailure": true - }, - "execution": { - "noTestsAction": "error", - "stopOnFailure": true - } - }, - { - "name": "gcc-debug", - "inherits": "_test_base", - "configurePreset": "gcc-debug" - }, - { - "name": "gcc-release", - "inherits": "_test_base", - "configurePreset": "gcc-release" - }, - { - "name": "llvm-debug", - "inherits": "_test_base", - "configurePreset": "llvm-debug" - }, - { - "name": "llvm-release", - "inherits": "_test_base", - "configurePreset": "llvm-release" - }, - { - "name": "appleclang-debug", - "inherits": "_test_base", - "configurePreset": "appleclang-debug" - }, - { - "name": "appleclang-release", - "inherits": "_test_base", - "configurePreset": "appleclang-release" - }, - { - "name": "msvc-debug", - "inherits": "_test_base", - "configurePreset": "msvc-debug" - }, - { - "name": "msvc-release", - "inherits": "_test_base", - "configurePreset": "msvc-release" - } - ], - "workflowPresets": [ - { - "name": "gcc-debug", - "steps": [ - { - "type": "configure", - "name": "gcc-debug" - }, - { - "type": "build", - "name": "gcc-debug" - }, - { - "type": "test", - "name": "gcc-debug" - } - ] - }, - { - "name": "gcc-release", - "steps": [ - { - "type": "configure", - "name": "gcc-release" - }, - { - "type": "build", - "name": "gcc-release" - }, - { - "type": "test", - "name": "gcc-release" - } - ] - }, - { - "name": "llvm-debug", - "steps": [ - { - "type": "configure", - "name": "llvm-debug" - }, - { - "type": "build", - "name": "llvm-debug" - }, - { - "type": "test", - "name": "llvm-debug" - } - ] - }, - { - "name": "llvm-release", - "steps": [ - { - "type": "configure", - "name": "llvm-release" - }, - { - "type": "build", - "name": "llvm-release" - }, - { - "type": "test", - "name": "llvm-release" - } - ] - }, - { - "name": "appleclang-debug", - "steps": [ - { - "type": "configure", - "name": "appleclang-debug" - }, - { - "type": "build", - "name": "appleclang-debug" - }, - { - "type": "test", - "name": "appleclang-debug" - } - ] - }, - { - "name": "appleclang-release", - "steps": [ - { - "type": "configure", - "name": "appleclang-release" - }, - { - "type": "build", - "name": "appleclang-release" - }, - { - "type": "test", - "name": "appleclang-release" - } - ] - }, - { - "name": "msvc-debug", - "steps": [ - { - "type": "configure", - "name": "msvc-debug" - }, - { - "type": "build", - "name": "msvc-debug" - }, - { - "type": "test", - "name": "msvc-debug" - } - ] - }, - { - "name": "msvc-release", - "steps": [ - { - "type": "configure", - "name": "msvc-release" - }, - { - "type": "build", - "name": "msvc-release" - }, - { - "type": "test", - "name": "msvc-release" - } - ] - } - ] -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/LICENSE b/cookiecutter/{{cookiecutter.project_name}}/LICENSE deleted file mode 100644 index f6db814..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/LICENSE +++ /dev/null @@ -1,219 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. diff --git a/cookiecutter/{{cookiecutter.project_name}}/README.md b/cookiecutter/{{cookiecutter.project_name}}/README.md deleted file mode 100644 index 855e22d..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/README.md +++ /dev/null @@ -1,387 +0,0 @@ -# beman.{{cookiecutter.project_name}}: {{cookiecutter.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) [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)]({{cookiecutter.godbolt_link}}) - -`beman.{{cookiecutter.project_name}}` 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. - -**Implements**: `std::identity` proposed in [Standard Library Concepts ({{cookiecutter.paper}})](https://wg21.link/{{cookiecutter.paper}}). - -**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. - -## Usage - -`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`: - -```cpp -#include - -namespace exe = beman::{{cookiecutter.project_name}}; - -// Class with a pair of values. -struct Pair -{ - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream &operator<<(std::ostream &os, const Pair &p) - { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print(const std::string_view rem, R &&range, Projection projection = exe::identity>) -{ - std::cout << rem << '{'; - std::ranges::for_each( - range, - [O = 0](const auto &o) mutable - { std::cout << (O++ ? ", " : "") << o; }, - projection); - std::cout << "}\n"; -}; - -int main() -{ - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - print("\tpairs with beman: ", pairs); - - return 0; -} - -``` - -Full runnable examples can be found in [`examples/`](examples/). - -## Dependencies - -### Build Environment - -This project requires at least the following to build: - -* A C++ compiler that conforms to the C++17 standard or greater -* CMake 3.25 or later -* (Test Only) GoogleTest - -You can disable building tests by setting CMake option -[`BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS`](#beman_{{cookiecutter.project_name}}_build_tests) to `OFF` -when configuring the project. - -Even when tests are being built and run, some of them will not be compiled -unless the provided compiler supports **C++20** ranges. - -> [!TIP] -> -> The logs indicate examples disabled due to lack of compiler support. -> -> For example: -> -> ```txt -> -- Looking for __cpp_lib_ranges -> -- Looking for __cpp_lib_ranges - not found -> CMake Warning at examples/CMakeLists.txt:12 (message): -> Missing range support! Skip: identity_as_default_projection -> -> -> Examples to be built: identity_direct_usage -> ``` - -### Supported Platforms - -This project officially supports: - -* GCC versions 11–15 -* LLVM Clang++ (with libstdc++ or libc++) versions 17–21 -* AppleClang version 17.0.0 (i.e., the [latest version on GitHub-hosted macOS runners](https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md)) -* MSVC version 19.44.35215.0 (i.e., the [latest version on GitHub-hosted Windows runners](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md)) - -> [!NOTE] -> -> Versions outside of this range would likely work as well, -> especially if you're using a version above the given range -> (e.g. HEAD/ nightly). -> These development environments are verified using our CI configuration. - -## Development - -### Develop using GitHub Codespace - -This project supports [GitHub Codespace](https://github.com/features/codespaces) -via [Development Containers](https://containers.dev/), -which allows rapid development and instant hacking in your browser. -We recommend using GitHub codespace to explore this project as it -requires minimal setup. - -Click the following badge to create a codespace: - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/bemanproject/{{cookiecutter.project_name}}) - -For more documentation on GitHub codespaces, please see -[this doc](https://docs.github.com/en/codespaces/). - -> [!NOTE] -> -> The codespace container may take up to 5 minutes to build and spin-up; this is normal. - -### Develop locally on your machines - -
- For Linux - -Beman libraries require [recent versions of CMake](#build-environment), -we recommend downloading CMake directly from [CMake's website](https://cmake.org/download/) -or installing it with the [Kitware apt library](https://apt.kitware.com/). - -A [supported compiler](#supported-platforms) should be available from your package manager. - -
- -
- For MacOS - -Beman libraries require [recent versions of CMake](#build-environment). -Use [`Homebrew`](https://brew.sh/) to install the latest version of CMake. - -```bash -brew install cmake -``` - -A [supported compiler](#supported-platforms) is also available from brew. - -For example, you can install the latest major release of Clang as: - -```bash -brew install llvm -``` - -
- -
- For Windows - -To build Beman libraries, you will need the MSVC compiler. MSVC can be obtained -by installing Visual Studio; the free Visual Studio 2022 Community Edition can -be downloaded from -[Microsoft](https://visualstudio.microsoft.com/vs/community/). - -After Visual Studio has been installed, you can launch "Developer PowerShell for -VS 2022" by typing it into Windows search bar. This shell environment will -provide CMake, Ninja, and MSVC, allowing you to build the library and run the -tests. - -Note that you will need to use FetchContent to build GoogleTest. To do so, -please see the instructions in the "Build GoogleTest dependency from github.com" -dropdown in the [Project specific configure -arguments](#project-specific-configure-arguments) section. - -
- -### Configure and Build the Project Using CMake Presets - -This project recommends using [CMake Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) -to configure, build and test the project. -Appropriate presets for major compilers have been included by default. -You can use `cmake --list-presets` to see all available presets. - -Here is an example to invoke the `gcc-debug` preset. - -```shell -cmake --workflow --preset gcc-debug -``` - -Generally, there are two kinds of presets, `debug` and `release`. - -The `debug` presets are designed to aid development, so it has debugging -instrumentation enabled and many sanitizers enabled. - -> [!NOTE] -> -> The sanitizers that are enabled vary from compiler to compiler. -> See the toolchain files under ([`cmake`](cmake/)) to determine the exact configuration used for each preset. - -The `release` presets are designed for production use, and -consequently have the highest optimization turned on (e.g. `O3`). - -### Configure and Build Manually - -If the presets are not suitable for your use-case, a traditional CMake -invocation will provide more configurability. - -To configure, build and test the project with extra arguments, -you can run this set of commands. - -```bash -cmake \ - -B build \ - -S . \ - -DCMAKE_CXX_STANDARD=20 \ - -DCMAKE_PREFIX_PATH=$PWD/infra/cmake \ - # Your extra arguments here. -cmake --build build -ctest --test-dir build -``` - -> [!IMPORTANT] -> -> Beman projects are -> [passive projects](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md#cmake), -> therefore, -> you will need to specify the C++ version via `CMAKE_CXX_STANDARD` -> when manually configuring the project. - -### Finding and Fetching GTest from GitHub - -If you do not have GoogleTest installed on your development system, you may -optionally configure this project to download a known-compatible release of -GoogleTest from source and build it as well. - -Example commands: - -```shell -cmake -B build -S . \ - -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake \ - -DCMAKE_CXX_STANDARD=20 -cmake --build build --target all -cmake --build build --target test -``` - -The precise version of GoogleTest that will be used is maintained in -`./lockfile.json`. - -### Project specific configure arguments - -Project-specific options are prefixed with `BEMAN_{{cookiecutter.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 -``` - -
- - Details of CMake arguments. - -#### `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS` - -Enable building tests and test infrastructure. Default: ON. -Values: `{ ON, OFF }`. - -You can configure the project to have this option turned off via: - -```bash -cmake -B build -S . -DCMAKE_CXX_STANDARD=20 -DBEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS=OFF -``` - -> [!TIP] -> Because this project requires GoogleTest for running tests, -> disabling `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS` avoids the project from -> cloning GoogleTest from GitHub. - -#### `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES` - -Enable building examples. Default: ON. Values: { ON, OFF }. - - -#### `BEMAN_{{cookiecutter.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. - -
- -## Integrate beman.{{cookiecutter.project_name}} into your project - -To use `beman.{{cookiecutter.project_name}}` in your C++ project, -include an appropriate `beman.{{cookiecutter.project_name}}` header from your source code. - -```c++ -#include -``` - -> [!NOTE] -> -> `beman.{{cookiecutter.project_name}}` headers are to be included with the `beman/{{cookiecutter.project_name}}/` prefix. -> Altering include search paths to spell the include target another way (e.g. -> `#include `) is unsupported. - -The process for incorporating `beman.{{cookiecutter.project_name}}` into your project depends on the -build system being used. Instructions for CMake are provided in following sections. - -### Incorporating `beman.{{cookiecutter.project_name}}` into your project with CMake - -For CMake based projects, -you will need to use the `beman.{{cookiecutter.project_name}}` CMake module -to define the `beman::{{cookiecutter.project_name}}` CMake target: - -```cmake -find_package(beman.{{cookiecutter.project_name}} REQUIRED) -``` - -You will also need to add `beman::{{cookiecutter.project_name}}` to the link libraries of -any libraries or executables that include `beman.{{cookiecutter.project_name}}` headers. - -```cmake -target_link_libraries(yourlib PUBLIC beman::{{cookiecutter.project_name}}) -``` - -### Produce beman.{{cookiecutter.project_name}} static library - -You can include {{cookiecutter.project_name}}'s headers locally -by producing a static `libbeman.{{cookiecutter.project_name}}.a` library. - -```bash -cmake --workflow --preset gcc-release -cmake --install build/gcc-release --prefix /opt/beman -``` - -This will generate the following directory structure at `/opt/beman`. - -```txt -/opt/beman -├── include -│ └── beman -│ └── {{cookiecutter.project_name}} -│ └── identity.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-debug.cmake - │   └── beman.{{cookiecutter.project_name}}-targets.cmake - └── libbeman.{{cookiecutter.project_name}}.a -``` diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt deleted file mode 100644 index 0c1d385..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -set(ALL_EXAMPLES identity_direct_usage) - -# Example `identity_as_default_projection` need ranges support: -include(CheckCXXSymbolExists) -check_cxx_symbol_exists(__cpp_lib_ranges "ranges" HAS_RANGES) - -if(HAS_RANGES) - list(APPEND ALL_EXAMPLES identity_as_default_projection) -else() - message( - WARNING - "Missing range support! Skip: identity_as_default_projection" - ) -endif() - -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) - target_link_libraries( - beman.{{cookiecutter.project_name}}.examples.${example} - PRIVATE beman::{{cookiecutter.project_name}} - ) -endforeach() diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp b/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp deleted file mode 100644 index 08a9fc7..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// 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. -// Requires: range support (C++20) and std::identity support (C++20). -// TODO Darius: Do we need to selectively compile this example? -// Or should we assume that this project is compiled with C++20 support only? - -#include - -#include -#include // std::identity -#include -#include -#include -#include - -namespace exe = beman::{{cookiecutter.project_name}}; - -// Class with a pair of values. -struct Pair { - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream& operator<<(std::ostream& os, const Pair& p) { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print_helper(const std::string_view rem, R&& range, Projection projection) { - std::cout << rem << '{'; - std::ranges::for_each(range, [O = 0](const auto& o) mutable { std::cout << (O++ ? ", " : "") << o; }, projection); - std::cout << "}\n"; -}; - -// Print wrapper with exe::identity. -template // <- Notice the default projection. -void print_beman(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -// Print wrapper with std::identity. -template // <- Notice the default projection. -void print_std(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -int main() { - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - std::cout << "Default projection:\n"; - print_beman("\tpairs with beman: ", pairs); - print_std("\tpairs with std: ", pairs); - - // Print the pairs using a custom projection. - std::cout << "Custom projection:\n"; - print_beman("\tpairs with beman: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - print_std("\tpairs with std: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - - return 0; -} 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 98795c8..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include - -#include - -namespace exe = beman::{{cookiecutter.project_name}}; - -int main() { - std::cout << exe::identity()(2024) << '\n'; - return 0; -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp deleted file mode 100644 index 4aeb595..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_IDENTITY_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_IDENTITY_HPP - -// C++ Standard Library: std::identity equivalent. -// See https://eel.is/c++draft/func.identity: -// -// 22.10.12 Class identity [func.identity] -// -// struct identity { -// template -// constexpr T&& operator()(T&& t) const noexcept; -// -// using is_transparent = unspecified; -// }; -// -// template -// constexpr T&& operator()(T&& t) const noexcept; -// -// Effects: Equivalent to: return std::forward(t); - -#include // std::forward - -namespace beman::{{cookiecutter.project_name}} { - -struct __is_transparent; // not defined - -// A function object that returns its argument unchanged. -struct identity { - // Returns `t`. - template - constexpr T&& operator()(T&& t) const noexcept { - return std::forward(t); - } - - using is_transparent = __is_transparent; -}; - -} // namespace beman::{{cookiecutter.project_name}} - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_IDENTITY_HPP diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule b/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule deleted file mode 100644 index e9e49f5..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule +++ /dev/null @@ -1,3 +0,0 @@ -[beman_submodule] -remote=https://github.com/bemanproject/infra.git -commit_hash=ec701785a8106c2b7088c7928d6fe861e27d67bc diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS deleted file mode 100644 index 4ff90a4..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @ednolan @neatudarius @rishyak @wusatosi @JeffGarland diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-submodule.yml b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-submodule.yml deleted file mode 100644 index 8435086..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-submodule.yml +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: beman-submodule tests - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - -jobs: - beman-submodule-script-ci: - name: beman_module.py ci - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.13 - - - name: Install pytest - run: | - python3 -m pip install pytest - - - name: Run pytest - run: | - cd tools/beman-submodule/ - pytest diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-tidy.yml b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-tidy.yml deleted file mode 100644 index 46221e6..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/beman-tidy.yml +++ /dev/null @@ -1,111 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: beman-tidy tests - -on: - push: - branches: - - main - pull_request: - workflow_call: - workflow_dispatch: - schedule: - - cron: '0 6 * * *' # 09:00AM EEST (@neatudarius' timezone) - -jobs: - run_linter: - runs-on: ubuntu-latest - defaults: - run: - working-directory: tools/beman-tidy - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v5 - - - name: Sync environment - run: | - uv sync - - - name: Run linter - run: | - uv run ruff check --diff - - run_tests: - runs-on: ubuntu-latest - defaults: - run: - working-directory: tools/beman-tidy - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v5 - - - name: Sync environment - run: | - uv sync - - - name: Run tests - run: | - uv run pytest tests/ -v - - build_and_install: - runs-on: ubuntu-latest - defaults: - run: - working-directory: tools/beman-tidy - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v5 - - - name: Sync environment - run: | - uv sync - - - name: Build and install beman-tidy - run: | - uv clean - uv build - python3 -m pip install dist/beman_tidy-0.1.0-py3-none-any.whl --force-reinstall - beman-tidy --help - - run_on_exemplar: - runs-on: ubuntu-latest - defaults: - run: - working-directory: tools/beman-tidy - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v5 - - - name: Sync environment - run: | - uv sync - - - name: Build and install beman-tidy - run: | - uv clean - uv build - python3 -m pip install dist/beman_tidy-0.1.0-py3-none-any.whl --force-reinstall - beman-tidy --help - - - name: Run installed beman-tidy on exemplar repo - run: | - git clone https://github.com/bemanproject/exemplar.git - cd exemplar/ # Testing that beman-tidy can be run from any path, e.g. from the exemplar repo. - beman-tidy --verbose --require-all . - - create-issue-when-fault: - needs: [run_linter, run_tests, build_and_install, run_on_exemplar] - if: failure() && (github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule') - uses: ./.github/workflows/reusable-beman-create-issue-when-fault.yml diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml deleted file mode 100644 index 9646831..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Lint Check (pre-commit) - -on: - # We have to use pull_request_target here as pull_request does not grant - # enough permission for reviewdog - pull_request_target: - push: - branches: - - main - -jobs: - pre-commit-push: - name: Pre-Commit check on Push - runs-on: ubuntu-latest - if: ${{ github.event_name == 'push' }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.13 - - # We wish to run pre-commit on all files instead of the changes - # only made in the push commit. - # - # So linting error persists when there's formatting problem. - - uses: pre-commit/action@v3.0.1 - - pre-commit-pr: - name: Pre-Commit check on PR - runs-on: ubuntu-latest - if: ${{ github.event_name == 'pull_request_target' }} - - permissions: - contents: read - checks: write - issues: write - pull-requests: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # pull_request_target checkout the base of the repo - # We need to checkout the actual pr to lint the changes. - - name: Checkout pr - run: gh pr checkout ${{ github.event.number }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.13 - - # we only lint on the changed file in PR. - - name: Get Changed Files - id: changed-files - uses: tj-actions/changed-files@v45 - - # See: - # https://github.com/tj-actions/changed-files?tab=readme-ov-file#using-local-git-directory- - - uses: pre-commit/action@v3.0.1 - id: run-pre-commit - with: - extra_args: --files ${{ steps.changed-files.outputs.all_changed_files }} - - # Review dog posts the suggested change from pre-commit to the pr. - - name: suggester / pre-commit - uses: reviewdog/action-suggester@v1 - if: ${{ failure() && steps.run-pre-commit.conclusion == 'failure' }} - with: - tool_name: pre-commit - level: warning - reviewdog_flags: "-fail-level=error" diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml deleted file mode 100644 index 024a51f..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: 'Beman issue creation workflow' -on: - workflow_call: - workflow_dispatch: -jobs: - create-issue: - runs-on: ubuntu-latest - steps: - # See https://github.com/cli/cli/issues/5075 - - uses: actions/checkout@v4 - - name: Create issue - run: | - issue_num=$(gh issue list -s open -S "[SCHEDULED-BUILD] infra repo CI job failure" -L 1 --json number | jq 'if length == 0 then -1 else .[0].number end') - body="**CI job failure Report** - - **Time of Failure**: $(date -u '+%B %d, %Y, %H:%M %Z') - - **Commit**: [${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) - - **Action Run**: [View logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) - The scheduled job triggered by cron has failed. - Please investigate the logs and recent changes associated with this commit or rerun the workflow if you believe this is an error." - if [[ $issue_num -eq -1 ]]; then - gh issue create --repo ${{ github.repository }} --title "[SCHEDULED-BUILD] infra repo CI job failure" --body "$body" --assignee ${{ github.actor }} - else - gh issue comment --repo ${{ github.repository }} $issue_num --body "$body" - fi - env: - GH_TOKEN: ${{ github.token }} diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore b/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore deleted file mode 100644 index b7cdbb5..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore +++ /dev/null @@ -1,59 +0,0 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Python -__pycache__/ -.pytest_cache/ -*.pyc -*.pyo -*.pyd -*.pyw -*.pyz -*.pywz -*.pyzw -*.pyzwz -*.delete_me - -# MAC OS -*.DS_Store - -# Editor files -.vscode/ -.idea/ - -# Build directories -infra.egg-info/ -beman_tidy.egg-info/ -*.egg-info/ -build/ -dist/ diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml b/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml deleted file mode 100644 index e806e59..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml +++ /dev/null @@ -1,32 +0,0 @@ -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files - - - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 - hooks: - - id: codespell - - # CMake linting and formatting - - repo: https://github.com/BlankSpruce/gersemi - rev: 0.22.3 - hooks: - - id: gersemi - name: CMake linting - exclude: ^.*/tests/.*/data/ # Exclude test data directories - - # Python linting and formatting - # config file: ruff.toml (not currently present but add if needed) - # https://docs.astral.sh/ruff/configuration/ - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.13.2 - hooks: - - id: ruff-check - files: ^tools/beman-tidy/ - - id: ruff-format - files: ^tools/beman-tidy/ diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-hooks.yaml b/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-hooks.yaml deleted file mode 100644 index d327587..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-hooks.yaml +++ /dev/null @@ -1,7 +0,0 @@ -- id: beman-tidy - name: "beman-tidy: bemanification your repo" - entry: ./tools/beman-tidy/beman-tidy - language: script - pass_filenames: false - always_run: true - args: [".", "--verbose"] diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE b/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE deleted file mode 100644 index f6db814..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE +++ /dev/null @@ -1,219 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/README.md b/cookiecutter/{{cookiecutter.project_name}}/infra/README.md deleted file mode 100644 index c273968..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Beman Project Infrastructure Repository - - - -[![beman-tidy tests](https://github.com/bemanproject/infra/actions/workflows/beman-tidy.yml/badge.svg)](https://github.com/bemanproject/infra/actions/workflows/beman-tidy.yml) - -This repository contains the infrastructure for The Beman Project. This is NOT a library repository, -so it does not respect the usual structure of a Beman library repository nor The Beman Standard! - -## Description - -* `cmake/`: CMake modules and toolchain files used by Beman libraries. -* `containers/`: Containers used for CI builds and tests in the Beman org. -* `tools/`: Tools used to manage the infrastructure and the codebase (e.g., linting, formatting, etc.). - -## Usage - -This repository is intended to be used as a beman-submodule in other Beman repositories. See -[the Beman Submodule documentation](./tools/beman-submodule/README.md) for details. - - -### CMake Modules - - -#### `beman_install_library` - -The CMake modules in this repository are intended to be used by Beman libraries. Use the -`beman_add_install_library_config()` function to install your library, along with header -files, any metadata files, and a CMake config file for `find_package()` support. - -```cmake -add_library(beman.something) -add_library(beman::something ALIAS beman.something) - -# ... configure your target as needed ... - -find_package(beman-install-library REQUIRED) -beman_install_library(beman.something) -``` - -Note that the target must be created before calling `beman_install_library()`. The module -also assumes that the target is named using the `beman.something` convention, and it -uses that assumption to derive the names to match other Beman standards and conventions. -If your target does not follow that convention, raise an issue or pull request to add -more configurability to the module. - -The module will configure the target to install: - -* The library target itself -* Any public headers associated with the target -* CMake files for `find_package(beman.something)` support - -Some options for the project and target will also be supported: - -* `BEMAN_INSTALL_CONFIG_FILE_PACKAGES` - a list of package names (e.g., `beman.something`) for which to install the config file - (default: all packages) -* `_INSTALL_CONFIG_FILE_PACKAGE` - a per-project option to enable/disable config file installation (default: `ON` if the project is top-level, `OFF` otherwise). For instance for `beman.something`, the option would be `BEMAN_SOMETHING_INSTALL_CONFIG_FILE_PACKAGE`. diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake deleted file mode 100644 index 70ef548..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for apple clang family of compiler. -# Note this is different from LLVM toolchain. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures clang and clang++ to use all available non-conflicting -# sanitizers. Note that apple clang does not support leak sanitizer. -# - TSan: configures clang and clang++ to enable the use of thread sanitizer. - -include_guard(GLOBAL) - -# Prevent PATH collision with an LLVM clang installation by using the system -# compiler shims -set(CMAKE_C_COMPILER cc) -set(CMAKE_CXX_COMPILER c++) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - set(SANITIZER_FLAGS - "-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" - ) -elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") - set(SANITIZER_FLAGS "-fsanitize=thread") -endif() - -set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library-config.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library-config.cmake deleted file mode 100644 index e7fd0ad..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library-config.cmake +++ /dev/null @@ -1,169 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -include_guard(GLOBAL) - -# This file defines the function `beman_install_library` which is used to -# install a library target and its headers, along with optional CMake -# configuration files. -# -# The function is designed to be reusable across different Beman libraries. - -function(beman_install_library name) - # Usage - # ----- - # - # beman_install_library(NAME) - # - # Brief - # ----- - # - # This function installs the specified library target and its headers. - # It also handles the installation of the CMake configuration files if needed. - # - # CMake variables - # --------------- - # - # Note that configuration of the installation is generally controlled by CMake - # cache variables so that they can be controlled by the user or tool running the - # `cmake` command. Neither `CMakeLists.txt` nor `*.cmake` files should set these - # variables directly. - # - # - BEMAN_INSTALL_CONFIG_FILE_PACKAGES: - # List of packages that require config file installation. - # If the package name is in this list, it will install the config file. - # - # - _INSTALL_CONFIG_FILE_PACKAGE: - # Boolean to control config file installation for the specific library. - # The prefix `` is the uppercased name of the library with dots - # replaced by underscores. - # - if(NOT TARGET "${name}") - message(FATAL_ERROR "Target '${name}' does not exist.") - endif() - - if(NOT ARGN STREQUAL "") - message( - FATAL_ERROR - "beman_install_library does not accept extra arguments: ${ARGN}" - ) - endif() - - # Given foo.bar, the component name is bar - string(REPLACE "." ";" name_parts "${name}") - # fail if the name doesn't look like foo.bar - list(LENGTH name_parts name_parts_length) - if(NOT name_parts_length EQUAL 2) - message( - FATAL_ERROR - "beman_install_library expects a name of the form 'beman.', got '${name}'" - ) - endif() - - set(target_name "${name}") - set(install_component_name "${name}") - set(export_name "${name}") - set(package_name "${name}") - list(GET name_parts -1 component_name) - - install( - TARGETS "${target_name}" - COMPONENT "${install_component_name}" - EXPORT "${export_name}" - FILE_SET HEADERS - ) - - set_target_properties( - "${target_name}" - PROPERTIES EXPORT_NAME "${component_name}" - ) - - include(GNUInstallDirs) - - # Determine the prefix for project-specific variables - string(TOUPPER "${name}" project_prefix) - string(REPLACE "." "_" project_prefix "${project_prefix}") - - option( - ${project_prefix}_INSTALL_CONFIG_FILE_PACKAGE - "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." - ${PROJECT_IS_TOP_LEVEL} - ) - - # By default, install the config package - set(install_config_package ON) - - # Turn OFF installation of config package by default if, - # in order of precedence: - # 1. The specific package variable is set to OFF - # 2. The package name is not in the list of packages to install config files - if(DEFINED BEMAN_INSTALL_CONFIG_FILE_PACKAGES) - if( - NOT "${install_component_name}" - IN_LIST - BEMAN_INSTALL_CONFIG_FILE_PACKAGES - ) - set(install_config_package OFF) - endif() - endif() - if(DEFINED ${project_prefix}_INSTALL_CONFIG_FILE_PACKAGE) - set(install_config_package - ${${project_prefix}_INSTALL_CONFIG_FILE_PACKAGE} - ) - endif() - - if(install_config_package) - message( - DEBUG - "beman-install-library: Installing a config package for '${name}'" - ) - - include(CMakePackageConfigHelpers) - - find_file( - config_file_template - NAMES "${package_name}-config.cmake.in" - PATHS "${CMAKE_CURRENT_SOURCE_DIR}" - NO_DEFAULT_PATH - NO_CACHE - REQUIRED - ) - set(config_package_file - "${CMAKE_CURRENT_BINARY_DIR}/${package_name}-config.cmake" - ) - set(package_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${package_name}") - configure_package_config_file( - "${config_file_template}" - "${config_package_file}" - INSTALL_DESTINATION "${package_install_dir}" - PATH_VARS PROJECT_NAME PROJECT_VERSION - ) - - set(config_version_file - "${CMAKE_CURRENT_BINARY_DIR}/${package_name}-config-version.cmake" - ) - write_basic_package_version_file( - "${config_version_file}" - VERSION "${PROJECT_VERSION}" - COMPATIBILITY ExactVersion - ) - - install( - FILES "${config_package_file}" "${config_version_file}" - DESTINATION "${package_install_dir}" - COMPONENT "${install_component_name}" - ) - - set(config_targets_file "${package_name}-targets.cmake") - install( - EXPORT "${export_name}" - DESTINATION "${package_install_dir}" - NAMESPACE beman:: - FILE "${config_targets_file}" - COMPONENT "${install_component_name}" - ) - else() - message( - DEBUG - "beman-install-library: Not installing a config package for '${name}'" - ) - endif() -endfunction() diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake deleted file mode 100644 index d3b9f92..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for GNU family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures gcc and g++ to use all available non-conflicting -# sanitizers. -# - TSan: configures gcc and g++ to enable the use of thread sanitizer - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER gcc) -set(CMAKE_CXX_COMPILER g++) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - set(SANITIZER_FLAGS - "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fsanitize-undefined-trap-on-error" - ) -elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") - set(SANITIZER_FLAGS "-fsanitize=thread") -endif() - -set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake deleted file mode 100644 index 76264c6..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: BSL-1.0 - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for LLVM family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures clang and clang++ to use all available non-conflicting -# sanitizers. -# - TSan: configures clang and clang++ to enable the use of thread sanitizer. - -include(${CMAKE_CURRENT_LIST_DIR}/llvm-toolchain.cmake) - -if(NOT CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+") - string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++") -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake deleted file mode 100644 index f1623b7..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for LLVM family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures clang and clang++ to use all available non-conflicting -# sanitizers. -# - TSan: configures clang and clang++ to enable the use of thread sanitizer. - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - set(SANITIZER_FLAGS - "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fsanitize-undefined-trap-on-error" - ) -elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") - set(SANITIZER_FLAGS "-fsanitize=thread") -endif() - -set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake deleted file mode 100644 index bdc24de..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for MSVC family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures cl to use all available non-conflicting sanitizers. -# -# Note that in other toolchain files, TSan is also a possible value for -# BEMAN_BUILDSYS_SANITIZER, however, MSVC does not support thread sanitizer, -# thus this value is omitted. - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER cl) -set(CMAKE_CXX_COMPILER cl) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - # /Zi flag (add debug symbol) is needed when using address sanitizer - # See C5072: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c5072 - set(SANITIZER_FLAGS "/fsanitize=address /Zi") -endif() - -set(CMAKE_CXX_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") -set(CMAKE_C_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "/EHsc /permissive- /O2 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake deleted file mode 100644 index 4ed4839..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake +++ /dev/null @@ -1,187 +0,0 @@ -cmake_minimum_required(VERSION 3.24) - -include(FetchContent) - -if(NOT BEMAN_EXEMPLAR_LOCKFILE) - set(BEMAN_EXEMPLAR_LOCKFILE - "lockfile.json" - CACHE FILEPATH - "Path to the dependency lockfile for the Beman Exemplar." - ) -endif() - -set(BemanExemplar_projectDir "${CMAKE_CURRENT_LIST_DIR}/../..") -message(TRACE "BemanExemplar_projectDir=\"${BemanExemplar_projectDir}\"") - -message(TRACE "BEMAN_EXEMPLAR_LOCKFILE=\"${BEMAN_EXEMPLAR_LOCKFILE}\"") -file( - REAL_PATH - "${BEMAN_EXEMPLAR_LOCKFILE}" - BemanExemplar_lockfile - BASE_DIRECTORY "${BemanExemplar_projectDir}" - EXPAND_TILDE -) -message(DEBUG "Using lockfile: \"${BemanExemplar_lockfile}\"") - -# Force CMake to reconfigure the project if the lockfile changes -set_property( - DIRECTORY "${BemanExemplar_projectDir}" - APPEND - PROPERTY CMAKE_CONFIGURE_DEPENDS "${BemanExemplar_lockfile}" -) - -# For more on the protocol for this function, see: -# https://cmake.org/cmake/help/latest/command/cmake_language.html#provider-commands -function(BemanExemplar_provideDependency method package_name) - # Read the lockfile - file(READ "${BemanExemplar_lockfile}" BemanExemplar_rootObj) - - # Get the "dependencies" field and store it in BemanExemplar_dependenciesObj - string( - JSON - BemanExemplar_dependenciesObj - ERROR_VARIABLE BemanExemplar_error - GET "${BemanExemplar_rootObj}" - "dependencies" - ) - if(BemanExemplar_error) - message(FATAL_ERROR "${BemanExemplar_lockfile}: ${BemanExemplar_error}") - endif() - - # Get the length of the libraries array and store it in BemanExemplar_dependenciesObj - string( - JSON - BemanExemplar_numDependencies - ERROR_VARIABLE BemanExemplar_error - LENGTH "${BemanExemplar_dependenciesObj}" - ) - if(BemanExemplar_error) - message(FATAL_ERROR "${BemanExemplar_lockfile}: ${BemanExemplar_error}") - endif() - - if(BemanExemplar_numDependencies EQUAL 0) - return() - endif() - - # Loop over each dependency object - math(EXPR BemanExemplar_maxIndex "${BemanExemplar_numDependencies} - 1") - foreach(BemanExemplar_index RANGE "${BemanExemplar_maxIndex}") - set(BemanExemplar_errorPrefix - "${BemanExemplar_lockfile}, dependency ${BemanExemplar_index}" - ) - - # Get the dependency object at BemanExemplar_index - # and store it in BemanExemplar_depObj - string( - JSON - BemanExemplar_depObj - ERROR_VARIABLE BemanExemplar_error - GET "${BemanExemplar_dependenciesObj}" - "${BemanExemplar_index}" - ) - if(BemanExemplar_error) - message( - FATAL_ERROR - "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" - ) - endif() - - # Get the "name" field and store it in BemanExemplar_name - string( - JSON - BemanExemplar_name - ERROR_VARIABLE BemanExemplar_error - GET "${BemanExemplar_depObj}" - "name" - ) - if(BemanExemplar_error) - message( - FATAL_ERROR - "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" - ) - endif() - - # Get the "package_name" field and store it in BemanExemplar_pkgName - string( - JSON - BemanExemplar_pkgName - ERROR_VARIABLE BemanExemplar_error - GET "${BemanExemplar_depObj}" - "package_name" - ) - if(BemanExemplar_error) - message( - FATAL_ERROR - "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" - ) - endif() - - # Get the "git_repository" field and store it in BemanExemplar_repo - string( - JSON - BemanExemplar_repo - ERROR_VARIABLE BemanExemplar_error - GET "${BemanExemplar_depObj}" - "git_repository" - ) - if(BemanExemplar_error) - message( - FATAL_ERROR - "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" - ) - endif() - - # Get the "git_tag" field and store it in BemanExemplar_tag - string( - JSON - BemanExemplar_tag - ERROR_VARIABLE BemanExemplar_error - GET "${BemanExemplar_depObj}" - "git_tag" - ) - if(BemanExemplar_error) - message( - FATAL_ERROR - "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" - ) - endif() - - if(method STREQUAL "FIND_PACKAGE") - if(package_name STREQUAL BemanExemplar_pkgName) - string( - APPEND - BemanExemplar_debug - "Redirecting find_package calls for ${BemanExemplar_pkgName} " - "to FetchContent logic.\n" - ) - string( - APPEND - BemanExemplar_debug - "Fetching ${BemanExemplar_repo} at " - "${BemanExemplar_tag} according to ${BemanExemplar_lockfile}." - ) - message(DEBUG "${BemanExemplar_debug}") - FetchContent_Declare( - "${BemanExemplar_name}" - GIT_REPOSITORY "${BemanExemplar_repo}" - GIT_TAG "${BemanExemplar_tag}" - EXCLUDE_FROM_ALL - ) - set(INSTALL_GTEST OFF) # Disable GoogleTest installation - FetchContent_MakeAvailable("${BemanExemplar_name}") - - # Important! _FOUND tells CMake that `find_package` is - # not needed for this package anymore - set("${BemanExemplar_pkgName}_FOUND" TRUE PARENT_SCOPE) - endif() - endif() - endforeach() -endfunction() - -cmake_language( - SET_DEPENDENCY_PROVIDER BemanExemplar_provideDependency - SUPPORTED_METHODS FIND_PACKAGE -) - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/README.md b/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/README.md deleted file mode 100644 index 36883ad..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# beman-submodule - - - -## What is this script? - -`beman-submodule` provides some of the features of `git submodule`, adding child git -repositories to a parent git repository, but unlike with `git submodule`, the entire child -repo is directly checked in, so only maintainers, not users, need to run this script. The -command line interface mimics `git submodule`'s. - -## How do I add a beman submodule to my repository? - -The first beman submodule you should add is this repository, `infra/`, which you can -bootstrap by running: - - -```sh -curl -s https://raw.githubusercontent.com/bemanproject/infra/refs/heads/main/tools/beman-submodule/beman-submodule | python3 - add https://github.com/bemanproject/infra.git -``` - -Once that's added, you can run the script from `infra/tools/beman-submodule/beman-submodule`. - -## How do I update a beman submodule to the latest trunk? - -You can run `beman-submodule update --remote` to update all beman submodule to latest -trunk, or e.g. `beman-submodule update --remote infra` to update only a specific one. - -## How does it work under the hood? - -Along with the files from the child repository, it creates a dotfile called -`.beman_submodule`, which looks like this: - -```ini -[beman_submodule] -remote=https://github.com/bemanproject/infra.git -commit_hash=9b88395a86c4290794e503e94d8213b6c442ae77 -``` - -## How do I update a beman submodule to a specific commit or change the remote URL? - -You can edit the corresponding lines in the `.beman_submodule` file and run -`beman-submodule update` to update the state of the beman submodule to the new -`.beman_submodule` settings. - -## How can I make CI ensure that my beman submodules are in a valid state? - -Add this job to your CI workflow: - -```yaml - beman-submodule-test: - runs-on: ubuntu-latest - name: "Check beman submodules for consistency" - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: beman submodule consistency check - run: | - (set -o pipefail; ./infra/tools/beman-submodule/beman-submodule status | grep -qvF '+') -``` - -This will fail if the contents of any beman submodule don't match what's specified in the -`.beman_submodule` file. diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/beman-submodule b/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/beman-submodule deleted file mode 100755 index 66cb96e..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/beman-submodule +++ /dev/null @@ -1,260 +0,0 @@ -#!/usr/bin/env python3 - -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -import argparse -import configparser -import filecmp -import glob -import os -import shutil -import subprocess -import sys -import tempfile -from pathlib import Path - - -def directory_compare( - reference: str | Path, actual: str | Path, ignore, allow_untracked_files: bool): - reference, actual = Path(reference), Path(actual) - - compared = filecmp.dircmp(reference, actual, ignore=ignore) - if (compared.left_only - or (compared.right_only and not allow_untracked_files) - or compared.diff_files): - return False - for common_dir in compared.common_dirs: - path1 = reference / common_dir - path2 = actual / common_dir - if not directory_compare(path1, path2, ignore, allow_untracked_files): - return False - return True - -class BemanSubmodule: - def __init__( - self, dirpath: str | Path, remote: str, commit_hash: str, - allow_untracked_files: bool): - self.dirpath = Path(dirpath) - self.remote = remote - self.commit_hash = commit_hash - self.allow_untracked_files = allow_untracked_files - -def parse_beman_submodule_file(path): - config = configparser.ConfigParser() - read_result = config.read(path) - def fail(): - raise Exception(f'Failed to parse {path} as a .beman_submodule file') - if not read_result: - fail() - if not 'beman_submodule' in config: - fail() - if not 'remote' in config['beman_submodule']: - fail() - if not 'commit_hash' in config['beman_submodule']: - fail() - allow_untracked_files = config.getboolean( - 'beman_submodule', 'allow_untracked_files', fallback=False) - return BemanSubmodule( - Path(path).resolve().parent, - config['beman_submodule']['remote'], - config['beman_submodule']['commit_hash'], - allow_untracked_files) - -def get_beman_submodule(path: str | Path): - beman_submodule_filepath = Path(path) / '.beman_submodule' - - if beman_submodule_filepath.is_file(): - return parse_beman_submodule_file(beman_submodule_filepath) - else: - return None - -def find_beman_submodules_in(path): - path = Path(path) - assert path.is_dir() - - result = [] - for dirpath, _, filenames in path.walk(): - if '.beman_submodule' in filenames: - result.append(parse_beman_submodule_file(dirpath / '.beman_submodule')) - return sorted(result, key=lambda module: module.dirpath) - -def cwd_git_repository_path(): - process = subprocess.run( - ['git', 'rev-parse', '--show-toplevel'], capture_output=True, text=True, - check=False) - if process.returncode == 0: - return process.stdout.strip() - elif "fatal: not a git repository" in process.stderr: - return None - else: - raise Exception("git rev-parse --show-toplevel failed") - -def clone_beman_submodule_into_tmpdir(beman_submodule, remote): - tmpdir = tempfile.TemporaryDirectory() - subprocess.run( - ['git', 'clone', beman_submodule.remote, tmpdir.name], capture_output=True, - check=True) - if not remote: - subprocess.run( - ['git', '-C', tmpdir.name, 'reset', '--hard', beman_submodule.commit_hash], - capture_output=True, check=True) - return tmpdir - -def get_paths(beman_submodule): - tmpdir = clone_beman_submodule_into_tmpdir(beman_submodule, False) - paths = set(glob.glob('*', root_dir=Path(tmpdir.name), include_hidden=True)) - paths.remove('.git') - return paths - -def beman_submodule_status(beman_submodule): - tmpdir = clone_beman_submodule_into_tmpdir(beman_submodule, False) - if directory_compare( - tmpdir.name, beman_submodule.dirpath, ['.beman_submodule', '.git'], - beman_submodule.allow_untracked_files): - status_character=' ' - else: - status_character='+' - parent_repo_path = cwd_git_repository_path() - if not parent_repo_path: - raise Exception('this is not a git repository') - relpath = Path(beman_submodule.dirpath).relative_to(Path(parent_repo_path)) - return status_character + ' ' + beman_submodule.commit_hash + ' ' + str(relpath) - -def beman_submodule_update(beman_submodule, remote): - tmpdir = clone_beman_submodule_into_tmpdir(beman_submodule, remote) - tmp_path = Path(tmpdir.name) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmp_path) - - if beman_submodule.allow_untracked_files: - for path in get_paths(beman_submodule): - path2 = Path(beman_submodule.dirpath) / path - if Path(path2).is_dir(): - shutil.rmtree(path2) - elif Path(path2).is_file(): - os.remove(path2) - else: - shutil.rmtree(beman_submodule.dirpath) - - submodule_path = tmp_path / '.beman_submodule' - with open(submodule_path, 'w') as f: - f.write('[beman_submodule]\n') - f.write(f'remote={beman_submodule.remote}\n') - f.write(f'commit_hash={sha_process.stdout.strip()}\n') - if beman_submodule.allow_untracked_files: - f.write(f'allow_untracked_files=True\n') - shutil.rmtree(tmp_path / '.git') - shutil.copytree(tmp_path, beman_submodule.dirpath, dirs_exist_ok=True) - -def update_command(remote, path): - if not path: - parent_repo_path = cwd_git_repository_path() - if not parent_repo_path: - raise Exception('this is not a git repository') - beman_submodules = find_beman_submodules_in(parent_repo_path) - else: - beman_submodule = get_beman_submodule(path) - if not beman_submodule: - raise Exception(f'{path} is not a beman_submodule') - beman_submodules = [beman_submodule] - for beman_submodule in beman_submodules: - beman_submodule_update(beman_submodule, remote) - -def add_command(repository, path, allow_untracked_files): - tmpdir = tempfile.TemporaryDirectory() - subprocess.run( - ['git', 'clone', repository], capture_output=True, check=True, cwd=tmpdir.name) - repository_name = os.listdir(tmpdir.name)[0] - if not path: - path = Path(repository_name) - else: - path = Path(path) - if not allow_untracked_files and path.exists(): - raise Exception(f'{path} exists') - path.mkdir(exist_ok=allow_untracked_files) - tmpdir_repo = Path(tmpdir.name) / repository_name - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir_repo) - with open(tmpdir_repo / '.beman_submodule', 'w') as f: - f.write('[beman_submodule]\n') - f.write(f'remote={repository}\n') - f.write(f'commit_hash={sha_process.stdout.strip()}\n') - if allow_untracked_files: - f.write(f'allow_untracked_files=True\n') - shutil.rmtree(tmpdir_repo /'.git') - shutil.copytree(tmpdir_repo, path, dirs_exist_ok=True) - -def status_command(paths): - if not paths: - parent_repo_path = cwd_git_repository_path() - if not parent_repo_path: - raise Exception('this is not a git repository') - beman_submodules = find_beman_submodules_in(parent_repo_path) - else: - beman_submodules = [] - for path in paths: - beman_submodule = get_beman_submodule(path) - if not beman_submodule: - raise Exception(f'{path} is not a beman_submodule') - beman_submodules.append(beman_submodule) - for beman_submodule in beman_submodules: - print(beman_submodule_status(beman_submodule)) - -def get_parser(): - parser = argparse.ArgumentParser(description='Beman pseudo-submodule tool') - subparsers = parser.add_subparsers(dest='command', help='available commands') - parser_update = subparsers.add_parser('update', help='update beman_submodules') - parser_update.add_argument( - '--remote', action='store_true', - help='update a beman_submodule to its latest from upstream') - parser_update.add_argument( - 'beman_submodule_path', nargs='?', - help='relative path to the beman_submodule to update') - parser_add = subparsers.add_parser('add', help='add a new beman_submodule') - parser_add.add_argument('repository', help='git repository to add') - parser_add.add_argument( - 'path', nargs='?', help='path where the repository will be added') - parser_add.add_argument( - '--allow-untracked-files', action='store_true', - help='the beman_submodule will not occupy the subdirectory exclusively') - parser_status = subparsers.add_parser( - 'status', help='show the status of beman_submodules') - parser_status.add_argument('paths', nargs='*') - return parser - -def parse_args(args): - return get_parser().parse_args(args); - -def usage(): - return get_parser().format_help() - -def run_command(args): - if args.command == 'update': - update_command(args.remote, args.beman_submodule_path) - elif args.command == 'add': - add_command(args.repository, args.path, args.allow_untracked_files) - elif args.command == 'status': - status_command(args.paths) - else: - raise Exception(usage()) - -def check_for_git(path): - env = os.environ.copy() - if path is not None: - env["PATH"] = path - return shutil.which("git", path=env.get("PATH")) is not None - -def main(): - try: - if not check_for_git(None): - raise Exception('git not found in PATH') - args = parse_args(sys.argv[1:]) - run_command(args) - except Exception as e: - print("Error:", e, file=sys.stderr) - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/test/test_beman_submodule.py b/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/test/test_beman_submodule.py deleted file mode 100644 index 600fc07..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/tools/beman-submodule/test/test_beman_submodule.py +++ /dev/null @@ -1,539 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -import glob -import os -import pytest -import shutil -import stat -import subprocess -import tempfile -from pathlib import Path - -# https://stackoverflow.com/a/19011259 -import types -import importlib.machinery -loader = importlib.machinery.SourceFileLoader( - 'beman_submodule', - str(Path(__file__).parent.resolve().parent / 'beman-submodule')) -beman_submodule = types.ModuleType(loader.name) -loader.exec_module(beman_submodule) - -def create_test_git_repository(): - tmpdir = tempfile.TemporaryDirectory() - tmp_path = Path(tmpdir.name) - - subprocess.run(['git', 'init'], check=True, cwd=tmpdir.name, capture_output=True) - def make_commit(a_txt_contents): - with open(tmp_path / 'a.txt', 'w') as f: - f.write(a_txt_contents) - subprocess.run( - ['git', 'add', 'a.txt'], check=True, cwd=tmpdir.name, capture_output=True) - subprocess.run( - ['git', '-c', 'user.name=test', '-c', 'user.email=test@example.com', 'commit', - '--author="test "', '-m', 'test'], - check=True, cwd=tmpdir.name, capture_output=True) - make_commit('A') - make_commit('a') - return tmpdir - -def create_test_git_repository2(): - tmpdir = tempfile.TemporaryDirectory() - tmp_path = Path(tmpdir.name) - - subprocess.run(['git', 'init'], check=True, cwd=tmpdir.name, capture_output=True) - with open(tmp_path / 'a.txt', 'w') as f: - f.write('a') - subprocess.run( - ['git', 'add', 'a.txt'], check=True, cwd=tmpdir.name, capture_output=True) - subprocess.run( - ['git', '-c', 'user.name=test', '-c', 'user.email=test@example.com', 'commit', - '--author="test "', '-m', 'test'], - check=True, cwd=tmpdir.name, capture_output=True) - os.remove(tmp_path / 'a.txt') - subprocess.run( - ['git', 'rm', 'a.txt'], check=True, cwd=tmpdir.name, capture_output=True) - with open(tmp_path / 'b.txt', 'w') as f: - f.write('b') - subprocess.run( - ['git', 'add', 'b.txt'], check=True, cwd=tmpdir.name, capture_output=True) - subprocess.run( - ['git', '-c', 'user.name=test', '-c', 'user.email=test@example.com', 'commit', - '--author="test "', '-m', 'test'], - check=True, cwd=tmpdir.name, capture_output=True) - return tmpdir - -def test_directory_compare(): - def create_dir_structure(dir_path: Path): - bar_path = dir_path / 'bar' - os.makedirs(bar_path) - - with open(dir_path / 'foo.txt', 'w') as f: - f.write('foo') - with open(bar_path / 'baz.txt', 'w') as f: - f.write('baz') - - with tempfile.TemporaryDirectory() as dir_a, \ - tempfile.TemporaryDirectory() as dir_b: - path_a = Path(dir_a) - path_b = Path(dir_b) - - create_dir_structure(path_a) - create_dir_structure(path_b) - - assert beman_submodule.directory_compare(dir_a, dir_b, [], False) - - with open(path_a / 'bar' / 'quux.txt', 'w') as f: - f.write('quux') - - assert not beman_submodule.directory_compare(path_a, path_b, [], False) - assert beman_submodule.directory_compare(path_a, path_b, ['quux.txt'], False) - -def test_directory_compare_untracked_files(): - def create_dir_structure(dir_path: Path): - bar_path = dir_path / 'bar' - os.makedirs(bar_path) - - with open(dir_path / 'foo.txt', 'w') as f: - f.write('foo') - with open(bar_path / 'baz.txt', 'w') as f: - f.write('baz') - - with tempfile.TemporaryDirectory() as reference, \ - tempfile.TemporaryDirectory() as actual: - path_a = Path(reference) - path_b = Path(actual) - - create_dir_structure(path_a) - create_dir_structure(path_b) - (path_b / 'c.txt').touch() - - assert beman_submodule.directory_compare(reference, actual, [], True) - - with open(path_a / 'bar' / 'quux.txt', 'w') as f: - f.write('quux') - - assert not beman_submodule.directory_compare(path_a, path_b, [], True) - assert beman_submodule.directory_compare(path_a, path_b, ['quux.txt'], True) - -def test_parse_beman_submodule_file(): - def valid_file(): - tmpfile = tempfile.NamedTemporaryFile() - tmpfile.write('[beman_submodule]\n'.encode('utf-8')) - tmpfile.write( - 'remote=git@github.com:bemanproject/infra.git\n'.encode('utf-8')) - tmpfile.write( - 'commit_hash=9b88395a86c4290794e503e94d8213b6c442ae77\n'.encode('utf-8')) - tmpfile.flush() - module = beman_submodule.parse_beman_submodule_file(tmpfile.name) - assert module.dirpath == Path(tmpfile.name).resolve().parent - assert module.remote == 'git@github.com:bemanproject/infra.git' - assert module.commit_hash == '9b88395a86c4290794e503e94d8213b6c442ae77' - valid_file() - def invalid_file_missing_remote(): - threw = False - try: - tmpfile = tempfile.NamedTemporaryFile() - tmpfile.write('[beman_submodule]\n'.encode('utf-8')) - tmpfile.write( - 'commit_hash=9b88395a86c4290794e503e94d8213b6c442ae77\n'.encode('utf-8')) - tmpfile.flush() - beman_submodule.parse_beman_submodule_file(tmpfile.name) - except: - threw = True - assert threw - invalid_file_missing_remote() - def invalid_file_missing_commit_hash(): - threw = False - try: - tmpfile = tempfile.NamedTemporaryFile() - tmpfile.write('[beman_submodule]\n'.encode('utf-8')) - tmpfile.write( - 'remote=git@github.com:bemanproject/infra.git\n'.encode('utf-8')) - tmpfile.flush() - beman_submodule.parse_beman_submodule_file(tmpfile.name) - except: - threw = True - assert threw - invalid_file_missing_commit_hash() - def invalid_file_wrong_section(): - threw = False - try: - tmpfile = tempfile.NamedTemporaryFile() - tmpfile.write('[invalid]\n'.encode('utf-8')) - tmpfile.write( - 'remote=git@github.com:bemanproject/infra.git\n'.encode('utf-8')) - tmpfile.write( - 'commit_hash=9b88395a86c4290794e503e94d8213b6c442ae77\n'.encode('utf-8')) - tmpfile.flush() - beman_submodule.parse_beman_submodule_file(tmpfile.name) - except: - threw = True - assert threw - invalid_file_wrong_section() - -def test_get_beman_submodule(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - assert beman_submodule.get_beman_submodule('foo') - os.remove('foo/.beman_submodule') - assert not beman_submodule.get_beman_submodule('foo') - os.chdir(original_cwd) - -def test_find_beman_submodules_in(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - beman_submodule.add_command(tmpdir.name, 'bar', False) - beman_submodules = beman_submodule.find_beman_submodules_in(tmpdir2.name) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - sha = sha_process.stdout.strip() - assert beman_submodules[0].dirpath == Path(tmpdir2.name) / 'bar' - assert beman_submodules[0].remote == tmpdir.name - assert beman_submodules[0].commit_hash == sha - assert beman_submodules[1].dirpath == Path(tmpdir2.name) / 'foo' - assert beman_submodules[1].remote == tmpdir.name - assert beman_submodules[1].commit_hash == sha - os.chdir(original_cwd) - -def test_cwd_git_repository_path(): - original_cwd = Path.cwd() - tmpdir = tempfile.TemporaryDirectory() - os.chdir(tmpdir.name) - assert not beman_submodule.cwd_git_repository_path() - subprocess.run(['git', 'init']) - assert beman_submodule.cwd_git_repository_path() == tmpdir.name - os.chdir(original_cwd) - -def test_clone_beman_submodule_into_tmpdir(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD^'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - sha = sha_process.stdout.strip() - beman_submodule.add_command(tmpdir.name, 'foo', False) - module = beman_submodule.get_beman_submodule(Path(tmpdir2.name) / 'foo') - module.commit_hash = sha - tmpdir3 = beman_submodule.clone_beman_submodule_into_tmpdir(module, False) - assert not beman_submodule.directory_compare( - tmpdir.name, tmpdir3.name, ['.git'], False) - tmpdir4 = beman_submodule.clone_beman_submodule_into_tmpdir(module, True) - assert beman_submodule.directory_compare(tmpdir.name, tmpdir4.name, ['.git'], False) - subprocess.run( - ['git', 'reset', '--hard', sha], capture_output=True, check=True, - cwd=tmpdir.name) - assert beman_submodule.directory_compare(tmpdir.name, tmpdir3.name, ['.git'], False) - os.chdir(original_cwd) - -def test_get_paths(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - module = beman_submodule.get_beman_submodule(Path(tmpdir2.name) / 'foo') - assert beman_submodule.get_paths(module) == set(['a.txt']) - os.chdir(original_cwd) - -def test_beman_submodule_status(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - sha = sha_process.stdout.strip() - assert ' ' + sha + ' foo' == beman_submodule.beman_submodule_status( - beman_submodule.get_beman_submodule(Path(tmpdir2.name) / 'foo')) - with open(Path(tmpdir2.name) / 'foo' / 'a.txt', 'w') as f: - f.write('b') - assert '+ ' + sha + ' foo' == beman_submodule.beman_submodule_status( - beman_submodule.get_beman_submodule(Path(tmpdir2.name) / 'foo')) - os.chdir(original_cwd) - -def test_update_command_no_paths(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - orig_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - orig_sha = orig_sha_process.stdout.strip() - parent_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD^'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - parent_sha = parent_sha_process.stdout.strip() - parent_parent_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD^'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - parent_parent_sha = parent_parent_sha_process.stdout.strip() - subprocess.run( - ['git', 'reset', '--hard', parent_parent_sha], capture_output=True, check=True, - cwd=tmpdir.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - beman_submodule.add_command(tmpdir.name, 'bar', False) - subprocess.run( - ['git', 'reset', '--hard', orig_sha], capture_output=True, check=True, - cwd=tmpdir.name) - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'w') as f: - f.write(f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n') - with open(Path(tmpdir2.name) / 'bar' / '.beman_submodule', 'w') as f: - f.write(f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n') - beman_submodule.update_command(False, None) - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n' - with open(Path(tmpdir2.name) / 'bar' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n' - subprocess.run( - ['git', 'reset', '--hard', parent_sha], capture_output=True, check=True, - cwd=tmpdir.name) - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'foo', ['.git', '.beman_submodule'], False) - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'bar', ['.git', '.beman_submodule'], False) - subprocess.run( - ['git', 'reset', '--hard', orig_sha], capture_output=True, check=True, - cwd=tmpdir.name) - beman_submodule.update_command(True, None) - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={orig_sha}\n' - with open(Path(tmpdir2.name) / 'bar' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={orig_sha}\n' - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'foo', ['.git', '.beman_submodule'], False) - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'bar', ['.git', '.beman_submodule'], False) - os.chdir(original_cwd) - -def test_update_command_with_path(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - orig_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - orig_sha = orig_sha_process.stdout.strip() - parent_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD^'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - parent_sha = parent_sha_process.stdout.strip() - parent_parent_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD^'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - parent_parent_sha = parent_parent_sha_process.stdout.strip() - subprocess.run( - ['git', 'reset', '--hard', parent_parent_sha], capture_output=True, check=True, - cwd=tmpdir.name) - tmpdir_parent_parent_copy = tempfile.TemporaryDirectory() - shutil.copytree(tmpdir.name, tmpdir_parent_parent_copy.name, dirs_exist_ok=True) - beman_submodule.add_command(tmpdir.name, 'foo', False) - beman_submodule.add_command(tmpdir.name, 'bar', False) - subprocess.run( - ['git', 'reset', '--hard', orig_sha], capture_output=True, check=True, - cwd=tmpdir.name) - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'w') as f: - f.write(f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n') - with open(Path(tmpdir2.name) / 'bar' / '.beman_submodule', 'w') as f: - f.write(f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n') - beman_submodule.update_command(False, 'foo') - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n' - with open(Path(tmpdir2.name) / 'bar' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n' - subprocess.run( - ['git', 'reset', '--hard', parent_sha], capture_output=True, check=True, - cwd=tmpdir.name) - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'foo', ['.git', '.beman_submodule'], False) - assert beman_submodule.directory_compare( - tmpdir_parent_parent_copy.name, - Path(tmpdir2.name) / 'bar', ['.git', '.beman_submodule'], False) - subprocess.run( - ['git', 'reset', '--hard', orig_sha], capture_output=True, check=True, - cwd=tmpdir.name) - beman_submodule.update_command(True, 'foo') - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={orig_sha}\n' - with open(Path(tmpdir2.name) / 'bar' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\n' - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'foo', ['.git', '.beman_submodule'], False) - assert beman_submodule.directory_compare( - tmpdir_parent_parent_copy.name, - Path(tmpdir2.name) / 'bar', ['.git', '.beman_submodule'], False) - os.chdir(original_cwd) - -def test_update_command_untracked_files(): - tmpdir = create_test_git_repository2() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd(); - os.chdir(tmpdir2.name) - orig_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - orig_sha = orig_sha_process.stdout.strip() - parent_sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD^'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - parent_sha = parent_sha_process.stdout.strip() - os.makedirs(Path(tmpdir2.name) / 'foo') - (Path(tmpdir2.name) / 'foo' / 'c.txt').touch() - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'w') as f: - f.write(f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={parent_sha}\nallow_untracked_files=True') - beman_submodule.update_command(False, 'foo') - assert set(['./foo/a.txt', './foo/c.txt']) == set(glob.glob('./foo/*.txt')) - beman_submodule.update_command(True, 'foo') - assert set(['./foo/b.txt', './foo/c.txt']) == set(glob.glob('./foo/*.txt')) - os.chdir(original_cwd) - -def test_add_command(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - sha = sha_process.stdout.strip() - assert beman_submodule.directory_compare( - tmpdir.name, Path(tmpdir2.name) / 'foo', ['.git', '.beman_submodule'], False) - with open(Path(tmpdir2.name) / 'foo' / '.beman_submodule', 'r') as f: - assert f.read() == f'[beman_submodule]\nremote={tmpdir.name}\ncommit_hash={sha}\n' - os.chdir(original_cwd) - -def test_add_command_untracked_files(): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - os.makedirs(Path(tmpdir2.name) / 'foo') - (Path(tmpdir2.name) / 'foo' / 'c.txt').touch() - beman_submodule.add_command(tmpdir.name, 'foo', True) - assert set(['./foo/a.txt', './foo/c.txt']) == set(glob.glob('./foo/*.txt')) - os.chdir(original_cwd) - -def test_status_command_no_paths(capsys): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - beman_submodule.add_command(tmpdir.name, 'bar', False) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - with open(Path(tmpdir2.name) / 'bar' / 'a.txt', 'w') as f: - f.write('b') - beman_submodule.status_command([]) - sha = sha_process.stdout.strip() - assert capsys.readouterr().out == '+ ' + sha + ' bar\n' + ' ' + sha + ' foo\n' - os.chdir(original_cwd) - -def test_status_command_with_path(capsys): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', False) - beman_submodule.add_command(tmpdir.name, 'bar', False) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - with open(Path(tmpdir2.name) / 'bar' / 'a.txt', 'w') as f: - f.write('b') - beman_submodule.status_command(['bar']) - sha = sha_process.stdout.strip() - assert capsys.readouterr().out == '+ ' + sha + ' bar\n' - os.chdir(original_cwd) - -def test_status_command_untracked_files(capsys): - tmpdir = create_test_git_repository() - tmpdir2 = create_test_git_repository() - original_cwd = Path.cwd() - os.chdir(tmpdir2.name) - beman_submodule.add_command(tmpdir.name, 'foo', True) - sha_process = subprocess.run( - ['git', 'rev-parse', 'HEAD'], capture_output=True, check=True, text=True, - cwd=tmpdir.name) - (Path(tmpdir2.name) / 'foo' / 'c.txt').touch() - beman_submodule.status_command(['foo']) - sha = sha_process.stdout.strip() - assert capsys.readouterr().out == ' ' + sha + ' foo\n' - os.chdir(original_cwd) - -def test_check_for_git(): - tmpdir = tempfile.TemporaryDirectory() - assert not beman_submodule.check_for_git(tmpdir.name) - fake_git_path = Path(tmpdir.name) / 'git' - with open(fake_git_path, 'w'): - pass - os.chmod(fake_git_path, stat.S_IRWXU) - assert beman_submodule.check_for_git(tmpdir.name) - -def test_parse_args(): - def plain_update(): - args = beman_submodule.parse_args(['update']) - assert args.command == 'update' - assert not args.remote - assert not args.beman_submodule_path - plain_update() - def update_remote(): - args = beman_submodule.parse_args(['update', '--remote']) - assert args.command == 'update' - assert args.remote - assert not args.beman_submodule_path - update_remote() - def update_path(): - args = beman_submodule.parse_args(['update', 'infra/']) - assert args.command == 'update' - assert not args.remote - assert args.beman_submodule_path == 'infra/' - update_path() - def update_path_remote(): - args = beman_submodule.parse_args(['update', '--remote', 'infra/']) - assert args.command == 'update' - assert args.remote - assert args.beman_submodule_path == 'infra/' - update_path_remote() - def plain_add(): - args = beman_submodule.parse_args(['add', 'git@github.com:bemanproject/infra.git']) - assert args.command == 'add' - assert args.repository == 'git@github.com:bemanproject/infra.git' - assert not args.path - plain_add() - def add_path(): - args = beman_submodule.parse_args( - ['add', 'git@github.com:bemanproject/infra.git', 'infra/']) - assert args.command == 'add' - assert args.repository == 'git@github.com:bemanproject/infra.git' - assert args.path == 'infra/' - add_path() - def plain_status(): - args = beman_submodule.parse_args(['status']) - assert args.command == 'status' - assert args.paths == [] - plain_status() - def status_one_module(): - args = beman_submodule.parse_args(['status', 'infra/']) - assert args.command == 'status' - assert args.paths == ['infra/'] - status_one_module() - def status_multiple_modules(): - args = beman_submodule.parse_args(['status', 'infra/', 'foobar/']) - assert args.command == 'status' - assert args.paths == ['infra/', 'foobar/'] - status_multiple_modules() diff --git a/cookiecutter/{{cookiecutter.project_name}}/lockfile.json b/cookiecutter/{{cookiecutter.project_name}}/lockfile.json deleted file mode 100644 index 3a69ab1..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/lockfile.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "dependencies": [ - { - "name": "googletest", - "package_name": "GTest", - "git_repository": "https://github.com/google/googletest.git", - "git_tag": "6910c9d9165801d8827d628cb72eb7ea9dd538c5" - } - ] -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index ba64430..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -add_library(beman.{{cookiecutter.project_name}}) -add_library(beman::{{cookiecutter.project_name}} ALIAS beman.{{cookiecutter.project_name}}) - -target_sources(beman.{{cookiecutter.project_name}} PRIVATE identity.cpp) - -target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET HEADERS - BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" - FILES - "${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/{{cookiecutter.project_name}}/identity.hpp" -) - -set_target_properties(beman.{{cookiecutter.project_name}} PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) - -find_package(beman-install-library REQUIRED) -beman_install_library(beman.{{cookiecutter.project_name}}) diff --git a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/beman.{{cookiecutter.project_name}}-config.cmake.in b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/beman.{{cookiecutter.project_name}}-config.cmake.in deleted file mode 100644 index 1e0a25f..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/beman.{{cookiecutter.project_name}}-config.cmake.in +++ /dev/null @@ -1,7 +0,0 @@ -set(BEMAN_{{cookiecutter.project_name.upper()}}_VERSION @PROJECT_VERSION@) - -@PACKAGE_INIT@ - -include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake) - -check_required_components(@PROJECT_NAME@) diff --git a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp deleted file mode 100644 index 1d076c7..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include 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 75c9dfd..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -find_package(GTest REQUIRED) - -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 - PRIVATE beman::{{cookiecutter.project_name}} GTest::gtest GTest::gtest_main -) - -include(GoogleTest) -gtest_discover_tests(beman.{{cookiecutter.project_name}}.tests.identity) 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 7f4bff3..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include - -#include - -#include -#include - -namespace exe = beman::{{cookiecutter.project_name}}; - -TEST(IdentityTest, call_identity_with_int) { - for (int i = -100; i < 100; ++i) { - EXPECT_EQ(i, exe::identity()(i)); - } -} - -TEST(IdentityTest, call_identity_with_custom_type) { - struct S { - int i; - }; - - for (int i = -100; i < 100; ++i) { - const S s{i}; - const S s_id = exe::identity()(s); - EXPECT_EQ(s.i, s_id.i); - } -} - -TEST(IdentityTest, compare_std_vs_beman) { -// 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) { - EXPECT_EQ(std_id(i), beman_id(i)); - } -#endif -} - -TEST(IdentityTest, check_is_transparent) { -// 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); - EXPECT_EQ(3, *it); - auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); - EXPECT_EQ(3, *it_with_id); - - EXPECT_EQ(it, it_with_id); -#endif -} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 49aaf25..d28d9f7 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,27 +1,14 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set(ALL_EXAMPLES identity_direct_usage) - -# Example `identity_as_default_projection` need ranges support: -include(CheckCXXSymbolExists) -check_cxx_symbol_exists(__cpp_lib_ranges "ranges" HAS_RANGES) - -if(HAS_RANGES) - list(APPEND ALL_EXAMPLES identity_as_default_projection) -else() - message( - WARNING - "Missing range support! Skip: identity_as_default_projection" - ) -endif() +set(ALL_EXAMPLES transform_view_join_direct_usage) message("Examples to be built: ${ALL_EXAMPLES}") foreach(example ${ALL_EXAMPLES}) - add_executable(beman.exemplar.examples.${example}) - target_sources(beman.exemplar.examples.${example} PRIVATE ${example}.cpp) + add_executable(beman.transform_join_view.examples.${example}) + target_sources(beman.transform_join_view.examples.${example} PRIVATE ${example}.cpp) target_link_libraries( - beman.exemplar.examples.${example} - PRIVATE beman::exemplar + beman.transform_join_view.examples.${example} + PRIVATE beman::transform_join_view ) endforeach() diff --git a/examples/identity_as_default_projection.cpp b/examples/identity_as_default_projection.cpp deleted file mode 100644 index c3847f1..0000000 --- a/examples/identity_as_default_projection.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -// This example demonstrates the usage of beman::exemplar::identity as a default projection in a range-printer. -// Requires: range support (C++20) and std::identity support (C++20). -// TODO Darius: Do we need to selectively compile this example? -// Or should we assume that this project is compiled with C++20 support only? - -#include - -#include -#include // std::identity -#include -#include -#include -#include - -namespace exe = beman::exemplar; - -// Class with a pair of values. -struct Pair { - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream& operator<<(std::ostream& os, const Pair& p) { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print_helper(const std::string_view rem, R&& range, Projection projection) { - std::cout << rem << '{'; - std::ranges::for_each(range, [O = 0](const auto& o) mutable { std::cout << (O++ ? ", " : "") << o; }, projection); - std::cout << "}\n"; -}; - -// Print wrapper with exe::identity. -template // <- Notice the default projection. -void print_beman(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -// Print wrapper with std::identity. -template // <- Notice the default projection. -void print_std(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -int main() { - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - std::cout << "Default projection:\n"; - print_beman("\tpairs with beman: ", pairs); - print_std("\tpairs with std: ", pairs); - - // Print the pairs using a custom projection. - std::cout << "Custom projection:\n"; - print_beman("\tpairs with beman: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - print_std("\tpairs with std: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - - return 0; -} diff --git a/examples/identity_direct_usage.cpp b/examples/identity_direct_usage.cpp deleted file mode 100644 index 236a63d..0000000 --- a/examples/identity_direct_usage.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include - -#include - -namespace exe = beman::exemplar; - -int main() { - std::cout << exe::identity()(2024) << '\n'; - return 0; -} diff --git a/examples/transform_view_join_direct_usage.cpp b/examples/transform_view_join_direct_usage.cpp new file mode 100644 index 0000000..52ebf9e --- /dev/null +++ b/examples/transform_view_join_direct_usage.cpp @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include + +#include + +namespace exe = beman::transform_join_view; + +int main() { + + return 0; +} diff --git a/include/beman/exemplar/identity.hpp b/include/beman/exemplar/identity.hpp deleted file mode 100644 index 9463125..0000000 --- a/include/beman/exemplar/identity.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_EXEMPLAR_IDENTITY_HPP -#define BEMAN_EXEMPLAR_IDENTITY_HPP - -// C++ Standard Library: std::identity equivalent. -// See https://eel.is/c++draft/func.identity: -// -// 22.10.12 Class identity [func.identity] -// -// struct identity { -// template -// constexpr T&& operator()(T&& t) const noexcept; -// -// using is_transparent = unspecified; -// }; -// -// template -// constexpr T&& operator()(T&& t) const noexcept; -// -// Effects: Equivalent to: return std::forward(t); - -#include // std::forward - -namespace beman::exemplar { - -struct __is_transparent; // not defined - -// A function object that returns its argument unchanged. -struct identity { - // Returns `t`. - template - constexpr T&& operator()(T&& t) const noexcept { - return std::forward(t); - } - - using is_transparent = __is_transparent; -}; - -} // namespace beman::exemplar - -#endif // BEMAN_EXEMPLAR_IDENTITY_HPP diff --git a/include/beman/transform_join_view/identity.hpp b/include/beman/transform_join_view/identity.hpp new file mode 100644 index 0000000..c7add44 --- /dev/null +++ b/include/beman/transform_join_view/identity.hpp @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_TRANSFORM_JOIN_VIEW_IDENTITY_HPP +#define BEMAN_TRANSFORM_JOIN_VIEW_IDENTITY_HPP + + +namespace beman::transform_join_view { + + +} // namespace beman::transform_join_view + +#endif // BEMAN_TRANSFORM_JOIN_VIEW_IDENTITY_HPP diff --git a/lockfile.json b/lockfile.json index 3a69ab1..d12dac5 100644 --- a/lockfile.json +++ b/lockfile.json @@ -1,10 +1,10 @@ { "dependencies": [ { - "name": "googletest", - "package_name": "GTest", - "git_repository": "https://github.com/google/googletest.git", - "git_tag": "6910c9d9165801d8827d628cb72eb7ea9dd538c5" + "name": "catch2", + "package_name": "Catch2", + "git_repository": "https://github.com/catchorg/Catch2.git", + "git_tag": "v3.8.0" } ] } diff --git a/src/beman/exemplar/CMakeLists.txt b/src/beman/exemplar/CMakeLists.txt deleted file mode 100644 index 14d9f70..0000000 --- a/src/beman/exemplar/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -add_library(beman.exemplar) -add_library(beman::exemplar ALIAS beman.exemplar) - -target_sources(beman.exemplar PRIVATE identity.cpp) - -target_sources( - beman.exemplar - PUBLIC - FILE_SET HEADERS - BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" - FILES - "${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/exemplar/identity.hpp" -) - -set_target_properties(beman.exemplar PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) - -find_package(beman-install-library REQUIRED) -beman_install_library(beman.exemplar) diff --git a/src/beman/exemplar/beman.exemplar-config.cmake.in b/src/beman/exemplar/beman.exemplar-config.cmake.in deleted file mode 100644 index 5769cc3..0000000 --- a/src/beman/exemplar/beman.exemplar-config.cmake.in +++ /dev/null @@ -1,7 +0,0 @@ -set(BEMAN_EXEMPLAR_VERSION @PROJECT_VERSION@) - -@PACKAGE_INIT@ - -include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake) - -check_required_components(@PROJECT_NAME@) diff --git a/src/beman/exemplar/identity.cpp b/src/beman/exemplar/identity.cpp deleted file mode 100644 index 21ef59d..0000000 --- a/src/beman/exemplar/identity.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include diff --git a/tests/beman/exemplar/CMakeLists.txt b/tests/beman/exemplar/CMakeLists.txt deleted file mode 100644 index 153cdb8..0000000 --- a/tests/beman/exemplar/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -find_package(GTest REQUIRED) - -add_executable(beman.exemplar.tests.identity) -target_sources(beman.exemplar.tests.identity PRIVATE identity.test.cpp) -target_link_libraries( - beman.exemplar.tests.identity - PRIVATE beman::exemplar GTest::gtest GTest::gtest_main -) - -include(GoogleTest) -gtest_discover_tests(beman.exemplar.tests.identity) diff --git a/tests/beman/exemplar/identity.test.cpp b/tests/beman/exemplar/identity.test.cpp deleted file mode 100644 index 52adbe5..0000000 --- a/tests/beman/exemplar/identity.test.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include - -#include - -#include -#include - -namespace exe = beman::exemplar; - -TEST(IdentityTest, call_identity_with_int) { - for (int i = -100; i < 100; ++i) { - EXPECT_EQ(i, exe::identity()(i)); - } -} - -TEST(IdentityTest, call_identity_with_custom_type) { - struct S { - int i; - }; - - for (int i = -100; i < 100; ++i) { - const S s{i}; - const S s_id = exe::identity()(s); - EXPECT_EQ(s.i, s_id.i); - } -} - -TEST(IdentityTest, compare_std_vs_beman) { -// 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) { - EXPECT_EQ(std_id(i), beman_id(i)); - } -#endif -} - -TEST(IdentityTest, check_is_transparent) { -// 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); - EXPECT_EQ(3, *it); - auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); - EXPECT_EQ(3, *it_with_id); - - EXPECT_EQ(it, it_with_id); -#endif -} diff --git a/tests/beman/transform_join_view/CMakeLists.txt b/tests/beman/transform_join_view/CMakeLists.txt new file mode 100644 index 0000000..44c959d --- /dev/null +++ b/tests/beman/transform_join_view/CMakeLists.txt @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +include(FetchContent) + +FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG v3.8.0 +) +FetchContent_MakeAvailable(Catch2) + +add_executable(beman.transform_join_view.tests) +target_sources(beman.transform_join_view.tests PRIVATE transform_view_join.test.cpp) +target_link_libraries( + beman.transform_join_view.tests + PRIVATE beman::transform_join_view Catch2::Catch2WithMain +) + +include(Catch) +catch_discover_tests(beman.transform_join_view.tests) diff --git a/tests/beman/transform_join_view/transform_view_join.test.cpp b/tests/beman/transform_join_view/transform_view_join.test.cpp new file mode 100644 index 0000000..24cef81 --- /dev/null +++ b/tests/beman/transform_join_view/transform_view_join.test.cpp @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +#include +#include + +namespace exe = beman::transform_join_view; + +TEST_CASE("placeholder test", "[transform_join_view]") { + REQUIRE(true); +} \ No newline at end of file