From 053e01ec68509f3c43d3d1b93469a006cbb62e7b Mon Sep 17 00:00:00 2001 From: Pasukhin Dmitry Date: Sun, 2 Feb 2025 16:35:20 +0100 Subject: [PATCH] Testing - Inspector building on GH #329 Add GitHub Actions for TInspector build and clang-format check Reorganize QT search to work with native Linux packages Reorganize build-and-test workflow to have actions --- .github/actions/build-tinspector/action.yml | 90 +++++++++++++++++++ .github/actions/clang-format-check/action.yml | 76 ++++++++++++++++ .../build-and-test-multiplatform.yml | 52 +++++++++++ .github/workflows/clang-format-check.yml | 84 ----------------- .gitignore | 3 +- adm/cmake/qt.cmake | 35 ++++---- tools/TInspector/TInspector_Communicator.cxx | 2 +- .../TInspector/TInspector_OpenFileDialog.cxx | 2 + tools/TreeModel/TreeModel_Tools.cxx | 8 +- 9 files changed, 248 insertions(+), 104 deletions(-) create mode 100644 .github/actions/build-tinspector/action.yml create mode 100644 .github/actions/clang-format-check/action.yml delete mode 100644 .github/workflows/clang-format-check.yml diff --git a/.github/actions/build-tinspector/action.yml b/.github/actions/build-tinspector/action.yml new file mode 100644 index 0000000000..3a23506934 --- /dev/null +++ b/.github/actions/build-tinspector/action.yml @@ -0,0 +1,90 @@ +name: 'Build TInspector' +description: 'Build TInspector using OCCT installation as a separate job' + +inputs: + platform: + description: 'Build platform (windows/linux)' + required: true + install-artifact-name: + description: 'OCCT installation artifact name' + required: true + thirdparty_url: + description: 'URL to download 3rdparty dependencies' + required: false + default: 'https://github.com/Open-Cascade-SAS/OCCT/releases/download/V7_8_0/3rdparty-vc14-64.zip' + +runs: + using: "composite" + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.7 + + - name: Download OCCT installation + uses: actions/download-artifact@v4.1.7 + with: + name: ${{ inputs.install-artifact-name }} + path: occt-install + + - name: Install Windows dependencies + if: inputs.platform == 'windows' + shell: pwsh + run: | + Invoke-WebRequest -Uri ${{ inputs.thirdparty_url }} -OutFile 3rdparty-vc14-64.zip + Expand-Archive -Path 3rdparty-vc14-64.zip -DestinationPath . + Remove-Item 3rdparty-vc14-64.zip + + + - name: Install Linux dependencies + if: inputs.platform == 'linux' + shell: bash + run: sudo apt-get update && sudo apt-get install -y tcl-dev tk-dev cmake gcc g++ make libbtbb-dev libx11-dev libglu1-mesa-dev tcllib tcl-thread tcl libvtk9-dev libopenvr-dev libdraco-dev libfreeimage-dev libegl1-mesa-dev libgles2-mesa-dev libfreetype-dev qtbase5-dev qt5-qmake qtbase5-dev-tools qtdeclarative5-dev qttools5-dev qttools5-dev-tools + + - name: Configure TInspector - Windows + if: inputs.platform == 'windows' + shell: pwsh + run: | + cd tools + mkdir build + cd build + cmake -G "Visual Studio 17 2022" -A x64 ` + -D CMAKE_BUILD_TYPE=Release ` + -D BUILD_SHARED_LIBS=ON ` + -D 3RDPARTY_DIR=${{ github.workspace }}//3rdparty-vc14-64 ` + -D OpenCASCADE_DIR=${{ github.workspace }}/occt-install ` + -D INSTALL_DIR=${{ github.workspace }}/tools/install ` + .. + + - name: Configure TInspector - Linux + if: inputs.platform == 'linux' + shell: bash + run: | + cd tools + mkdir build + cd build + cmake -G "Unix Makefiles" \ + -D CMAKE_BUILD_TYPE=Release \ + -D BUILD_SHARED_LIBS=ON \ + -D OpenCASCADE_DIR=${{ github.workspace }}/occt-install \ + -D INSTALL_DIR=${{ github.workspace }}/tools/install \ + .. + + - name: Build TInspector - Windows + if: inputs.platform == 'windows' + shell: pwsh + run: | + cd tools/build + cmake --build . --config Release --target install + + - name: Build TInspector - Linux + if: inputs.platform == 'linux' + shell: bash + run: | + cd tools/build + make install -j$(nproc) + + - name: Upload TInspector installation + uses: actions/upload-artifact@v4.4.3 + with: + name: inspector-${{ inputs.platform }}-x64 + path: tools/install + retention-days: 7 diff --git a/.github/actions/clang-format-check/action.yml b/.github/actions/clang-format-check/action.yml new file mode 100644 index 0000000000..9f23090ccc --- /dev/null +++ b/.github/actions/clang-format-check/action.yml @@ -0,0 +1,76 @@ +name: 'Clang-Format Code Check' +description: 'Check code formatting of changed files using clang-format' +inputs: + base-ref: + description: 'Base reference to compare changes against' + required: true + default: 'master' + file-pattern: + description: 'Pattern to match files for formatting check' + required: false + default: '^(src|tools)/.*\.(cpp|hxx|cxx|lxx|h|pxx|hpp)$' + clang-format-version: + description: 'Required clang-format version' + required: false + default: '18.1.8' + +outputs: + has-changes: + description: 'Whether any files needed formatting' + value: ${{ steps.git-check.outputs.has_changes }} + +runs: + using: "composite" + steps: + - name: Check clang-format version + shell: pwsh + run: | + $version = clang-format --version + Write-Output "Detected clang-format version: $version" + $version | Select-String "${{ inputs.clang-format-version }}" >$null + if ($LASTEXITCODE -ne 0) { + echo "::error::Wrong clang-format version. Expected ${{ inputs.clang-format-version }}" + Write-Output "Error: Version mismatch - expected ${{ inputs.clang-format-version }}" + exit 1 + } + + - name: Get changed files + id: changed-files + shell: pwsh + run: | + $changedFiles = git diff --name-only origin/${{ inputs.base-ref }} HEAD | + Where-Object { $_ -match '${{ inputs.file-pattern }}' } + $changedFiles | Set-Content "changed_files.txt" + if ($changedFiles.Count -gt 0) { + echo "has_files=true" >> $env:GITHUB_OUTPUT + } + + - name: Check formatting + if: steps.changed-files.outputs.has_files == 'true' + shell: pwsh + run: | + $files = Get-Content "changed_files.txt" + $files | ForEach-Object -ThrottleLimit 8 -Parallel { + clang-format -i -style=file $_ + } + + - name: Check git status + id: git-check + if: steps.changed-files.outputs.has_files == 'true' + shell: pwsh + run: | + git diff > format.patch + if ((Get-Item format.patch).length -gt 0) { + echo "has_changes=true" >> $env:GITHUB_OUTPUT + } + + - name: Upload patch + if: steps.git-check.outputs.has_changes == 'true' + uses: actions/upload-artifact@v4 + with: + name: format-patch + path: format.patch + +branding: + icon: 'check-square' + color: 'green' diff --git a/.github/workflows/build-and-test-multiplatform.yml b/.github/workflows/build-and-test-multiplatform.yml index 06f88d26ae..7bc0eabf33 100644 --- a/.github/workflows/build-and-test-multiplatform.yml +++ b/.github/workflows/build-and-test-multiplatform.yml @@ -18,6 +18,28 @@ concurrency: cancel-in-progress: true jobs: + clang-format: + name: Check code formatting + runs-on: windows-2022 + + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.7 + with: + fetch-depth: 0 + + - name: Run clang-format check + uses: ./.github/actions/clang-format-check + with: + base-ref: ${{ github.event.pull_request.base.ref || 'master' }} + + - name: Fail if changes needed + if: steps.clang-format-check.outputs.has-changes == 'true' + shell: pwsh + run: | + echo "::error::Files need formatting. To fix: 1. Download format.patch 2. \"git apply format.patch\" 3. Commit and push" + exit 1 + prepare-and-build-windows-x64: name: Prepare and Build on Windows with MSVC (x64) runs-on: windows-2022 @@ -374,6 +396,36 @@ jobs: path: install retention-days: 7 + build-inspector-windows: + name: Build TInspector on Windows + needs: prepare-and-build-windows-x64 + runs-on: windows-2022 + + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.7 + + - name: Build TInspector + uses: ./.github/actions/build-tinspector + with: + platform: windows + install-artifact-name: install-windows-x64 + + build-inspector-linux: + name: Build TInspector on Linux + needs: prepare-and-build-linux-clang-x64 + runs-on: ubuntu-24.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.7 + + - name: Build TInspector + uses: ./.github/actions/build-tinspector + with: + platform: linux + install-artifact-name: install-linux-clang-x64 + test-windows-x64: name: Test on Windows (x64) runs-on: windows-2022 diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml deleted file mode 100644 index 475fb5dc8f..0000000000 --- a/.github/workflows/clang-format-check.yml +++ /dev/null @@ -1,84 +0,0 @@ -# This workflow checks the code formatting of changed files in a pull request using clang-format. -# It is triggered on pull requests to the master branch. -# The workflow verifies that the clang-format version matches 18.1.8, -# checks formatting of modified files, and if formatting issues are found, -# creates a patch file that can be applied to fix the formatting. - -name: Clang-Format Check - -on: - pull_request: - branches: - - '**' - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number }} - cancel-in-progress: true - -jobs: - format-check: - name: Check code formatting - runs-on: windows-2022 - - steps: - - name: Checkout repository - uses: actions/checkout@v4.1.7 - with: - fetch-depth: 0 - - - name: Check clang-format version - run: | - $version = clang-format --version - Write-Output "Detected clang-format version: $version" - $version | Select-String "18.1.8" >$null - if ($LASTEXITCODE -ne 0) { - echo "::error::Wrong clang-format version. Expected 18.1.8" - Write-Output "Error: Version mismatch - expected 18.1.8" - exit 1 - } - shell: pwsh - - - name: Get changed files - id: changed-files - run: | - $changedFiles = git diff --name-only origin/${{ github.base_ref }} HEAD | - Where-Object { $_ -match '^(src|tools)/' -and $_ -match '\.(cpp|hxx|cxx|lxx|h|pxx|hpp)$' } - $changedFiles | Set-Content "changed_files.txt" - if ($changedFiles.Count -gt 0) { - echo "has_files=true" >> $env:GITHUB_OUTPUT - } - shell: pwsh - - - name: Check formatting - id: check - if: steps.changed-files.outputs.has_files == 'true' - run: | - $files = Get-Content "changed_files.txt" - $files | ForEach-Object -ThrottleLimit 8 -Parallel { - clang-format -i -style=file $_ - } - shell: pwsh - - - name: Check git status - id: git-check - if: steps.changed-files.outputs.has_files == 'true' - run: | - git diff > format.patch - if ((Get-Item format.patch).length -gt 0) { - echo "has_changes=true" >> $env:GITHUB_OUTPUT - } - shell: pwsh - - - name: Upload patch - if: steps.git-check.outputs.has_changes == 'true' - uses: actions/upload-artifact@v4 - with: - name: format-patch - path: format.patch - - - name: Fail with instructions - if: steps.git-check.outputs.has_changes == 'true' - run: | - echo "::error::Files need formatting. To fix: 1. Download format.patch 2. "git apply format.patch" 3. Commit and push" - exit 1 - shell: pwsh diff --git a/.gitignore b/.gitignore index 444031ba34..5197534322 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,5 @@ win64 /libtool /stamp* /build* -/install +/install* +/tools/build* diff --git a/adm/cmake/qt.cmake b/adm/cmake/qt.cmake index 535e6a2038..a87b1db29d 100644 --- a/adm/cmake/qt.cmake +++ b/adm/cmake/qt.cmake @@ -3,37 +3,40 @@ # Qt is searched manually first (just determine root) message (STATUS "Processing Qt 3-rd party") +set (USE_QT_FROM_3RDPARTY_DIR TRUE) if (NOT DEFINED ${3RDPARTY_QT_DIR} AND ${3RDPARTY_QT_DIR} STREQUAL "") FIND_PRODUCT_DIR ("${3RDPARTY_DIR}" Qt 3RDPARTY_QT_DIR_NAME) if (NOT DEFINED ${3RDPARTY_QT_DIR_NAME} AND ${3RDPARTY_QT_DIR_NAME} STREQUAL "") set (3RDPARTY_QT_DIR "" CACHE PATH "The directory containing qt") - message (FATAL_ERROR "Could not find used third-party product: 3RDPARTY_QT_DIR") + set (USE_QT_FROM_3RDPARTY_DIR FALSE) + else() + # Combine directory name with absolute path and show in GUI + set (3RDPARTY_QT_DIR "${3RDPARTY_DIR}/${3RDPARTY_QT_DIR_NAME}" CACHE PATH "The directory containing Qt" FORCE) endif() - - # Combine directory name with absolute path and show in GUI - set (3RDPARTY_QT_DIR "${3RDPARTY_DIR}/${3RDPARTY_QT_DIR_NAME}" CACHE PATH "The directory containing Qt" FORCE) - message (STATUS "Info: Qt is used from folder: ${3RDPARTY_QT_DIR}") endif() -set (USED_3RDPARTY_QT_DIR "${3RDPARTY_QT_DIR}") - -# Now set CMAKE_PREFIX_PATH to point to local Qt installation. -# Without this setting find_package() will not work -set(CMAKE_PREFIX_PATH ${3RDPARTY_QT_DIR}) - -# Now we can apply standard CMake finder for Qt5. We do this mostly -# to have qt5_wrap_cpp() function available and Qt5_FOUND variable filled -find_package(Qt5 QUIET COMPONENTS Widgets Quick Xml PATHS ${3RDPARTY_QT_DIR} NO_DEFAULT_PATH) +if (${USE_QT_FROM_3RDPARTY_DIR}) + # Now set CMAKE_PREFIX_PATH to point to local Qt installation. + # Without this setting find_package() will not work + set(CMAKE_PREFIX_PATH ${3RDPARTY_QT_DIR}) + + # Now we can apply standard CMake finder for Qt5. We do this mostly + # to have qt5_wrap_cpp() function available and Qt5_FOUND variable filled + find_package(Qt5 QUIET COMPONENTS Widgets Quick Xml PATHS ${3RDPARTY_QT_DIR} NO_DEFAULT_PATH) +else() + find_package(Qt5 QUIET COMPONENTS Widgets Quick Xml) +endif() if (NOT ${Qt5_FOUND}) # Now we can apply standard CMake finder for Qt. We do this mostly # to have qt4_wrap_cpp() function available find_package(Qt4) - #message (STATUS "Qt4 cmake configuration") else() - #message (STATUS "Qt5 cmake configuration") + set (3RDPARTY_QT_DIR ${Qt5_DIR} CACHE PATH "The directory containing Qt" FORCE) endif() +set (USED_3RDPARTY_QT_DIR "${3RDPARTY_QT_DIR}") + if (3RDPARTY_QT_DIR OR EXISTS "${3RDPARTY_QT_DIR}") list (APPEND 3RDPARTY_DLL_DIRS "${3RDPARTY_QT_DIR}/bin") else() diff --git a/tools/TInspector/TInspector_Communicator.cxx b/tools/TInspector/TInspector_Communicator.cxx index d1970fab5f..39d8e5961b 100644 --- a/tools/TInspector/TInspector_Communicator.cxx +++ b/tools/TInspector/TInspector_Communicator.cxx @@ -69,7 +69,7 @@ Standard_Boolean TInspector_Communicator::PluginsDir(TCollection_AsciiString& th #else ':'; #endif - for (int i = 1; !aPathValue.IsEmpty(); i++) + while (!aPathValue.IsEmpty()) { Standard_Integer aSepIndex = aPathValue.FirstLocationInSet(aPathSep, 1, aPathValue.Length()); if (aSepIndex <= 1) diff --git a/tools/TInspector/TInspector_OpenFileDialog.cxx b/tools/TInspector/TInspector_OpenFileDialog.cxx index bf943f87be..fbd88ed567 100644 --- a/tools/TInspector/TInspector_OpenFileDialog.cxx +++ b/tools/TInspector/TInspector_OpenFileDialog.cxx @@ -155,7 +155,9 @@ void TInspector_OpenFileDialog::GetPluginRecentlyOpenedFiles( { if (!anItemIt.Key().IsEqual("recently_opened_files")) continue; +#include theFileNames = QString(anItemIt.Value().ToCString()).split(";", QString::SkipEmptyParts); +#include if (theFileNames.size() > RECENT_FILES_CACHE_SIZE) for (int i = 0; i < theFileNames.size() - RECENT_FILES_CACHE_SIZE; i++) theFileNames.removeFirst(); diff --git a/tools/TreeModel/TreeModel_Tools.cxx b/tools/TreeModel/TreeModel_Tools.cxx index 037793ec46..64a32e9309 100644 --- a/tools/TreeModel/TreeModel_Tools.cxx +++ b/tools/TreeModel/TreeModel_Tools.cxx @@ -59,8 +59,10 @@ QByteArray TreeModel_Tools::ToByteArray(const QString& theValue) if (!theValue.startsWith("@ByteArray[") || !theValue.endsWith(']')) return aStateArray; - QString aValue = theValue.mid(11, theValue.size() - 12); - QStringList lst = aValue.split(QRegExp("[\\s|,]"), QString::SkipEmptyParts); + QString aValue = theValue.mid(11, theValue.size() - 12); +#include + QStringList lst = aValue.split(QRegExp("[\\s|,]"), QString::SkipEmptyParts); +#include for (QStringList::ConstIterator aByteId = lst.begin(); aByteId != lst.end(); ++aByteId) { int aBase = 10; @@ -177,7 +179,9 @@ int TreeModel_Tools::GetTextWidth(const QString& theText, QObject*) int aTextMargin = 10; QFontMetrics aFontMetrics(QApplication::font()); QRect aBoundingRect = aFontMetrics.boundingRect(theText); +#include return qMax(aBoundingRect.width(), aFontMetrics.width(theText)) + aTextMargin * 2; +#include } // =======================================================================