From d6a08f7db3f9fcde1ffc6b894d9f497e033885f2 Mon Sep 17 00:00:00 2001 From: m-aXimilian <56168660+m-aXimilian@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:00:09 +0200 Subject: [PATCH] Atomic woes, megalinter, and batches (#13) * fix libCZI dependency w/ atomic woes * add megalinter * fix megalinter triggers * use correct flavor * build status in readme * clang-format * megalinter batch * disable suggestions set libCZI options before fetching Set compile definitions for static libCZI --- .github/workflows/mega-linter.yml | 204 +++++++++++++++++++++++++ .gitignore | 3 +- .mega-linter.yml | 28 ++++ Readme.org | 3 + cmake/libCZI.cmake | 14 +- lib/imaging/CMakeLists.txt | 2 + lib/imaging/IPixelariumImage.hpp | 2 +- lib/imaging/PixelariumImageFactory.cpp | 1 - lib/imaging/impl/PixelariumCzi.cpp | 1 - lib/imaging/impl/PixelariumCzi.hpp | 6 +- lib/rendering/RenderImageManager.hpp | 2 - 11 files changed, 251 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/mega-linter.yml create mode 100644 .mega-linter.yml diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml new file mode 100644 index 0000000..04ffa2e --- /dev/null +++ b/.github/workflows/mega-linter.yml @@ -0,0 +1,204 @@ +# MegaLinter GitHub Action configuration file +# More info at https://megalinter.io +--- +name: MegaLinter + +# Trigger mega-linter at every push. Action will also be visible from +# Pull Requests to main +on: + # Comment this line to trigger action only on pull-requests + # (not recommended if you don't pay for GH Actions) + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +# Comment env block if you do not want to apply fixes +env: + # Apply linter fixes configuration + # + # When active, APPLY_FIXES must also be defined as environment variable + # (in github/workflows/mega-linter.yml or other CI tool) + APPLY_FIXES: none + + # Decide which event triggers application of fixes in a commit or a PR + # (pull_request, push, all) + APPLY_FIXES_EVENT: pull_request + + # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) + # or posted in a PR (pull_request) + APPLY_FIXES_MODE: commit + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + megalinter: + name: MegaLinter + runs-on: ubuntu-latest + + # Give the default GITHUB_TOKEN write permission to commit and push, comment + # issues, and post new Pull Requests; remove the ones you do not need + permissions: + contents: write + issues: write + pull-requests: write + + steps: + # Git Checkout + - name: Checkout Code + uses: actions/checkout@v5 + with: + token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + + # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to + # improve performance + fetch-depth: 0 + + # MegaLinter + - name: MegaLinter + + # You can override MegaLinter flavor used to have faster performances + # More info at https://megalinter.io/latest/flavors/ + uses: oxsecurity/megalinter/flavors/c_cpp@v9.1.0 + + id: ml + + # All available variables are described in documentation + # https://megalinter.io/latest/config-file/ + env: + # Validates all source when push on main, else just the git diff with + # main. Override with true if you always want to lint all sources + # + # To validate the entire codebase, set to: + # VALIDATE_ALL_CODEBASE: true + # + # To validate only diff with main, set to: + # VALIDATE_ALL_CODEBASE: >- + # ${{ + # github.event_name == 'push' && + # github.ref == 'refs/heads/main' + # }} + VALIDATE_ALL_CODEBASE: true + + # Disable LLM Advisor for bot PRs (dependabot, renovate, etc.) + LLM_ADVISOR_ENABLED: >- + ${{ + github.event_name != 'pull_request' || + (github.event.pull_request.user.login != 'dependabot[bot]' && + github.event.pull_request.user.login != 'renovate[bot]' && + github.event.pull_request.user.login != 'github-actions[bot]' && + !startsWith(github.event.pull_request.user.login, 'dependabot') && + !startsWith(github.event.pull_request.user.login, 'renovate')) + }} + + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Uncomment to use ApiReporter (Grafana) + # API_REPORTER: true + # API_REPORTER_URL: ${{ secrets.API_REPORTER_URL }} + # API_REPORTER_BASIC_AUTH_USERNAME: ${{ secrets.API_REPORTER_BASIC_AUTH_USERNAME }} + # API_REPORTER_BASIC_AUTH_PASSWORD: ${{ secrets.API_REPORTER_BASIC_AUTH_PASSWORD }} + # API_REPORTER_METRICS_URL: ${{ secrets.API_REPORTER_METRICS_URL }} + # API_REPORTER_METRICS_BASIC_AUTH_USERNAME: ${{ secrets.API_REPORTER_METRICS_BASIC_AUTH_USERNAME }} + # API_REPORTER_METRICS_BASIC_AUTH_PASSWORD: ${{ secrets.API_REPORTER_METRICS_BASIC_AUTH_PASSWORD }} + # API_REPORTER_DEBUG: false + + # ADD YOUR CUSTOM ENV VARIABLES HERE TO OVERRIDE VALUES OF + # .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY + + # Upload MegaLinter artifacts + - name: Archive production artifacts + uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: MegaLinter reports + include-hidden-files: "true" + path: | + megalinter-reports + mega-linter.log + + # Create pull request if applicable + # (for now works only on PR from same repository, not from forks) + - name: Create Pull Request with applied fixes + uses: peter-evans/create-pull-request@v7 + id: cpr + if: >- + steps.ml.outputs.has_updated_sources == 1 && + ( + env.APPLY_FIXES_EVENT == 'all' || + env.APPLY_FIXES_EVENT == github.event_name + ) && + env.APPLY_FIXES_MODE == 'pull_request' && + ( + github.event_name == 'push' || + github.event.pull_request.head.repo.full_name == github.repository + ) && + !contains(github.event.head_commit.message, 'skip fix') + with: + token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + commit-message: "[MegaLinter] Apply linters automatic fixes" + title: "[MegaLinter] Apply linters automatic fixes" + labels: bot + + - name: Create PR output + if: >- + steps.ml.outputs.has_updated_sources == 1 && + ( + env.APPLY_FIXES_EVENT == 'all' || + env.APPLY_FIXES_EVENT == github.event_name + ) && + env.APPLY_FIXES_MODE == 'pull_request' && + ( + github.event_name == 'push' || + github.event.pull_request.head.repo.full_name == github.repository + ) && + !contains(github.event.head_commit.message, 'skip fix') + run: | + echo "PR Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "PR URL - ${{ steps.cpr.outputs.pull-request-url }}" + + # Push new commit if applicable + # (for now works only on PR from same repository, not from forks) + - name: Prepare commit + if: >- + steps.ml.outputs.has_updated_sources == 1 && + ( + env.APPLY_FIXES_EVENT == 'all' || + env.APPLY_FIXES_EVENT == github.event_name + ) && + env.APPLY_FIXES_MODE == 'commit' && + github.ref != 'refs/heads/main' && + ( + github.event_name == 'push' || + github.event.pull_request.head.repo.full_name == github.repository + ) && + !contains(github.event.head_commit.message, 'skip fix') + run: sudo chown -Rc $UID .git/ + + - name: Commit and push applied linter fixes + uses: stefanzweifel/git-auto-commit-action@v6 + if: >- + steps.ml.outputs.has_updated_sources == 1 && + ( + env.APPLY_FIXES_EVENT == 'all' || + env.APPLY_FIXES_EVENT == github.event_name + ) && + env.APPLY_FIXES_MODE == 'commit' && + github.ref != 'refs/heads/main' && + ( + github.event_name == 'push' || + github.event.pull_request.head.repo.full_name == github.repository + ) && + !contains(github.event.head_commit.message, 'skip fix') + with: + branch: >- + ${{ + github.event.pull_request.head.ref || + github.head_ref || + github.ref + }} + commit_message: "[MegaLinter] Apply linters fixes" + commit_user_name: megalinter-bot + commit_user_email: 129584137+megalinter-bot@users.noreply.github.com diff --git a/.gitignore b/.gitignore index 93f8500..e3592d6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ build/ out/ .vs/ .cache/ -*~ \ No newline at end of file +*~ +megalinter-reports/ diff --git a/.mega-linter.yml b/.mega-linter.yml new file mode 100644 index 0000000..51d60cb --- /dev/null +++ b/.mega-linter.yml @@ -0,0 +1,28 @@ +# Configuration file for MegaLinter +# +# See all available variables at https://megalinter.io/latest/config-file/ and in +# linters documentation + +# all, none, or list of linter keys +APPLY_FIXES: none + +# If you use ENABLE variable, all other languages/formats/tooling-formats will +# be disabled by default +# ENABLE: + +# If you use ENABLE_LINTERS variable, all other linters will be disabled by +# default +ENABLE_LINTERS: + - SPELL + - CPP_CLANG_FORMAT + +# DISABLE: + # - COPYPASTE # Uncomment to disable checks of excessive copy-pastes + # - SPELL # Uncomment to disable checks of spelling mistakes + +SHOW_ELAPSED_TIME: true + +# Uncomment if you want MegaLinter to detect errors but not block CI to pass +DISABLE_ERRORS: true + +FLAVOR_SUGGESTIONS: false diff --git a/Readme.org b/Readme.org index 43e9eb0..62d4105 100644 --- a/Readme.org +++ b/Readme.org @@ -6,6 +6,9 @@ #+author: Maximilian Kueffner #+exclude_tags: noexport +[[https://github.com/m-aXimilian/pixelarium/actions/workflows/ci-workflow.yml][file:https://github.com/m-aXimilian/pixelarium/actions/workflows/ci-workflow.yml/badge.svg]] +[[https://github.com/m-aXimilian/pixelarium/actions/workflows/mega-linter.yml][file:https://github.com/m-aXimilian/pixelarium/actions/workflows/mega-linter.yml/badge.svg]] + * Synopsis Pixelarium strives to be a batteries-included visualizer application used in conjunction with an externally implemented and linked arbitrary functionality. diff --git a/cmake/libCZI.cmake b/cmake/libCZI.cmake index a593fa3..46922f0 100644 --- a/cmake/libCZI.cmake +++ b/cmake/libCZI.cmake @@ -8,13 +8,15 @@ FetchContent_Declare( if(NOT libCZI_POPULATED) message(STATUS "Fetching libCZI") - FetchContent_MakeAvailable(libCZI) - set(LIBCZI_BUILD_CZICMD OFF CACHE BOOL "" FORCE) - set(LIBCZI_BUILD_DYNLIB OFF CACHE BOOL "" FORCE) - set(LIBCZI_BUILD_UNITTESTS OFF CACHE BOOL "" FORCE) - set(LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_RAPIDJSON OFF CACHE BOOL "" FORCE) - set(LIBCZI_DO_NOT_SET_MSVC_RUNTIME_LIBRARY ON CACHE BOOL "" FORCE) + set(LIBCZI_BUILD_CZICMD OFF CACHE BOOL "Don't build commandline libCZI." FORCE) + set(LIBCZI_BUILD_DYNLIB OFF CACHE BOOL "Don't build libCZI as a shared library." FORCE) + set(LIBCZI_BUILD_UNITTESTS OFF CACHE BOOL "Don't build libCZI unit tests." FORCE) + set(LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_RAPIDJSON OFF CACHE BOOL "Use internal rapidjson." FORCE) + set(LIBCZI_DO_NOT_SET_MSVC_RUNTIME_LIBRARY ON CACHE BOOL "Consumer sets the runtime." FORCE) + set(ADDITIONAL_LIBS_REQUIRED_FOR_ATOMIC "" CACHE STRING "Additional atomic libs included." FORCE) + + FetchContent_MakeAvailable(libCZI) endif() FetchContent_GetProperties(libCZI) diff --git a/lib/imaging/CMakeLists.txt b/lib/imaging/CMakeLists.txt index 324bd50..b109bd3 100644 --- a/lib/imaging/CMakeLists.txt +++ b/lib/imaging/CMakeLists.txt @@ -22,6 +22,8 @@ set(IMAGELIBLIBNAME pixelariumimagelib) add_library(${IMAGELIBLIBNAME} STATIC ${IMAGELIBSRC}) +target_compile_definitions(${IMAGELIBLIBNAME} PUBLIC _LIBCZISTATICLIB) + target_link_libraries(${IMAGELIBLIBNAME} PUBLIC ${OpenCV_LIBS} PUBLIC pixelariumutilslib diff --git a/lib/imaging/IPixelariumImage.hpp b/lib/imaging/IPixelariumImage.hpp index 2d5bd95..e5b8727 100644 --- a/lib/imaging/IPixelariumImage.hpp +++ b/lib/imaging/IPixelariumImage.hpp @@ -46,7 +46,7 @@ class IPixelariumImage virtual std::unique_ptr TryGetImage() = 0; /// @brief Attempts to retrieve the image. - /// @param query The query object defining the images to retrieve./// + /// @param query The query object defining the images to retrieve. /// @return A unique pointer to a Mat object containing the image data, /// or nullptr if the image is not found or cannot be retrieved. virtual std::unique_ptr TryGetImage(const IImageQuery& query) = 0; diff --git a/lib/imaging/PixelariumImageFactory.cpp b/lib/imaging/PixelariumImageFactory.cpp index 84b6c2c..8b2d5c0 100644 --- a/lib/imaging/PixelariumImageFactory.cpp +++ b/lib/imaging/PixelariumImageFactory.cpp @@ -7,7 +7,6 @@ #include "impl/PixelariumJpg.hpp" #include "impl/PixelariumPng.hpp" - /*static*/ std::unique_ptr pixelarium::imaging::PixelariumImageFactory::CreateImage(const std::string& uri, const Log& log) { diff --git a/lib/imaging/impl/PixelariumCzi.cpp b/lib/imaging/impl/PixelariumCzi.cpp index 1de2717..659ed8f 100644 --- a/lib/imaging/impl/PixelariumCzi.cpp +++ b/lib/imaging/impl/PixelariumCzi.cpp @@ -29,7 +29,6 @@ bool comp_blockinfo_params(const pixelarium::imaging::CziParams& params, const l return res; } - constexpr int try_get_index_match(const pixelarium::imaging::CziParams& params, libCZI::ICZIReader& reader) { int index{-1}; diff --git a/lib/imaging/impl/PixelariumCzi.hpp b/lib/imaging/impl/PixelariumCzi.hpp index 599f394..75dd899 100644 --- a/lib/imaging/impl/PixelariumCzi.hpp +++ b/lib/imaging/impl/PixelariumCzi.hpp @@ -4,8 +4,8 @@ #include #include "../IPixelariumImage.hpp" -#include "utilities/ILog.hpp" #include "libCZI.h" +#include "utilities/ILog.hpp" namespace pixelarium::imaging { @@ -21,12 +21,12 @@ struct CziParams : public IImageQuery class PixelariumCzi : public IPixelariumImage { using Log = pixelarium::utils::log::ILog; + public: explicit PixelariumCzi(const std::string& uri, const Log& log); ~PixelariumCzi() { - if (this->czi_reader_) - this->czi_reader_->Close(); + if (this->czi_reader_) this->czi_reader_->Close(); } // IPixelariumImage member implementations diff --git a/lib/rendering/RenderImageManager.hpp b/lib/rendering/RenderImageManager.hpp index c72f099..296f5af 100644 --- a/lib/rendering/RenderImageManager.hpp +++ b/lib/rendering/RenderImageManager.hpp @@ -5,7 +5,6 @@ #include #include "ImageViewFactory.hpp" -#include "PixelariumImageViewDefault.hpp" #include "rendering/IPixelariumImageView.hpp" #include "resources/resource.hpp" #include "utilities/ILog.hpp" @@ -23,7 +22,6 @@ struct RenderImageStateWrapper const bool* show_state; }; - /// @brief Manage instances of IPixelariumImageView. /// /// This class is used to keep track of what must be rendered.