a82bdf4734
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>
65 lines
2.1 KiB
CMake
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()
|