From b784dff2a0c6bc2e26794e9e8ad478709afaa3c0 Mon Sep 17 00:00:00 2001 From: Yury Bayda Date: Fri, 31 Jul 2026 17:59:51 -0700 Subject: [PATCH] feat: streamline cross-platform kata setup Fetch and verify GoogleTest 1.17 when no installed package is available. Use Make locally and throughout CI while retaining direct CMake and CTest commands for environments without Make. Add three-platform CI, ownership, dependency updates, and zero-start documentation. --- .github/CODEOWNERS | 1 + .github/dependabot.yml | 6 +++ .github/workflows/main.yml | 10 ++-- .vscode/tasks.json | 5 +- CMakeLists.txt | 5 +- Makefile | 41 +++++++++++----- README.md | 98 ++++++++++++++++++++++++++++++++------ cmake/FetchGTest.cmake | 17 ++++++- 8 files changed, 145 insertions(+), 38 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..e656eab --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Coding-Cuddles/kata-maintainers diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ca79ca5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 255c5f4..f4a77e1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Check formatting run: make format-check @@ -22,11 +22,11 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 + env: + GTEST_COLOR: "1" - - name: Build - run: make build + steps: + - uses: actions/checkout@v7 - name: Test run: make test diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9ed5ca3..b64ae0d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -17,8 +17,7 @@ "group": { "kind": "test", "isDefault": true - }, - "dependsOn": "Build" + } }, { "label": "Format", @@ -30,4 +29,4 @@ "problemMatcher": [] } ] -} \ No newline at end of file +} diff --git a/CMakeLists.txt b/CMakeLists.txt index ce4f254..b4380e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,12 @@ -cmake_minimum_required(VERSION 3.19) +cmake_minimum_required(VERSION 3.24) project(bootstrap-cpp-kata CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_COLOR_DIAGNOSTICS ON) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) @@ -32,5 +34,6 @@ if(UNIX) copy_if_different ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_CURRENT_LIST_DIR} + COMMENT "Copying compile commands to the source directory" ) endif() diff --git a/Makefile b/Makefile index 1bd5a45..c4edc25 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,47 @@ -all: build test +COLOR_CYAN := \033[36m +COLOR_RESET := \033[0m + +CLICOLOR ?= 1 +GTEST_COLOR ?= 1 +export CLICOLOR GTEST_COLOR BUILDDIR ?= build -SRCS := $(shell git ls-files *.cpp *.h) +BUILDCONFIG ?= Debug +SRCS := $(shell git ls-files '*.cpp' '*.h' '*.hpp') + +.DEFAULT_GOAL := help + +.PHONY: all +all: test ## Build and run tests + +.PHONY: help +help: ## Show this help message + @awk 'BEGIN {FS = ":.*##"; printf "Usage: make [options] $(COLOR_CYAN)[target] ...$(COLOR_RESET)\n\n"} \ + /^[a-zA-Z_-]+:.*##/ {printf " $(COLOR_CYAN)%-20s$(COLOR_RESET) %s\n", $$1, $$2}' \ + $(MAKEFILE_LIST) .PHONY: build -build: - cmake -B ${BUILDDIR} . - cmake --build ${BUILDDIR} +build: ## Configure and build + cmake -S . -B ${BUILDDIR} -DCMAKE_BUILD_TYPE=${BUILDCONFIG} + cmake --build ${BUILDDIR} --config ${BUILDCONFIG} .PHONY: test -test: - ctest --output-on-failure --test-dir ${BUILDDIR} +test: build ## Build and run tests + ctest --test-dir ${BUILDDIR} --build-config ${BUILDCONFIG} --output-on-failure .PHONY: format -format: +format: ## Format C++ sources in place clang-format -i -style=file $(SRCS) .PHONY: format-check -format-check: +format-check: ## Fail if C++ sources require formatting clang-format -style=file --dry-run -Werror $(SRCS) \ || (echo "Some files require formatting. Run 'make format' to fix." && exit 1) .PHONY: clean -clean: - rm -rf ${BUILDDIR} +clean: ## Remove generated build artifacts + rm -rf ${BUILDDIR} compile_commands.json -ifndef VERBOSE +ifneq ($(VERBOSE),1) .SILENT: endif diff --git a/README.md b/README.md index 588fd8d..f5cd427 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,95 @@ # Bootstrap for C++ coding kata [![CI](https://github.com/Coding-Cuddles/bootstrap-cpp-kata/actions/workflows/main.yml/badge.svg)](https://github.com/Coding-Cuddles/bootstrap-cpp-kata/actions/workflows/main.yml) +[![C++17](https://img.shields.io/badge/C%2B%2B-17-blue.svg)](https://en.cppreference.com/w/cpp/17) +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -## Overview - -This is a bootstrap repository for clean code katas in C++17 using GoogleTest. +Start a C++17 coding kata with GoogleTest. Setup is complete when the starter +test passes. ## Prerequisites -- A compatible C++ compiler that supports at least C++17 -- [CMake](https://cmake.org) -- [GoogleTest](https://github.com/google/googletest) +Required: + +- [Git](https://git-scm.com/downloads) +- A compiler with C++17 support. Choose one: + - [GCC](https://gcc.gnu.org/) 10+ on Linux + - [LLVM Clang](https://llvm.org/) 14+ on Linux + - [Apple Clang](https://developer.apple.com/xcode/) 17+ on macOS + - [MSVC](https://visualstudio.microsoft.com/) 2022 on Windows +- [CMake 3.24 or later](https://cmake.org) + +Optional: + +- [GNU Make](https://www.gnu.org/software/make/), for shorter commands. Every + required task also has direct CMake and CTest commands. + +You do not need to install GoogleTest separately. CMake finds an installed +copy or downloads the pinned release when needed. + +## Set up the kata + +1. Clone the repository: + + ```console + git clone https://github.com/Coding-Cuddles/bootstrap-cpp-kata.git + ``` + +2. Enter the repository directory: + + ```console + cd bootstrap-cpp-kata + ``` + +3. Run the starter test. Use Make when it is installed: + + ```console + make test + ``` + + Otherwise, use CMake and CTest directly: + + ```console + cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug + cmake --build build --config Debug + ctest --test-dir build --build-config Debug --output-on-failure + ``` + +The first run may download and build GoogleTest. Setup is complete when CTest reports +`100% tests passed`. + +If a command reports a missing compiler or CMake, install that prerequisite +and run the setup commands again. + +## Work on the kata + +1. Replace the starter assertions in `test_something.cpp` with the first kata test. + +2. Run the tests after each change. Use Make when it is installed: + + ```console + make test + ``` + + Otherwise, use CMake and CTest directly: -## Usage + ```console + cmake --build build --config Debug + ctest --test-dir build --build-config Debug --output-on-failure + ``` -### Build + Continue when CTest reports `100% tests passed`. -```console -make build -``` +## Make command reference -### Run tests +Make is optional. Run `make` or `make help` to list these commands in the +terminal. -```console -make test -``` +| Command | Result | +| ------------------- | ----------------------------------------- | +| `make all` | Build and run the test suite | +| `make build` | Configure and build without running tests | +| `make test` | Build and run the test suite | +| `make format` | Format tracked C++ and header files | +| `make format-check` | Check formatting without changing files | +| `make clean` | Remove generated build artifacts | diff --git a/cmake/FetchGTest.cmake b/cmake/FetchGTest.cmake index f3778ae..c801e16 100644 --- a/cmake/FetchGTest.cmake +++ b/cmake/FetchGTest.cmake @@ -1,10 +1,22 @@ include(FetchContent) +# Find an installed GoogleTest package or fetch and verify the pinned release function(fetch_gtest) + string( + CONCAT + gtest_url + "https://github.com/google/googletest/releases/download/" + "v1.17.0/googletest-1.17.0.tar.gz" + ) + set( + gtest_sha256 + 65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c + ) + FetchContent_Declare( googletest - URL https://github.com/google/googletest/releases/download/v1.16.0/googletest-1.16.0.tar.gz - URL_HASH MD5=9a75eb2ac97300cdb8b65b1a5833f411 + URL ${gtest_url} + URL_HASH SHA256=${gtest_sha256} DOWNLOAD_EXTRACT_TIMESTAMP FALSE FIND_PACKAGE_ARGS @@ -13,6 +25,7 @@ function(fetch_gtest) ) # Prevent overriding parent project's compiler/linker settings on Windows + # cmake-lint: disable=C0103 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest) endfunction()