From 55ea0c0512b89ebffacb23bf376fc24576624c60 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Mon, 12 May 2025 13:37:10 -0400 Subject: [PATCH 01/27] Run ClangTidy on GitHub Actions See: https://github.com/sourcemeta/blaze/issues/429 Signed-off-by: Juan Cruz Viotti --- .github/workflows/ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d8aa7586..55ca2935e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,3 +161,18 @@ jobs: alert-threshold: '5%' comment-always: true fail-on-alert: false + + clang-tidy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: cmake --version + - run: > + cmake -S . -B ./build + -DCMAKE_BUILD_TYPE:STRING=Release + -DSOURCEMETA_CORE_TESTS:BOOL=OFF + -DSOURCEMETA_CORE_BENCHMARK:BOOL=OFF + -DSOURCEMETA_CORE_DOCS:BOOL=OFF + -DBUILD_SHARED_LIBS:BOOL=OFF + -DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON + - run: cmake --build ./build --config Release --target clang_tidy From 8c698eac4b2545e1e271f80ef6cc585c2af00753 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 12:55:31 +0530 Subject: [PATCH 02/27] use llvm Signed-off-by: Balakrishna Avulapati --- .../targets/clang-tidy.config => .clang-tidy | 8 +- .github/workflows/ci.yml | 8 +- CMakeLists.txt | 7 + Makefile | 3 - cmake/common/targets/clang-tidy.cmake | 132 +----------------- 5 files changed, 21 insertions(+), 137 deletions(-) rename cmake/common/targets/clang-tidy.config => .clang-tidy (68%) diff --git a/cmake/common/targets/clang-tidy.config b/.clang-tidy similarity index 68% rename from cmake/common/targets/clang-tidy.config rename to .clang-tidy index a7de0a47b..01659abb0 100644 --- a/cmake/common/targets/clang-tidy.config +++ b/.clang-tidy @@ -13,10 +13,6 @@ Checks: '-*, objc-*, misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-const-correctness' WarningsAsErrors: '*' -HeaderFilterRegex: '' FormatStyle: none -CheckOptions: - # See https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html - # Otherwise ClangTidy wants us to directly include private headers from our modules - - key: misc-include-cleaner.IgnoreHeaders - value: 'src\/core\/.*;uriparser\/.*' +UseColor: true +SystemHeaders: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55ca2935e..8a3214843 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,9 +164,14 @@ jobs: clang-tidy: runs-on: ubuntu-latest + env: + CC: clang + CXX: clang++ steps: - uses: actions/checkout@v4 - run: cmake --version + - name: Install llvm + run: bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release @@ -175,4 +180,5 @@ jobs: -DSOURCEMETA_CORE_DOCS:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON - - run: cmake --build ./build --config Release --target clang_tidy + -DSOURCEMETA_CORE_CLANG_TIDY:BOOL=ON + - run: cmake --build ./build --config Release diff --git a/CMakeLists.txt b/CMakeLists.txt index bc16d8290..6516f36d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ option(SOURCEMETA_CORE_CONTRIB_ZLIB "Build the ZLIB library for downstream consu option(SOURCEMETA_CORE_CONTRIB_BEARSSL "Build the BearSSL library for downstream consumers" OFF) option(SOURCEMETA_CORE_CONTRIB_GOOGLETEST "Build the GoogleTest library for downstream consumers" OFF) option(SOURCEMETA_CORE_CONTRIB_GOOGLEBENCHMARK "Build the GoogleBenchmark library for downstream consumers" OFF) +option(SOURCEMETA_CORE_CLANG_TIDY "Run clang-tidy checks" OFF) include(Sourcemeta) @@ -32,6 +33,10 @@ if(PROJECT_IS_TOP_LEVEL) sourcemeta_enable_simd() endif() +if(SOURCEMETA_CORE_CLANG_TIDY) + sourcemeta_enable_clang_tidy() +endif() + # TODO: Turn this into a re-usable utility CMake function if(SOURCEMETA_CORE_INSTALL) include(GNUInstallDirs) @@ -118,6 +123,8 @@ if(PROJECT_IS_TOP_LEVEL) sourcemeta_target_clang_tidy(SOURCES src/*.cc) endif() +sourcemeta_disable_clang_tidy() + # Testing if(SOURCEMETA_CORE_CONTRIB_GOOGLETEST OR SOURCEMETA_CORE_TESTS) diff --git a/Makefile b/Makefile index d447bd57a..9c166e3fd 100644 --- a/Makefile +++ b/Makefile @@ -25,9 +25,6 @@ compile: .always $(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \ --component sourcemeta_core_dev -lint: .always - $(CMAKE) --build ./build --config $(PRESET) --target clang_tidy - test: .always $(CMAKE) -E env UBSAN_OPTIONS=print_stacktrace=1 \ $(CTEST) --test-dir ./build --build-config $(PRESET) \ diff --git a/cmake/common/targets/clang-tidy.cmake b/cmake/common/targets/clang-tidy.cmake index 47954d1d0..3f7956c60 100644 --- a/cmake/common/targets/clang-tidy.cmake +++ b/cmake/common/targets/clang-tidy.cmake @@ -1,130 +1,8 @@ -function(sourcemeta_target_clang_tidy_attempt_install) - cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL "" "OUTPUT_DIRECTORY" "" ${ARGN}) - if(NOT SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY) - message(FATAL_ERROR "You must pass the output directory in the OUTPUT_DIRECTORY option") - endif() - - # See https://pypi.org/project/clang-tidy/ - set(CLANG_TIDY_BINARY_VERSION "20.1.0") - set(CLANG_TIDY_BINARY_Windows_AMD64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-win_amd64.whl") - set(CLANG_TIDY_BINARY_MSYS_x86_64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-win_amd64.whl") - set(CLANG_TIDY_BINARY_Darwin_arm64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-macosx_11_0_arm64.whl") - set(CLANG_TIDY_BINARY_Darwin_x86_64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-macosx_10_9_x86_64.whl") - set(CLANG_TIDY_BINARY_Linux_aarch64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl") - set(CLANG_TIDY_BINARY_Linux_x86_64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl") - set(CLANG_TIDY_BINARY_CHECKSUM_Windows_AMD64 "02/f0/dd985d9d9b76f8c39f1995aa475d8d5aabbea0d3e0cf498df44dc7bf1cb0") - set(CLANG_TIDY_BINARY_CHECKSUM_MSYS_x86_64 "02/f0/dd985d9d9b76f8c39f1995aa475d8d5aabbea0d3e0cf498df44dc7bf1cb0") - set(CLANG_TIDY_BINARY_CHECKSUM_Darwin_arm64 "95/02/838baf08764b08327322096bda55e8d1e2344e4a13b9308e5642cfaafd8e") - set(CLANG_TIDY_BINARY_CHECKSUM_Darwin_x86_64 "6d/5b/dcfc84b895d8544e00186738ca85132bbd14db4d11dbe39502630ece5391") - set(CLANG_TIDY_BINARY_CHECKSUM_Linux_aarch64 "be/61/9e1a0797639e81c41d38d7b8b2508a9be4b05b9a23baa9d64e7284d07238") - set(CLANG_TIDY_BINARY_CHECKSUM_Linux_x86_64 "52/76/42c61be1c1fdf8bacdbb265f0cd3e11321fee7362f91fa840717a6a41ad6") - set(CLANG_TIDY_BINARY_NAME_Windows_AMD64 "clang-tidy.exe") - set(CLANG_TIDY_BINARY_NAME_MSYS_x86_64 "clang-tidy.exe") - set(CLANG_TIDY_BINARY_NAME_Darwin_arm64 "clang-tidy") - set(CLANG_TIDY_BINARY_NAME_Darwin_x86_64 "clang-tidy") - set(CLANG_TIDY_BINARY_NAME_Linux_aarch64 "clang-tidy") - set(CLANG_TIDY_BINARY_NAME_Linux_x86_64 "clang-tidy") - - # Determine the pre-built binary URL - string(REPLACE "." "_" CLANG_TIDY_BINARY_SYSTEM "${CMAKE_SYSTEM_NAME}") - string(REPLACE "." "_" CLANG_TIDY_BINARY_ARCH "${CMAKE_SYSTEM_PROCESSOR}") - set(CLANG_TIDY_BINARY_URL_VAR "CLANG_TIDY_BINARY_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}") - set(CLANG_TIDY_BINARY_CHECKSUM_VAR "CLANG_TIDY_BINARY_CHECKSUM_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}") - set(CLANG_TIDY_BINARY_NAME_VAR "CLANG_TIDY_BINARY_NAME_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}") - if(NOT DEFINED ${CLANG_TIDY_BINARY_URL_VAR} OR "${${CLANG_TIDY_BINARY_URL_VAR}}" STREQUAL "") - message(WARNING "Skipping `clang-tidy` download. No known pre-build binary URL") - return() - elseif(NOT DEFINED ${CLANG_TIDY_BINARY_CHECKSUM_VAR} OR "${${CLANG_TIDY_BINARY_CHECKSUM_VAR}}" STREQUAL "") - message(FATAL_ERROR "No known `clang-tidy` pre-build binary checksum") - elseif(NOT DEFINED ${CLANG_TIDY_BINARY_NAME_VAR} OR "${${CLANG_TIDY_BINARY_NAME_VAR}}" STREQUAL "") - message(FATAL_ERROR "No known `clang-tidy` pre-build binary name") - endif() - set(CLANG_TIDY_BINARY_URL "https://files.pythonhosted.org/packages/${${CLANG_TIDY_BINARY_CHECKSUM_VAR}}/${${CLANG_TIDY_BINARY_URL_VAR}}") - - # Download and extract the pre-built binary ZIP if needed - set(CLANG_TIDY_BINARY_NAME "${${CLANG_TIDY_BINARY_NAME_VAR}}") - set(CLANG_TIDY_BINARY_OUTPUT "${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}/${CLANG_TIDY_BINARY_NAME}") - if(EXISTS "${CLANG_TIDY_BINARY_OUTPUT}") - message(STATUS "Found existing `clang-tidy` pre-built binary at ${CLANG_TIDY_BINARY_OUTPUT}") - return() - endif() - set(CLANG_TIDY_BINARY_DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/clang-tidy") - file(REMOVE_RECURSE "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}") - file(MAKE_DIRECTORY "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}") - set(CLANG_TIDY_BINARY_WHEEL "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}/clang-tidy.whl") - message(STATUS "Downloading `clang-tidy` pre-built binary from ${CLANG_TIDY_BINARY_URL}") - file(DOWNLOAD "${CLANG_TIDY_BINARY_URL}" "${CLANG_TIDY_BINARY_WHEEL}" - STATUS CLANG_TIDY_BINARY_DOWNLOAD_STATUS SHOW_PROGRESS TLS_VERIFY ON - LOG CLANG_TIDY_BINARY_DOWNLOAD_LOG) - list(GET CLANG_TIDY_BINARY_DOWNLOAD_STATUS 0 _code) - if(NOT _code EQUAL 0) - message(WARNING "Failed to download the `clang-tidy` pre-built binary") - message(WARNING "${CLANG_TIDY_BINARY_DOWNLOAD_LOG}") - file(REMOVE_RECURSE "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}") - return() - endif() - set(CLANG_TIDY_BINARY_EXTRACT_DIR "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}/extracted") - file(MAKE_DIRECTORY "${CLANG_TIDY_BINARY_EXTRACT_DIR}") - file(ARCHIVE_EXTRACT INPUT "${CLANG_TIDY_BINARY_WHEEL}" DESTINATION "${CLANG_TIDY_BINARY_EXTRACT_DIR}") - - # Install the binary - file(MAKE_DIRECTORY "${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}") - file(COPY "${CLANG_TIDY_BINARY_EXTRACT_DIR}/clang_tidy/data/bin/${CLANG_TIDY_BINARY_NAME}" - DESTINATION "${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}") - file(CHMOD "${CLANG_TIDY_BINARY_OUTPUT}" PERMISSIONS - OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - message(STATUS "Installed `clang-tidy` pre-built binary to ${CLANG_TIDY_BINARY_OUTPUT}") +function(sourcemeta_enable_clang_tidy) + find_program(CLANG_TIDY_BIN NAMES clang-tidy) + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) endfunction() -function(sourcemeta_target_clang_tidy) - cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY "REQUIRED" "" "SOURCES" ${ARGN}) - sourcemeta_target_clang_tidy_attempt_install(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") - - if(SOURCEMETA_TARGET_CLANG_TIDY_REQUIRED) - find_program(CLANG_TIDY_BIN NAMES clang-tidy NO_DEFAULT_PATH - PATHS "${CMAKE_CURRENT_BINARY_DIR}/bin") - if(NOT CLANG_TIDY_BIN) - find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED) - endif() - else() - find_program(CLANG_TIDY_BIN NAMES clang-tidy NO_DEFAULT_PATH - PATHS "${CMAKE_CURRENT_BINARY_DIR}/bin") - if(NOT CLANG_TIDY_BIN) - find_program(CLANG_TIDY_BIN NAMES clang-tidy) - endif() - endif() - - - # This covers the empty list too - if(NOT SOURCEMETA_TARGET_CLANG_TIDY_SOURCES) - message(FATAL_ERROR "You must pass file globs to analyze in the SOURCES option") - endif() - file(GLOB_RECURSE SOURCEMETA_TARGET_CLANG_TIDY_FILES - ${SOURCEMETA_TARGET_CLANG_TIDY_SOURCES}) - - set(CLANG_TIDY_CONFIG "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-tidy.config") - - if(CMAKE_SYSTEM_NAME STREQUAL "MSYS") - # Because `clang-tidy` is typically a Windows `.exe`, transform the path accordingly - execute_process(COMMAND cygpath -w "${CLANG_TIDY_CONFIG}" - OUTPUT_VARIABLE CLANG_TIDY_CONFIG OUTPUT_STRIP_TRAILING_WHITESPACE) - endif() - - if(CLANG_TIDY_BIN) - add_custom_target(clang_tidy - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - VERBATIM - COMMAND "${CLANG_TIDY_BIN}" -p "${PROJECT_BINARY_DIR}" - --config-file "${CLANG_TIDY_CONFIG}" - ${SOURCEMETA_TARGET_CLANG_TIDY_FILES} - COMMENT "Analyzing sources using ClangTidy") - else() - add_custom_target(clang_tidy - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - VERBATIM - COMMAND "${CMAKE_COMMAND}" -E echo "Could not locate ClangTidy" - COMMAND "${CMAKE_COMMAND}" -E false) - endif() - - set_target_properties(clang_tidy PROPERTIES FOLDER "Linting") +function(sourcemeta_disable_clang_tidy) + unset(CMAKE_CXX_CLANG_TIDY PARENT_SCOPE) endfunction() From e48ea525c2bd5ff091dc9887b503cfe2e35de240 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 13:09:03 +0530 Subject: [PATCH 03/27] run llvm installation as root Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a3214843..e5448d8b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -171,7 +171,7 @@ jobs: - uses: actions/checkout@v4 - run: cmake --version - name: Install llvm - run: bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" + run: bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" | sudo - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From c845be070a7e01a922c848ef5fcfd4e7bd44fe60 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 13:10:18 +0530 Subject: [PATCH 04/27] use sudo Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5448d8b0..7c8f23d6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -171,7 +171,7 @@ jobs: - uses: actions/checkout@v4 - run: cmake --version - name: Install llvm - run: bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" | sudo + run: sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From 6ee97225f8b6dd167329f32f8748f9daae0abdfd Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 13:12:00 +0530 Subject: [PATCH 05/27] remove redundant target call Signed-off-by: Balakrishna Avulapati --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6516f36d1..e682eb243 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,7 +120,6 @@ if(PROJECT_IS_TOP_LEVEL) src/*.h src/*.cc benchmark/*.h benchmark/*.cc test/*.h test/*.cc) - sourcemeta_target_clang_tidy(SOURCES src/*.cc) endif() sourcemeta_disable_clang_tidy() From 0c9e0d8ccea2397a0d287c90ade7fd219d0de222 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 13:46:48 +0530 Subject: [PATCH 06/27] use macos instead of ubuntu Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c8f23d6f..16245e636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -163,7 +163,7 @@ jobs: fail-on-alert: false clang-tidy: - runs-on: ubuntu-latest + runs-on: macos-latest env: CC: clang CXX: clang++ From f7a9f53cdbc88c8b5154a124323a51b118f1249b Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 13:48:54 +0530 Subject: [PATCH 07/27] use brew Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16245e636..537d6f445 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -171,7 +171,7 @@ jobs: - uses: actions/checkout@v4 - run: cmake --version - name: Install llvm - run: sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" + run: brew install llvm - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From 291bc33e69549b9f92cbd4de2cf9f30fe3309d1b Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 13:54:47 +0530 Subject: [PATCH 08/27] use llvm path Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 537d6f445..8f426afb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -167,6 +167,7 @@ jobs: env: CC: clang CXX: clang++ + PATH: "/opt/homebrew/opt/llvm/bin/:$PATH" steps: - uses: actions/checkout@v4 - run: cmake --version From 12b3e3d5ddb65826339d1ee3998157a449a26028 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 14:00:24 +0530 Subject: [PATCH 09/27] fix path Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f426afb4..bdc4705db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -167,7 +167,7 @@ jobs: env: CC: clang CXX: clang++ - PATH: "/opt/homebrew/opt/llvm/bin/:$PATH" + PATH: "/opt/homebrew/opt/llvm/bin:$PATH" steps: - uses: actions/checkout@v4 - run: cmake --version From 70b925bc68fd36df8c4246e0b87b10c5fc221f3d Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 14:20:13 +0530 Subject: [PATCH 10/27] use a step to set path Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bdc4705db..eb77b16a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -167,12 +167,13 @@ jobs: env: CC: clang CXX: clang++ - PATH: "/opt/homebrew/opt/llvm/bin:$PATH" steps: - uses: actions/checkout@v4 - run: cmake --version - name: Install llvm run: brew install llvm + - name: Set PATH + run: echo "export PATH=/opt/homebrew/opt/llvm/bin:\$PATH" >> $GITHUB_ENV - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From 1bf2001712afd93a787c3fa4609a6ffceb97ecdb Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 14:24:23 +0530 Subject: [PATCH 11/27] disable other jobs while you test the changes Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 116 +++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb77b16a7..58e436813 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,63 +21,63 @@ jobs: type: static shell: sh benchmark: macos/llvm - - os: macos-latest - cc: clang - cxx: clang++ - type: shared - shell: sh - - os: macos-latest - cc: gcc-13 - cxx: g++-13 - type: static - shell: sh - benchmark: macos/gcc - - os: ubuntu-latest - cc: clang - cxx: clang++ - type: static - shell: sh - benchmark: linux/llvm - - os: ubuntu-latest - cc: gcc - cxx: g++ - type: static - shell: sh - benchmark: linux/gcc - - os: ubuntu-latest - cc: clang - cxx: clang++ - type: shared - shell: sh - - os: ubuntu-latest - cc: gcc - cxx: g++ - type: shared - shell: sh - - os: windows-latest - type: static - shell: pwsh - benchmark: windows/msvc - - os: windows-latest - type: shared - shell: pwsh - - os: windows-latest - type: static - shell: msys2 {0} - - # Sanitizers - - os: ubuntu-latest - cc: clang - cxx: clang++ - type: static - shell: sh - options: -DSOURCEMETA_CORE_ADDRESS_SANITIZER:BOOL=ON - - os: ubuntu-latest - cc: clang - cxx: clang++ - type: static - shell: sh - options: -DSOURCEMETA_CORE_UNDEFINED_SANITIZER:BOOL=ON + # - os: macos-latest + # cc: clang + # cxx: clang++ + # type: shared + # shell: sh + # - os: macos-latest + # cc: gcc-13 + # cxx: g++-13 + # type: static + # shell: sh + # benchmark: macos/gcc + # - os: ubuntu-latest + # cc: clang + # cxx: clang++ + # type: static + # shell: sh + # benchmark: linux/llvm + # - os: ubuntu-latest + # cc: gcc + # cxx: g++ + # type: static + # shell: sh + # benchmark: linux/gcc + # - os: ubuntu-latest + # cc: clang + # cxx: clang++ + # type: shared + # shell: sh + # - os: ubuntu-latest + # cc: gcc + # cxx: g++ + # type: shared + # shell: sh + # - os: windows-latest + # type: static + # shell: pwsh + # benchmark: windows/msvc + # - os: windows-latest + # type: shared + # shell: pwsh + # - os: windows-latest + # type: static + # shell: msys2 {0} + # + # # Sanitizers + # - os: ubuntu-latest + # cc: clang + # cxx: clang++ + # type: static + # shell: sh + # options: -DSOURCEMETA_CORE_ADDRESS_SANITIZER:BOOL=ON + # - os: ubuntu-latest + # cc: clang + # cxx: clang++ + # type: static + # shell: sh + # options: -DSOURCEMETA_CORE_UNDEFINED_SANITIZER:BOOL=ON defaults: run: @@ -173,7 +173,7 @@ jobs: - name: Install llvm run: brew install llvm - name: Set PATH - run: echo "export PATH=/opt/homebrew/opt/llvm/bin:\$PATH" >> $GITHUB_ENV + run: echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> /Users/runner/.bash_profile - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From 593833dc341486ddcb1b91b5056ad9385225cbd1 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 14:41:49 +0530 Subject: [PATCH 12/27] use bash Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58e436813..75f567548 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -183,4 +183,6 @@ jobs: -DBUILD_SHARED_LIBS:BOOL=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON -DSOURCEMETA_CORE_CLANG_TIDY:BOOL=ON + shell: bash - run: cmake --build ./build --config Release + shell: bash From d334af431b8b82098400effa636b315c1a1d93eb Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 14:45:33 +0530 Subject: [PATCH 13/27] debug path Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75f567548..4615fd15e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -174,6 +174,11 @@ jobs: run: brew install llvm - name: Set PATH run: echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> /Users/runner/.bash_profile + - name: Debug Environment + run: | + echo "PATH: $PATH" + echo "SHELL: $SHELL" + shell: bash - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From 996c687033dfa7c7876f4db14ea68239748ff03e Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 15:00:21 +0530 Subject: [PATCH 14/27] use Github path Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4615fd15e..f2a170b8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -173,7 +173,7 @@ jobs: - name: Install llvm run: brew install llvm - name: Set PATH - run: echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> /Users/runner/.bash_profile + run: echo "/opt/homebrew/opt/llvm/bin:$PATH" >> "$GITHUB_PATH" - name: Debug Environment run: | echo "PATH: $PATH" From 81bc9ab14b20ef6fc10b8e2fcf4f78019e4a5c31 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 15:07:57 +0530 Subject: [PATCH 15/27] use ubuntu Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2a170b8b..e2cde26ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -163,17 +163,14 @@ jobs: fail-on-alert: false clang-tidy: - runs-on: macos-latest - env: - CC: clang - CXX: clang++ + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: cmake --version - name: Install llvm - run: brew install llvm - - name: Set PATH - run: echo "/opt/homebrew/opt/llvm/bin:$PATH" >> "$GITHUB_PATH" + run: sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" + # - name: Set PATH + # run: echo "/opt/homebrew/opt/llvm/bin:$PATH" >> "$GITHUB_PATH" - name: Debug Environment run: | echo "PATH: $PATH" From bdac96cf3168c4abc92860cacbf693c0e5fec8e0 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 18:18:54 +0530 Subject: [PATCH 16/27] fix modernize-use-nodiscard checks Signed-off-by: Balakrishna Avulapati --- .clang-tidy | 22 ++++--- .../json/include/sourcemeta/core/json_array.h | 24 ++++--- .../json/include/sourcemeta/core/json_hash.h | 8 ++- .../include/sourcemeta/core/json_object.h | 66 ++++++++++++------- .../sourcemeta/core/jsonpointer_pointer.h | 44 ++++++++----- .../sourcemeta/core/jsonpointer_position.h | 5 +- .../sourcemeta/core/jsonpointer_template.h | 27 +++++--- .../sourcemeta/core/jsonpointer_walker.h | 16 +++-- .../sourcemeta/core/jsonschema_frame.h | 32 ++++----- .../sourcemeta/core/jsonschema_transform.h | 18 ++--- .../sourcemeta/core/jsonschema_walker.h | 24 +++---- src/core/uri/include/sourcemeta/core/uri.h | 14 ++-- .../jsonschema/jsonschema_transformer_test.cc | 7 +- 13 files changed, 188 insertions(+), 119 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 01659abb0..5cfe08f36 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -2,16 +2,18 @@ # See https://clang.llvm.org/extra/clang-tidy/index.html # First disable all default checks (with -*) Checks: '-*, - bugprone-*,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-bugprone-empty-catch, - clang-analyzer-*, - clang-diagnostic-*, - modernize-*, - concurrency-*, - cppcoreguidelines-*,-cppcoreguidelines-rvalue-reference-param-not-moved, - performance-*,-performance-enum-size, - portability-*, - objc-*, - misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-const-correctness' + modernize-use-nodiscard' +# TODO(bavulapati): iterate through the rules and enable them incrementally inorder to send smaller PRs + # bugprone-*,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-bugprone-empty-catch, + # clang-analyzer-*, + # clang-diagnostic-*, + # modernize-*, + # concurrency-*, + # cppcoreguidelines-*,-cppcoreguidelines-rvalue-reference-param-not-moved, + # performance-*,-performance-enum-size, + # portability-*, + # objc-*, + # misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-const-correctness' WarningsAsErrors: '*' FormatStyle: none UseColor: true diff --git a/src/core/json/include/sourcemeta/core/json_array.h b/src/core/json/include/sourcemeta/core/json_array.h index 5772abac5..d43fdc459 100644 --- a/src/core/json/include/sourcemeta/core/json_array.h +++ b/src/core/json/include/sourcemeta/core/json_array.h @@ -56,31 +56,39 @@ template class JSONArray { /// Get a mutable end iterator on the array auto end() noexcept -> iterator { return this->data.end(); } /// Get a constant begin iterator on the array - auto begin() const noexcept -> const_iterator { return this->data.begin(); } + [[nodiscard]] auto begin() const noexcept -> const_iterator { + return this->data.begin(); + } /// Get a constant end iterator on the array - auto end() const noexcept -> const_iterator { return this->data.end(); } + [[nodiscard]] auto end() const noexcept -> const_iterator { + return this->data.end(); + } /// Get a constant begin iterator on the array - auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); } + [[nodiscard]] auto cbegin() const noexcept -> const_iterator { + return this->data.cbegin(); + } /// Get a constant end iterator on the array - auto cend() const noexcept -> const_iterator { return this->data.cend(); } + [[nodiscard]] auto cend() const noexcept -> const_iterator { + return this->data.cend(); + } /// Get a mutable reverse begin iterator on the array auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); } /// Get a mutable reverse end iterator on the array auto rend() noexcept -> reverse_iterator { return this->data.rend(); } /// Get a constant reverse begin iterator on the array - auto rbegin() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator { return this->data.rbegin(); } /// Get a constant reverse end iterator on the array - auto rend() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return this->data.rend(); } /// Get a constant reverse begin iterator on the array - auto crbegin() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator { return this->data.crbegin(); } /// Get a constant reverse end iterator on the array - auto crend() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return this->data.crend(); } diff --git a/src/core/json/include/sourcemeta/core/json_hash.h b/src/core/json/include/sourcemeta/core/json_hash.h index 14bfe9b35..e4da63e38 100644 --- a/src/core/json/include/sourcemeta/core/json_hash.h +++ b/src/core/json/include/sourcemeta/core/json_hash.h @@ -14,7 +14,7 @@ template struct HashJSON { return value.fast_hash(); } - inline auto is_perfect(const hash_type) const noexcept -> bool { + [[nodiscard]] inline auto is_perfect(const hash_type) const noexcept -> bool { return false; } }; @@ -45,7 +45,8 @@ template struct PropertyHashJSON { } }; - inline auto perfect(const T &value, const std::size_t size) const noexcept + [[nodiscard]] inline auto perfect(const T &value, + const std::size_t size) const noexcept -> hash_type { hash_type result; assert(!value.empty()); @@ -134,7 +135,8 @@ template struct PropertyHashJSON { } } - inline auto is_perfect(const hash_type &hash) const noexcept -> bool { + [[nodiscard]] inline auto is_perfect(const hash_type &hash) const noexcept + -> bool { // If there is anything written past the first byte, // then it is a perfect hash return hash.a > 255; diff --git a/src/core/json/include/sourcemeta/core/json_object.h b/src/core/json/include/sourcemeta/core/json_object.h index c14d6ba9c..0b8f39e0f 100644 --- a/src/core/json/include/sourcemeta/core/json_object.h +++ b/src/core/json/include/sourcemeta/core/json_object.h @@ -46,12 +46,21 @@ template class FlatMap { } } - auto begin() const noexcept -> const_iterator { return this->data.begin(); } - auto end() const noexcept -> const_iterator { return this->data.end(); } - auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); } - auto cend() const noexcept -> const_iterator { return this->data.cend(); } + [[nodiscard]] auto begin() const noexcept -> const_iterator { + return this->data.begin(); + } + [[nodiscard]] auto end() const noexcept -> const_iterator { + return this->data.end(); + } + [[nodiscard]] auto cbegin() const noexcept -> const_iterator { + return this->data.cbegin(); + } + [[nodiscard]] auto cend() const noexcept -> const_iterator { + return this->data.cend(); + } - inline auto hash(const key_type &key) const noexcept -> hash_type { + [[nodiscard]] inline auto hash(const key_type &key) const noexcept + -> hash_type { return this->hasher(key); } @@ -102,7 +111,8 @@ template class FlatMap { } // As a performance optimisation if the hash is known - inline auto find(const key_type &key, const hash_type key_hash) const + [[nodiscard]] inline auto find(const key_type &key, + const hash_type key_hash) const -> const_iterator { assert(this->hash(key) == key_hash); @@ -129,7 +139,8 @@ template class FlatMap { return this->cend(); } - inline auto try_at(const key_type &key, const hash_type key_hash) const + [[nodiscard]] inline auto try_at(const key_type &key, + const hash_type key_hash) const -> const mapped_type * { assert(this->hash(key) == key_hash); @@ -153,7 +164,8 @@ template class FlatMap { } // As a performance optimisation if the hash is known - auto contains(const key_type &key, const hash_type key_hash) const -> bool { + [[nodiscard]] auto contains(const key_type &key, + const hash_type key_hash) const -> bool { assert(this->hash(key) == key_hash); // Move the perfect hash condition out of the loop for extra performance @@ -176,7 +188,8 @@ template class FlatMap { // As a performance optimisation if the hash is known - inline auto at(const key_type &key, const hash_type key_hash) const + [[nodiscard]] inline auto at(const key_type &key, + const hash_type key_hash) const -> const mapped_type & { assert(this->hash(key) == key_hash); @@ -230,7 +243,8 @@ template class FlatMap { #endif } - inline auto at(const size_type index) const noexcept -> const Entry & { + [[nodiscard]] inline auto at(const size_type index) const noexcept + -> const Entry & { return this->data[index]; } @@ -285,9 +299,13 @@ template class FlatMap { return this->erase(key, this->hash(key)); } - inline auto size() const noexcept -> size_type { return this->data.size(); } + [[nodiscard]] inline auto size() const noexcept -> size_type { + return this->data.size(); + } - inline auto empty() const noexcept -> bool { return this->data.empty(); } + [[nodiscard]] inline auto empty() const noexcept -> bool { + return this->data.empty(); + } inline auto clear() noexcept -> void { this->data.clear(); } @@ -386,44 +404,48 @@ template class JSONObject { using const_pointer = typename Container::const_pointer; using const_iterator = typename Container::const_iterator; - inline auto begin() const noexcept -> const_iterator { + [[nodiscard]] inline auto begin() const noexcept -> const_iterator { return this->data.begin(); } /// Get a constant end iterator on the object - inline auto end() const noexcept -> const_iterator { + [[nodiscard]] inline auto end() const noexcept -> const_iterator { return this->data.end(); } /// Get a constant begin iterator on the object - inline auto cbegin() const noexcept -> const_iterator { + [[nodiscard]] inline auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); } /// Get a constant end iterator on the object - inline auto cend() const noexcept -> const_iterator { + [[nodiscard]] inline auto cend() const noexcept -> const_iterator { return this->data.cend(); } /// Attempt to find an entry by key - inline auto find(const Key &key) const -> const_iterator { + [[nodiscard]] inline auto find(const Key &key) const -> const_iterator { return this->data.find(key, this->data.hash(key)); } /// Check if an entry with the given key exists - inline auto defines(const Key &key, - const typename Container::hash_type hash) const -> bool { + [[nodiscard]] inline auto + defines(const Key &key, const typename Container::hash_type hash) const + -> bool { return this->data.contains(key, hash); } /// Check the size of the object - inline auto size() const -> std::size_t { return this->data.size(); } + [[nodiscard]] inline auto size() const -> std::size_t { + return this->data.size(); + } /// Access an object entry by its underlying positional index - inline auto at(const size_type index) const noexcept -> const + [[nodiscard]] inline auto at(const size_type index) const noexcept -> const typename Container::Entry & { return this->data.at(index); } // Hash an object property - inline auto hash(const Key &property) const -> typename Container::hash_type { + [[nodiscard]] inline auto hash(const Key &property) const -> + typename Container::hash_type { return this->data.hasher(property); } diff --git a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_pointer.h b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_pointer.h index b751e177c..c4fa9b8b1 100644 --- a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_pointer.h +++ b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_pointer.h @@ -68,31 +68,39 @@ template class GenericPointer { /// Get a mutable end iterator on the pointer auto end() noexcept -> iterator { return this->data.end(); } /// Get a constant begin iterator on the pointer - auto begin() const noexcept -> const_iterator { return this->data.begin(); } + [[nodiscard]] auto begin() const noexcept -> const_iterator { + return this->data.begin(); + } /// Get a constant end iterator on the pointer - auto end() const noexcept -> const_iterator { return this->data.end(); } + [[nodiscard]] auto end() const noexcept -> const_iterator { + return this->data.end(); + } /// Get a constant begin iterator on the pointer - auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); } + [[nodiscard]] auto cbegin() const noexcept -> const_iterator { + return this->data.cbegin(); + } /// Get a constant end iterator on the pointer - auto cend() const noexcept -> const_iterator { return this->data.cend(); } + [[nodiscard]] auto cend() const noexcept -> const_iterator { + return this->data.cend(); + } /// Get a mutable reverse begin iterator on the pointer auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); } /// Get a mutable reverse end iterator on the pointer auto rend() noexcept -> reverse_iterator { return this->data.rend(); } /// Get a constant reverse begin iterator on the pointer - auto rbegin() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator { return this->data.rbegin(); } /// Get a constant reverse end iterator on the pointer - auto rend() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return this->data.rend(); } /// Get a constant reverse begin iterator on the pointer - auto crbegin() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator { return this->data.crbegin(); } /// Get a constant reverse end iterator on the pointer - auto crend() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return this->data.crend(); } @@ -437,7 +445,7 @@ template class GenericPointer { /// assert(left.concat(right) == /// sourcemeta::core::Pointer{"foo", "bar", "baz"}); /// ``` - auto concat(const GenericPointer &other) const + [[nodiscard]] auto concat(const GenericPointer &other) const -> GenericPointer { GenericPointer result{*this}; result.push_back(other); @@ -455,7 +463,8 @@ template class GenericPointer { /// const sourcemeta::core::Pointer prefix{"foo", "bar"}; /// assert(pointer.starts_with(prefix)); /// ``` - auto starts_with(const GenericPointer &other) const -> bool { + [[nodiscard]] auto + starts_with(const GenericPointer &other) const -> bool { return other.data.size() <= this->data.size() && std::equal(other.data.cbegin(), other.data.cend(), this->data.cbegin()); @@ -473,8 +482,8 @@ template class GenericPointer { /// const sourcemeta::core::Pointer prefix{"foo", "bar", "baz"}; /// assert(pointer.starts_with(prefix, tail)); /// ``` - auto starts_with(const GenericPointer &other, - const Token &tail) const -> bool { + [[nodiscard]] auto starts_with(const GenericPointer &other, + const Token &tail) const -> bool { if (other.size() == this->size() + 1) { assert(!other.empty()); return other.starts_with(*this) && other.back() == tail; @@ -494,7 +503,8 @@ template class GenericPointer { /// const sourcemeta::core::Pointer prefix{"foo", "bar", "qux"}; /// assert(pointer.starts_with_initial(prefix)); /// ``` - auto starts_with_initial(const GenericPointer &other) const + [[nodiscard]] auto + starts_with_initial(const GenericPointer &other) const -> bool { const auto prefix_size{other.size()}; if (prefix_size == 0) { @@ -525,8 +535,9 @@ template class GenericPointer { /// assert(pointer.rebase(prefix, replacement) == /// sourcemeta::core::Pointer{"qux", "baz"}); /// ``` - auto rebase(const GenericPointer &prefix, - const GenericPointer &replacement) const + [[nodiscard]] auto + rebase(const GenericPointer &prefix, + const GenericPointer &replacement) const -> GenericPointer { typename Container::size_type index{0}; while (index < prefix.size()) { @@ -560,7 +571,8 @@ template class GenericPointer { /// /// If the JSON Pointer is not relative to the base, a copy of the original /// input pointer is returned. - auto resolve_from(const GenericPointer &base) const + [[nodiscard]] auto + resolve_from(const GenericPointer &base) const -> GenericPointer { typename Container::size_type index{0}; while (index < base.size()) { diff --git a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_position.h b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_position.h index 6da8ea21e..2e36acbd5 100644 --- a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_position.h +++ b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_position.h @@ -51,8 +51,9 @@ class SOURCEMETA_CORE_JSONPOINTER_EXPORT PointerPositionTracker { auto operator()(const JSON::ParsePhase phase, const JSON::Type, const std::uint64_t line, const std::uint64_t column, const JSON &value) -> void; - auto get(const Pointer &pointer) const -> std::optional; - auto size() const -> std::size_t; + [[nodiscard]] auto get(const Pointer &pointer) const + -> std::optional; + [[nodiscard]] auto size() const -> std::size_t; private: // Exporting symbols that depends on the standard C++ library is considered diff --git a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_template.h b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_template.h index c79fb91f9..0a6eb600f 100644 --- a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_template.h +++ b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_template.h @@ -85,31 +85,39 @@ template class GenericPointerTemplate { /// Get a mutable end iterator on the pointer auto end() noexcept -> iterator { return this->data.end(); } /// Get a constant begin iterator on the pointer - auto begin() const noexcept -> const_iterator { return this->data.begin(); } + [[nodiscard]] auto begin() const noexcept -> const_iterator { + return this->data.begin(); + } /// Get a constant end iterator on the pointer - auto end() const noexcept -> const_iterator { return this->data.end(); } + [[nodiscard]] auto end() const noexcept -> const_iterator { + return this->data.end(); + } /// Get a constant begin iterator on the pointer - auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); } + [[nodiscard]] auto cbegin() const noexcept -> const_iterator { + return this->data.cbegin(); + } /// Get a constant end iterator on the pointer - auto cend() const noexcept -> const_iterator { return this->data.cend(); } + [[nodiscard]] auto cend() const noexcept -> const_iterator { + return this->data.cend(); + } /// Get a mutable reverse begin iterator on the pointer auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); } /// Get a mutable reverse end iterator on the pointer auto rend() noexcept -> reverse_iterator { return this->data.rend(); } /// Get a constant reverse begin iterator on the pointer - auto rbegin() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator { return this->data.rbegin(); } /// Get a constant reverse end iterator on the pointer - auto rend() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return this->data.rend(); } /// Get a constant reverse begin iterator on the pointer - auto crbegin() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator { return this->data.crbegin(); } /// Get a constant reverse end iterator on the pointer - auto crend() const noexcept -> const_reverse_iterator { + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return this->data.crend(); } @@ -172,7 +180,8 @@ template class GenericPointerTemplate { /// /// assert(left.concat(right) == expected); /// ``` - auto concat(const GenericPointerTemplate &&other) const + [[nodiscard]] auto + concat(const GenericPointerTemplate &&other) const -> GenericPointerTemplate { GenericPointerTemplate result{*this}; result.data.reserve(result.data.size() + other.data.size()); diff --git a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_walker.h b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_walker.h index cece2d5ec..9441f564b 100644 --- a/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_walker.h +++ b/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_walker.h @@ -19,10 +19,18 @@ template class GenericPointerWalker { GenericPointerWalker(const JSON &document) { this->walk(document, {}); } using const_iterator = typename internal::const_iterator; - auto begin() const -> const_iterator { return this->pointers.begin(); }; - auto end() const -> const_iterator { return this->pointers.end(); }; - auto cbegin() const -> const_iterator { return this->pointers.cbegin(); }; - auto cend() const -> const_iterator { return this->pointers.cend(); }; + [[nodiscard]] auto begin() const -> const_iterator { + return this->pointers.begin(); + }; + [[nodiscard]] auto end() const -> const_iterator { + return this->pointers.end(); + }; + [[nodiscard]] auto cbegin() const -> const_iterator { + return this->pointers.cbegin(); + }; + [[nodiscard]] auto cend() const -> const_iterator { + return this->pointers.cend(); + }; private: auto walk(const JSON &document, const PointerT &pointer) -> void { diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h index 5c772f539..38dac4d69 100644 --- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h +++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h @@ -110,7 +110,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame { SchemaFrame(const Mode mode) : mode_{mode} {} // Query the current mode that the schema frame was configured with - auto mode() const noexcept -> Mode { return this->mode_; } + [[nodiscard]] auto mode() const noexcept -> Mode { return this->mode_; } /// A single entry in a JSON Schema reference map struct ReferencesEntry { @@ -182,7 +182,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame { using Paths = std::set; /// Export the frame entries as JSON - auto to_json() const -> JSON; + [[nodiscard]] auto to_json() const -> JSON; /// Analyse a schema or set of schemas from a given root. Passing /// multiple paths that have any overlap is undefined behaviour @@ -194,45 +194,47 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame { const Paths &paths = {empty_pointer}) -> void; /// Access the analysed schema locations - auto locations() const noexcept -> const Locations &; + [[nodiscard]] auto locations() const noexcept -> const Locations &; /// Access the analysed schema references - auto references() const noexcept -> const References &; + [[nodiscard]] auto references() const noexcept -> const References &; /// Check whether the analysed schema has no external references - auto standalone() const -> bool; + [[nodiscard]] auto standalone() const -> bool; /// Get the vocabularies associated with a location entry - auto vocabularies(const Location &location, - const SchemaResolver &resolver) const -> Vocabularies; + [[nodiscard]] auto vocabularies(const Location &location, + const SchemaResolver &resolver) const + -> Vocabularies; /// Get the URI associated with a location entry - auto uri(const Location &location, - const Pointer &relative_schema_location = empty_pointer) const + [[nodiscard]] auto + uri(const Location &location, + const Pointer &relative_schema_location = empty_pointer) const -> JSON::String; /// Get the location associated by traversing a pointer from another location - auto traverse(const Location &location, - const Pointer &relative_schema_location) const + [[nodiscard]] auto traverse(const Location &location, + const Pointer &relative_schema_location) const -> const Location &; /// Get the location associated with a given URI - auto traverse(const JSON::String &uri) const + [[nodiscard]] auto traverse(const JSON::String &uri) const -> std::optional>; /// Try to dereference a reference location into its destination location - auto + [[nodiscard]] auto dereference(const Location &location, const Pointer &relative_schema_location = empty_pointer) const -> std::pair>>; /// Get the unresolved instance locations associated with a location entry - auto instance_locations(const Location &location) const -> const + [[nodiscard]] auto instance_locations(const Location &location) const -> const typename Instances::mapped_type &; /// Find all references to a given location pointer - auto references_to(const Pointer &pointer) const -> std::vector< + [[nodiscard]] auto references_to(const Pointer &pointer) const -> std::vector< std::reference_wrapper>; private: diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_transform.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_transform.h index 84f738b79..a496bb375 100644 --- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_transform.h +++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_transform.h @@ -93,10 +93,11 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaTransformRule { -> std::pair; /// Check if the rule applies to a schema - auto check(const JSON &schema, const JSON &root, - const Vocabularies &vocabularies, const SchemaWalker &walker, - const SchemaResolver &resolver, const SchemaFrame &frame, - const SchemaFrame::Location &location) const -> Result; + [[nodiscard]] auto + check(const JSON &schema, const JSON &root, const Vocabularies &vocabularies, + const SchemaWalker &walker, const SchemaResolver &resolver, + const SchemaFrame &frame, const SchemaFrame::Location &location) const + -> Result; /// A method to optionally fix any reference location that was affected by the /// transformation. @@ -236,10 +237,11 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaTransformer { -> bool; /// Report back the rules from the bundle that need to be applied to a schema - auto check(const JSON &schema, const SchemaWalker &walker, - const SchemaResolver &resolver, const Callback &callback, - const std::optional &default_dialect = std::nullopt, - const std::optional &default_id = std::nullopt) const + [[nodiscard]] auto + check(const JSON &schema, const SchemaWalker &walker, + const SchemaResolver &resolver, const Callback &callback, + const std::optional &default_dialect = std::nullopt, + const std::optional &default_id = std::nullopt) const -> bool; private: diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h index 4083ade59..a953b52fa 100644 --- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h +++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h @@ -65,10 +65,10 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaIterator { const JSON &input, const SchemaWalker &walker, const SchemaResolver &resolver, const std::optional &default_dialect = std::nullopt); - auto begin() const -> const_iterator; - auto end() const -> const_iterator; - auto cbegin() const -> const_iterator; - auto cend() const -> const_iterator; + [[nodiscard]] auto begin() const -> const_iterator; + [[nodiscard]] auto end() const -> const_iterator; + [[nodiscard]] auto cbegin() const -> const_iterator; + [[nodiscard]] auto cend() const -> const_iterator; private: // Exporting symbols that depends on the standard C++ library is considered @@ -132,10 +132,10 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaIteratorFlat { const JSON &input, const SchemaWalker &walker, const SchemaResolver &resolver, const std::optional &default_dialect = std::nullopt); - auto begin() const -> const_iterator; - auto end() const -> const_iterator; - auto cbegin() const -> const_iterator; - auto cend() const -> const_iterator; + [[nodiscard]] auto begin() const -> const_iterator; + [[nodiscard]] auto end() const -> const_iterator; + [[nodiscard]] auto cbegin() const -> const_iterator; + [[nodiscard]] auto cend() const -> const_iterator; private: // Exporting symbols that depends on the standard C++ library is considered @@ -189,10 +189,10 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaKeywordIterator { const JSON &input, const SchemaWalker &walker, const SchemaResolver &resolver, const std::optional &default_dialect = std::nullopt); - auto begin() const -> const_iterator; - auto end() const -> const_iterator; - auto cbegin() const -> const_iterator; - auto cend() const -> const_iterator; + [[nodiscard]] auto begin() const -> const_iterator; + [[nodiscard]] auto end() const -> const_iterator; + [[nodiscard]] auto cbegin() const -> const_iterator; + [[nodiscard]] auto cend() const -> const_iterator; private: // Exporting symbols that depends on the standard C++ library is considered diff --git a/src/core/uri/include/sourcemeta/core/uri.h b/src/core/uri/include/sourcemeta/core/uri.h index 3312a7603..f5a69015f 100644 --- a/src/core/uri/include/sourcemeta/core/uri.h +++ b/src/core/uri/include/sourcemeta/core/uri.h @@ -85,7 +85,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// const sourcemeta::core::URI uri{"urn:example:schema"}; /// assert(uri.is_urn()); /// ``` - auto is_urn() const -> bool; + [[nodiscard]] auto is_urn() const -> bool; /// Check if the URI is a tag as described by RFC 4151. For example: /// @@ -96,7 +96,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// const sourcemeta::core::URI uri{"tag:yaml.org,2002:int"}; /// assert(uri.is_tag()); /// ``` - auto is_tag() const -> bool; + [[nodiscard]] auto is_tag() const -> bool; /// Check if the URI has the `mailto` scheme. For example: /// @@ -107,7 +107,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// const sourcemeta::core::URI uri{"mailto:joe@example.com"}; /// assert(uri.is_mailto()); /// ``` - auto is_mailto() const -> bool; + [[nodiscard]] auto is_mailto() const -> bool; /// Check if the URI only consists of a fragment. For example: /// @@ -118,7 +118,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// const sourcemeta::core::URI uri{"#foo"}; /// assert(uri.is_fragment_only()); /// ``` - auto is_fragment_only() const -> bool; + [[nodiscard]] auto is_fragment_only() const -> bool; /// Check if the URI is relative. For example: /// @@ -129,7 +129,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// sourcemeta::core::URI uri{"./foo"}; /// assert(uri.is_relative()); /// ``` - auto is_relative() const -> bool; + [[nodiscard]] auto is_relative() const -> bool; /// Check if the host is an ipv6 address. For example: /// @@ -140,7 +140,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// sourcemeta::core::URI uri{"http://[::1]"}; /// assert(uri.is_ipv6()); /// ``` - auto is_ipv6() const -> bool; + [[nodiscard]] auto is_ipv6() const -> bool; /// Check if the URI corresponds to the empty URI. For example: /// @@ -151,7 +151,7 @@ class SOURCEMETA_CORE_URI_EXPORT URI { /// sourcemeta::core::URI uri{""}; /// assert(uri.empty()); /// ``` - auto empty() const -> bool; + [[nodiscard]] auto empty() const -> bool; /// Get the scheme part of the URI, if any. For example: /// diff --git a/test/jsonschema/jsonschema_transformer_test.cc b/test/jsonschema/jsonschema_transformer_test.cc index 90feacd03..f4e31903f 100644 --- a/test/jsonschema/jsonschema_transformer_test.cc +++ b/test/jsonschema/jsonschema_transformer_test.cc @@ -540,9 +540,10 @@ TEST(JSONSchema_transformer, check_throw_if_no_dialect_invalid_default) { "qux": "xxx" })JSON"); - EXPECT_THROW(bundle.check(document, sourcemeta::core::schema_official_walker, - sourcemeta::core::schema_official_resolver, nullptr, - "https://example.com/invalid"), + EXPECT_THROW((void)bundle.check(document, + sourcemeta::core::schema_official_walker, + sourcemeta::core::schema_official_resolver, + nullptr, "https://example.com/invalid"), sourcemeta::core::SchemaResolutionError); } From dace288ad534925d7d875fa61435fe3f63eb52bf Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 18:27:31 +0530 Subject: [PATCH 17/27] remove verbose steps Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2cde26ce..6e80be825 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,13 +169,6 @@ jobs: - run: cmake --version - name: Install llvm run: sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" - # - name: Set PATH - # run: echo "/opt/homebrew/opt/llvm/bin:$PATH" >> "$GITHUB_PATH" - - name: Debug Environment - run: | - echo "PATH: $PATH" - echo "SHELL: $SHELL" - shell: bash - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release @@ -185,6 +178,4 @@ jobs: -DBUILD_SHARED_LIBS:BOOL=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON -DSOURCEMETA_CORE_CLANG_TIDY:BOOL=ON - shell: bash - run: cmake --build ./build --config Release - shell: bash From e1203af10c266fa2d8911af15c8c165c987dff56 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 18:58:18 +0530 Subject: [PATCH 18/27] use clang compiler Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e80be825..c98d0e4e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,6 +164,9 @@ jobs: clang-tidy: runs-on: ubuntu-latest + env: + CC: clang + CXX: clang++ steps: - uses: actions/checkout@v4 - run: cmake --version From eef5869078a35a574a71e7a6af4b6d2ec59d67fe Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Wed, 2 Jul 2025 19:02:07 +0530 Subject: [PATCH 19/27] re-enable the ci jobs Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 114 +++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c98d0e4e6..7c8f23d6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,63 +21,63 @@ jobs: type: static shell: sh benchmark: macos/llvm - # - os: macos-latest - # cc: clang - # cxx: clang++ - # type: shared - # shell: sh - # - os: macos-latest - # cc: gcc-13 - # cxx: g++-13 - # type: static - # shell: sh - # benchmark: macos/gcc - # - os: ubuntu-latest - # cc: clang - # cxx: clang++ - # type: static - # shell: sh - # benchmark: linux/llvm - # - os: ubuntu-latest - # cc: gcc - # cxx: g++ - # type: static - # shell: sh - # benchmark: linux/gcc - # - os: ubuntu-latest - # cc: clang - # cxx: clang++ - # type: shared - # shell: sh - # - os: ubuntu-latest - # cc: gcc - # cxx: g++ - # type: shared - # shell: sh - # - os: windows-latest - # type: static - # shell: pwsh - # benchmark: windows/msvc - # - os: windows-latest - # type: shared - # shell: pwsh - # - os: windows-latest - # type: static - # shell: msys2 {0} - # - # # Sanitizers - # - os: ubuntu-latest - # cc: clang - # cxx: clang++ - # type: static - # shell: sh - # options: -DSOURCEMETA_CORE_ADDRESS_SANITIZER:BOOL=ON - # - os: ubuntu-latest - # cc: clang - # cxx: clang++ - # type: static - # shell: sh - # options: -DSOURCEMETA_CORE_UNDEFINED_SANITIZER:BOOL=ON + - os: macos-latest + cc: clang + cxx: clang++ + type: shared + shell: sh + - os: macos-latest + cc: gcc-13 + cxx: g++-13 + type: static + shell: sh + benchmark: macos/gcc + - os: ubuntu-latest + cc: clang + cxx: clang++ + type: static + shell: sh + benchmark: linux/llvm + - os: ubuntu-latest + cc: gcc + cxx: g++ + type: static + shell: sh + benchmark: linux/gcc + - os: ubuntu-latest + cc: clang + cxx: clang++ + type: shared + shell: sh + - os: ubuntu-latest + cc: gcc + cxx: g++ + type: shared + shell: sh + - os: windows-latest + type: static + shell: pwsh + benchmark: windows/msvc + - os: windows-latest + type: shared + shell: pwsh + - os: windows-latest + type: static + shell: msys2 {0} + + # Sanitizers + - os: ubuntu-latest + cc: clang + cxx: clang++ + type: static + shell: sh + options: -DSOURCEMETA_CORE_ADDRESS_SANITIZER:BOOL=ON + - os: ubuntu-latest + cc: clang + cxx: clang++ + type: static + shell: sh + options: -DSOURCEMETA_CORE_UNDEFINED_SANITIZER:BOOL=ON defaults: run: From cbd24f885bb94af6a1cd1466fc504df7d3d3207d Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Fri, 4 Jul 2025 16:00:09 +0530 Subject: [PATCH 20/27] Update cmake/common/targets/clang-tidy.cmake Co-authored-by: Juan Cruz Viotti Signed-off-by: Balakrishna Avulapati --- cmake/common/targets/clang-tidy.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/common/targets/clang-tidy.cmake b/cmake/common/targets/clang-tidy.cmake index 3f7956c60..6b7ddb229 100644 --- a/cmake/common/targets/clang-tidy.cmake +++ b/cmake/common/targets/clang-tidy.cmake @@ -1,6 +1,6 @@ function(sourcemeta_enable_clang_tidy) find_program(CLANG_TIDY_BIN NAMES clang-tidy) - set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) endfunction() function(sourcemeta_disable_clang_tidy) From bc7cdda98c7fa4f3fab529d8fae19e611a1829d1 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Fri, 4 Jul 2025 16:04:53 +0530 Subject: [PATCH 21/27] install llvm via ubuntu packages Signed-off-by: Balakrishna Avulapati --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c8f23d6f..95fab6b00 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -171,7 +171,7 @@ jobs: - uses: actions/checkout@v4 - run: cmake --version - name: Install llvm - run: sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" + run: sudo apt update && sudo apt install llvm - run: > cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release From 5a00ecac6c169d7aa6d502378253652c2ca49cdd Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Fri, 4 Jul 2025 16:08:29 +0530 Subject: [PATCH 22/27] make clang-tidy required on ci job Signed-off-by: Balakrishna Avulapati --- cmake/common/targets/clang-tidy.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/common/targets/clang-tidy.cmake b/cmake/common/targets/clang-tidy.cmake index 6b7ddb229..1305ebee1 100644 --- a/cmake/common/targets/clang-tidy.cmake +++ b/cmake/common/targets/clang-tidy.cmake @@ -1,5 +1,5 @@ function(sourcemeta_enable_clang_tidy) - find_program(CLANG_TIDY_BIN NAMES clang-tidy) + find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED) set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) endfunction() From e9369fe0083f7e34186a09759973d9cd5bfbc641 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Fri, 4 Jul 2025 16:19:12 +0530 Subject: [PATCH 23/27] Error out if clang-tidy is invoked without clang tool chain Signed-off-by: Balakrishna Avulapati --- cmake/common/targets/clang-tidy.cmake | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/common/targets/clang-tidy.cmake b/cmake/common/targets/clang-tidy.cmake index 1305ebee1..45185aa8c 100644 --- a/cmake/common/targets/clang-tidy.cmake +++ b/cmake/common/targets/clang-tidy.cmake @@ -1,6 +1,11 @@ function(sourcemeta_enable_clang_tidy) - find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED) - set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED) + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) + else() + message(FATAL_ERROR "Incompatible compiler toolchain. Clang-tidy is only tested to be working with clang toolchain") + endif() + endfunction() function(sourcemeta_disable_clang_tidy) From 847cea1a1a8c11ae118cbb3bf8e7d8953184f9aa Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Tue, 8 Jul 2025 12:35:22 +0530 Subject: [PATCH 24/27] enable clang-tidy at target level Signed-off-by: Balakrishna Avulapati --- CMakeLists.txt | 4 +--- cmake/common/targets/clang-tidy.cmake | 10 +++------- cmake/common/targets/library.cmake | 9 ++++++++- src/core/uuid/CMakeLists.txt | 13 ++++++++++++- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e682eb243..06e5b2240 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ if(PROJECT_IS_TOP_LEVEL) endif() if(SOURCEMETA_CORE_CLANG_TIDY) - sourcemeta_enable_clang_tidy() + sourcemeta_find_clang_tidy() endif() # TODO: Turn this into a re-usable utility CMake function @@ -122,8 +122,6 @@ if(PROJECT_IS_TOP_LEVEL) test/*.h test/*.cc) endif() -sourcemeta_disable_clang_tidy() - # Testing if(SOURCEMETA_CORE_CONTRIB_GOOGLETEST OR SOURCEMETA_CORE_TESTS) diff --git a/cmake/common/targets/clang-tidy.cmake b/cmake/common/targets/clang-tidy.cmake index 45185aa8c..96d7137fe 100644 --- a/cmake/common/targets/clang-tidy.cmake +++ b/cmake/common/targets/clang-tidy.cmake @@ -1,13 +1,9 @@ -function(sourcemeta_enable_clang_tidy) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +function(sourcemeta_find_clang_tidy) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED) - set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) + set(SOURCEMETA_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) else() message(FATAL_ERROR "Incompatible compiler toolchain. Clang-tidy is only tested to be working with clang toolchain") endif() endfunction() - -function(sourcemeta_disable_clang_tidy) - unset(CMAKE_CXX_CLANG_TIDY PARENT_SCOPE) -endfunction() diff --git a/cmake/common/targets/library.cmake b/cmake/common/targets/library.cmake index e2f2ebe60..e5b0957d1 100644 --- a/cmake/common/targets/library.cmake +++ b/cmake/common/targets/library.cmake @@ -1,6 +1,6 @@ function(sourcemeta_library) cmake_parse_arguments(SOURCEMETA_LIBRARY "" - "NAMESPACE;PROJECT;NAME;VARIANT" "PRIVATE_HEADERS;SOURCES" ${ARGN}) + "NAMESPACE;PROJECT;NAME;VARIANT" "PRIVATE_HEADERS;SOURCES;CLANG_TIDY" ${ARGN}) if(NOT SOURCEMETA_LIBRARY_PROJECT) message(FATAL_ERROR "You must pass the project name using the PROJECT option") @@ -115,6 +115,13 @@ function(sourcemeta_library) target_include_directories(${TARGET_NAME} PUBLIC "$") endif() + + if(SOURCEMETA_LIBRARY_CLANG_TIDY) + message(STATUS "setting CXX_CLANG_TIDY target property to ${SOURCEMETA_LIBRARY_CLANG_TIDY} on ${TARGET_NAME}") + set_target_properties(${TARGET_NAME} + PROPERTIES + CXX_CLANG_TIDY "${SOURCEMETA_LIBRARY_CLANG_TIDY}") + endif() endfunction() function(sourcemeta_library_install) diff --git a/src/core/uuid/CMakeLists.txt b/src/core/uuid/CMakeLists.txt index 324b05a72..550a41ae1 100644 --- a/src/core/uuid/CMakeLists.txt +++ b/src/core/uuid/CMakeLists.txt @@ -1,4 +1,15 @@ -sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME uuid SOURCES uuid.cc) +if(SOURCEMETA_CXX_CLANG_TIDY) + sourcemeta_library(NAMESPACE sourcemeta + PROJECT core + NAME uuid + SOURCES uuid.cc + CLANG_TIDY "${SOURCEMETA_CXX_CLANG_TIDY}") +else() + sourcemeta_library(NAMESPACE sourcemeta + PROJECT core + NAME uuid + SOURCES uuid.cc) +endif() if(SOURCEMETA_CORE_INSTALL) sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME uuid) From dea5f3c10dd61e1f6a2cd5153d0f80c48619d377 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Tue, 8 Jul 2025 12:37:18 +0530 Subject: [PATCH 25/27] Enable clang-tidy modernize-* checks Signed-off-by: Balakrishna Avulapati --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 5cfe08f36..faf7bcf01 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -2,7 +2,7 @@ # See https://clang.llvm.org/extra/clang-tidy/index.html # First disable all default checks (with -*) Checks: '-*, - modernize-use-nodiscard' + modernize-*' # TODO(bavulapati): iterate through the rules and enable them incrementally inorder to send smaller PRs # bugprone-*,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-bugprone-empty-catch, # clang-analyzer-*, From 26d0bbc502faf17dba5e8cae68ce55bd82176ab3 Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Tue, 8 Jul 2025 13:41:01 +0530 Subject: [PATCH 26/27] pass header-filter as a cmake function parameter Signed-off-by: Balakrishna Avulapati --- CMakeLists.txt | 2 +- cmake/common/targets/clang-tidy.cmake | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ec8d266e..4e91f8c34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(PROJECT_IS_TOP_LEVEL) endif() if(SOURCEMETA_CORE_CLANG_TIDY) - sourcemeta_find_clang_tidy() + sourcemeta_set_clang_tidy_config(HEADER_FILTER "${PROJECT_SOURCE_DIR}/src/*") endif() # TODO: Turn this into a re-usable utility CMake function diff --git a/cmake/common/targets/clang-tidy.cmake b/cmake/common/targets/clang-tidy.cmake index 96d7137fe..958c4e139 100644 --- a/cmake/common/targets/clang-tidy.cmake +++ b/cmake/common/targets/clang-tidy.cmake @@ -1,9 +1,18 @@ function(sourcemeta_find_clang_tidy) if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED) - set(SOURCEMETA_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE) else() message(FATAL_ERROR "Incompatible compiler toolchain. Clang-tidy is only tested to be working with clang toolchain") endif() endfunction() + +function(sourcemeta_set_clang_tidy_config) + cmake_parse_arguments(SOURCEMETA_SET_CLANG_TIDY_CONFIG "" "HEADER_FILTER" "" ${ARGN}) + if(NOT SOURCEMETA_SET_CLANG_TIDY_CONFIG_HEADER_FILTER) + message(FATAL_ERROR "HEADER_FILTER is required for clang-tidy.") + endif() + + sourcemeta_find_clang_tidy() + set(SOURCEMETA_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${SOURCEMETA_SET_CLANG_TIDY_CONFIG_HEADER_FILTER}" PARENT_SCOPE) +endfunction() From 0a76a8ee8ae744561bf0c2c7977b555c570fdb5c Mon Sep 17 00:00:00 2001 From: Balakrishna Avulapati Date: Tue, 8 Jul 2025 16:29:40 +0530 Subject: [PATCH 27/27] move .clang-format config to root directory Signed-off-by: Balakrishna Avulapati --- cmake/common/targets/clang-format.config => .clang-format | 0 cmake/common/targets/clang-format.cmake | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename cmake/common/targets/clang-format.config => .clang-format (100%) diff --git a/cmake/common/targets/clang-format.config b/.clang-format similarity index 100% rename from cmake/common/targets/clang-format.config rename to .clang-format diff --git a/cmake/common/targets/clang-format.cmake b/cmake/common/targets/clang-format.cmake index 55fbb6cdc..5aee2edea 100644 --- a/cmake/common/targets/clang-format.cmake +++ b/cmake/common/targets/clang-format.cmake @@ -101,7 +101,7 @@ function(sourcemeta_target_clang_format) file(GLOB_RECURSE SOURCEMETA_TARGET_CLANG_FORMAT_FILES ${SOURCEMETA_TARGET_CLANG_FORMAT_SOURCES}) - set(CLANG_FORMAT_CONFIG "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-format.config") + set(CLANG_FORMAT_CONFIG "${PROJECT_SOURCE_DIR}/.clang-format") if(CMAKE_SYSTEM_NAME STREQUAL "MSYS") # Because `clang-format` is typically a Windows `.exe`, transform the path accordingly execute_process(COMMAND cygpath -w "${CLANG_FORMAT_CONFIG}"