Files
canon/CMakeLists.txt
T
paulhorn a82bdf4734 Add template overrides: canon templates and templates export
Every generated source file, README.md and .gitignore now comes from a
template that a file of the same name can replace:

- <project>/.canon/templates/ for that project, which wins over
- ~/.config/canon/templates/ ($XDG_CONFIG_HOME respected) for all
  projects; canon new reads only these

canon templates lists each template, where it comes from and the
placeholders it can use. canon templates export [<file>...] [--user]
copies built-in texts as a starting point and never overwrites.

Overrides are checked strictly: an unknown file name or a placeholder
the template does not provide is an error naming the file; hidden files
are ignored. Generators take a template_set, so they stay pure.

Also:
- executor: a symlink to a directory counts as a directory (macOS /var,
  linked config directories)
- plan: add_directory stops at the filesystem root
- project: find_project_root, shared by load_project and templates
- tests: a templates scenario; scenarios run canon with their own empty
  XDG_CONFIG_HOME so personal templates cannot affect results

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 19:01:37 +02:00

65 lines
2.1 KiB
CMake

cmake_minimum_required(VERSION 3.20)
project(canon
VERSION 0.1.0
DESCRIPTION "Scaffolds C++ projects that follow P1204R0 (Canonical Project Structure)"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(BUILD_TESTING "Build canon's tests" ON)
# Everything except main(), so unit tests can link against it.
add_library(canon.core STATIC
canon/add.cpp
canon/cli.cpp
canon/cmake.cpp
canon/doctor.cpp
canon/executor.cpp
canon/generate.cpp
canon/manifest.cpp
canon/name.cpp
canon/plan.cpp
canon/project.cpp
canon/template.cpp
canon/templates.cpp
canon/toml.cpp
)
target_include_directories(canon.core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT MSVC)
target_compile_options(canon.core PUBLIC -Wall -Wextra -Wpedantic)
endif()
add_executable(canon canon/canon.cpp)
target_link_libraries(canon PRIVATE canon.core)
target_compile_definitions(canon PRIVATE CANON_VERSION="${PROJECT_VERSION}")
install(TARGETS canon)
if(BUILD_TESTING)
enable_testing()
# Unit tests live next to the code they test: canon/<unit>.test.cpp.
foreach(unit add cli cmake doctor executor generate manifest name plan project template templates toml)
add_executable(canon.${unit}.test canon/${unit}.test.cpp)
target_link_libraries(canon.${unit}.test PRIVATE canon.core)
add_test(NAME canon/${unit}.test COMMAND canon.${unit}.test)
endforeach()
# Byte-for-byte comparison of scaffolded projects against tests/golden/.
add_test(NAME tests/golden
COMMAND ${CMAKE_COMMAND}
-DCANON=$<TARGET_FILE:canon>
-DWORK_DIR=${CMAKE_CURRENT_BINARY_DIR}/tests/golden
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/golden/check.cmake)
# Scaffolds each project kind, then configures, builds and tests it.
add_test(NAME tests/e2e
COMMAND ${CMAKE_COMMAND}
-DCANON=$<TARGET_FILE:canon>
-DWORK_DIR=${CMAKE_CURRENT_BINARY_DIR}/tests/e2e
-DCXX=${CMAKE_CXX_COMPILER}
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/e2e/check.cmake)
set_tests_properties(tests/e2e PROPERTIES LABELS e2e TIMEOUT 300)
endif()