Files
canon/CMakeLists.txt
T
paulhorn 6981f55f28 Add canon sync
canon sync rewrites the managed block of CMakeLists.txt from .canon.toml,
for after either was edited by hand. It prints a unified diff of the
change (also with --dry-run), writes only CMakeLists.txt so comments in
.canon.toml survive, does nothing if the block already matches, and
warns when the build will still fail because .canon.toml declares files
that do not exist. doctor's hand-edited-block warning now points to it.

- diff: a small line-based unified diff, no external tools
- tests: a sync scenario (hand-edited manifest, --dry-run leaves the file
  untouched, sync from a subdirectory, no-op second run, hand edits in
  the block replaced); unit tests for plan_sync and unified_diff

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

67 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/diff.cpp
canon/doctor.cpp
canon/executor.cpp
canon/generate.cpp
canon/manifest.cpp
canon/name.cpp
canon/plan.cpp
canon/project.cpp
canon/sync.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 diff doctor executor generate manifest name plan project sync 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()