From ecb7aa561e2d343f182a3da2494fa82d16afb782 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 18 Feb 2026 16:55:35 +0100 Subject: [PATCH 1/2] feat: support GIT_TAG with CMake variable When GIT_TAG uses a variable like ${FOO_REF}, resolve it to the corresponding set() definition and update that line instead of the FetchContent_Declare block. Co-Authored-By: Claude Opus 4.6 --- updater/scripts/cmake-functions.ps1 | 29 ++- .../tests/update-dependency-cmake.Tests.ps1 | 171 ++++++++++++++++++ 2 files changed, 196 insertions(+), 4 deletions(-) diff --git a/updater/scripts/cmake-functions.ps1 b/updater/scripts/cmake-functions.ps1 index 8089e90f..8ef4fb32 100644 --- a/updater/scripts/cmake-functions.ps1 +++ b/updater/scripts/cmake-functions.ps1 @@ -44,7 +44,18 @@ function Parse-CMakeFetchContent { throw "Could not parse GIT_REPOSITORY or GIT_TAG from FetchContent_Declare block" } - return @{ GitRepository = $repo; GitTag = $tag; DepName = $depName } + # Resolve CMake variable references like ${FOO_REF} + $gitTagVariable = $null + if ($tag -match '^\$\{(\w+)\}$') { + $gitTagVariable = $Matches[1] + $setMatch = [regex]::Match($content, "(?m)^\s*set\s*\(\s*$gitTagVariable\s+`"?([^`"\s)]+)") + if (-not $setMatch.Success) { + throw "CMake variable '$gitTagVariable' referenced by GIT_TAG not found in $filePath" + } + $tag = $setMatch.Groups[1].Value + } + + return @{ GitRepository = $repo; GitTag = $tag; DepName = $depName; GitTagVariable = $gitTagVariable } } function Find-TagForHash { @@ -167,10 +178,20 @@ function Update-CMakeFile { $replacement = $newValue } - # Update GIT_TAG value, replacing entire line content after GIT_TAG + # Update the value, replacing entire line content after the value # This removes potentially outdated version-specific comments - $pattern = "(FetchContent_Declare\s*\(\s*$depName\s+[^)]*GIT_TAG\s+)[^\r\n]+(\r?\n[^)]*\))" - $newContent = [regex]::Replace($content, $pattern, "`${1}$replacement`${2}", 'Singleline') + $gitTagVariable = $fetchContent.GitTagVariable + if ($gitTagVariable) { + # Update the set() line that defines the variable + $pattern = "(?m)(^\s*set\s*\(\s*$gitTagVariable\s+`"?)([^`"\s)]+)(`"?[^)]*\))[^\r\n]*" + $valueOnly = if ($wasHash) { $newHash } else { $newValue } + $trailingComment = if ($wasHash) { " # $newValue" } else { "" } + $newContent = [regex]::Replace($content, $pattern, "`${1}$valueOnly`${3}$trailingComment") + } else { + # Update GIT_TAG value in FetchContent_Declare block + $pattern = "(FetchContent_Declare\s*\(\s*$depName\s+[^)]*GIT_TAG\s+)[^\r\n]+(\r?\n[^)]*\))" + $newContent = [regex]::Replace($content, $pattern, "`${1}$replacement`${2}", 'Singleline') + } if ($newContent -eq $content) { throw "Failed to update GIT_TAG in $filePath - pattern may not have matched" diff --git a/updater/tests/update-dependency-cmake.Tests.ps1 b/updater/tests/update-dependency-cmake.Tests.ps1 index cb9343d4..c4400e20 100644 --- a/updater/tests/update-dependency-cmake.Tests.ps1 +++ b/updater/tests/update-dependency-cmake.Tests.ps1 @@ -147,6 +147,92 @@ FetchContent_MakeAvailable(sentry-native googletest) } } + Context 'Variable reference GIT_TAG' { + BeforeAll { + $script:tempDir = "$TestDrive/cmake-tests" + New-Item $tempDir -ItemType Directory -Force | Out-Null + + $script:varRefFile = "$tempDir/varref.cmake" + @' +include(FetchContent) + +set(SENTRY_NATIVE_REF "v0.9.1" CACHE STRING "The sentry-native ref") + +FetchContent_Declare( + sentry-native + GIT_REPOSITORY https://github.com/getsentry/sentry-native + GIT_TAG ${SENTRY_NATIVE_REF} + GIT_SHALLOW FALSE +) + +FetchContent_MakeAvailable(sentry-native) +'@ | Out-File $varRefFile + + $script:varRefHashFile = "$tempDir/varref-hash.cmake" + @' +include(FetchContent) + +set(SENTRY_NATIVE_REF a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2) # 0.9.1 + +FetchContent_Declare( + sentry-native + GIT_REPOSITORY https://github.com/getsentry/sentry-native + GIT_TAG ${SENTRY_NATIVE_REF} +) + +FetchContent_MakeAvailable(sentry-native) +'@ | Out-File $varRefHashFile + + $script:varRefDirectFile = "$tempDir/varref-direct.cmake" + @' +include(FetchContent) + +FetchContent_Declare( + sentry-native + GIT_REPOSITORY https://github.com/getsentry/sentry-native + GIT_TAG v0.9.1 +) +'@ | Out-File $varRefDirectFile + + $script:varRefMissingFile = "$tempDir/varref-missing.cmake" + @' +include(FetchContent) + +FetchContent_Declare( + sentry-native + GIT_REPOSITORY https://github.com/getsentry/sentry-native + GIT_TAG ${UNDEFINED_VAR} +) +'@ | Out-File $varRefMissingFile + } + + It 'resolves quoted variable to actual value' { + $result = Parse-CMakeFetchContent $varRefFile 'sentry-native' + + $result.GitRepository | Should -Be 'https://github.com/getsentry/sentry-native' + $result.GitTag | Should -Be 'v0.9.1' + $result.GitTagVariable | Should -Be 'SENTRY_NATIVE_REF' + $result.DepName | Should -Be 'sentry-native' + } + + It 'resolves unquoted variable with hash value' { + $result = Parse-CMakeFetchContent $varRefHashFile 'sentry-native' + + $result.GitTag | Should -Be 'a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2' + $result.GitTagVariable | Should -Be 'SENTRY_NATIVE_REF' + } + + It 'throws when variable definition is missing' { + { Parse-CMakeFetchContent $varRefMissingFile 'sentry-native' } | Should -Throw "*CMake variable 'UNDEFINED_VAR' referenced by GIT_TAG not found*" + } + + It 'returns null GitTagVariable for direct values' { + $result = Parse-CMakeFetchContent $varRefDirectFile 'sentry-native' + + $result.GitTagVariable | Should -BeNullOrEmpty + } + } + Context 'Malformed files' { BeforeAll { $script:tempDir = "$TestDrive/cmake-tests" @@ -342,6 +428,91 @@ FetchContent_MakeAvailable(sentry-native) } } + Context 'Variable reference tag updates' { + BeforeAll { + $script:tempDir = "$TestDrive/cmake-update-tests" + New-Item $tempDir -ItemType Directory -Force | Out-Null + + $script:varRefTagTemplate = @' +include(FetchContent) + +set(SENTRY_NATIVE_REF "v0.9.1" CACHE STRING "The sentry-native ref") + +FetchContent_Declare( + sentry-native + GIT_REPOSITORY https://github.com/getsentry/sentry-native + GIT_TAG ${SENTRY_NATIVE_REF} + GIT_SHALLOW FALSE +) + +FetchContent_MakeAvailable(sentry-native) +'@ + } + + BeforeEach { + $script:varRefTagTestFile = "$tempDir/varref-tag-test.cmake" + } + + It 'updates set() value and leaves GIT_TAG variable reference untouched' { + $varRefTagTemplate | Out-File $varRefTagTestFile + + Update-CMakeFile $varRefTagTestFile 'sentry-native' 'v0.9.2' + + $content = Get-Content $varRefTagTestFile -Raw + $content | Should -Match 'set\(SENTRY_NATIVE_REF "v0.9.2"' + $content | Should -Match 'GIT_TAG \$\{SENTRY_NATIVE_REF\}' + $content | Should -Not -Match 'v0.9.1' + } + + It 'preserves file structure' { + $varRefTagTemplate | Out-File $varRefTagTestFile + + Update-CMakeFile $varRefTagTestFile 'sentry-native' 'v0.9.2' + + $content = Get-Content $varRefTagTestFile -Raw + $content | Should -Match 'include\(FetchContent\)' + $content | Should -Match 'FetchContent_MakeAvailable' + $content | Should -Match 'GIT_SHALLOW FALSE' + } + } + + Context 'Variable reference hash updates' { + BeforeAll { + $script:tempDir = "$TestDrive/cmake-update-tests" + New-Item $tempDir -ItemType Directory -Force | Out-Null + + $script:varRefHashTemplate = @' +include(FetchContent) + +set(SENTRY_NATIVE_REF a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2) # 0.9.1 + +FetchContent_Declare( + sentry-native + GIT_REPOSITORY https://github.com/getsentry/sentry-native + GIT_TAG ${SENTRY_NATIVE_REF} +) + +FetchContent_MakeAvailable(sentry-native) +'@ + } + + BeforeEach { + $script:varRefHashTestFile = "$tempDir/varref-hash-test.cmake" + } + + It 'updates set() value with new hash and comment' { + $varRefHashTemplate | Out-File $varRefHashTestFile + + Update-CMakeFile $varRefHashTestFile 'sentry-native' '0.11.0' + + $content = Get-Content $varRefHashTestFile -Raw + $content | Should -Match 'set\(SENTRY_NATIVE_REF 3bd091313ae97be90be62696a2babe591a988eb8\) # 0.11.0' + $content | Should -Match 'GIT_TAG \$\{SENTRY_NATIVE_REF\}' + $content | Should -Not -Match 'a64d5bd8ee130f2cda196b6fa7d9b65bfa6d32e2' + $content | Should -Not -Match '# 0.9.1' + } + } + # Note: Hash update tests require network access for git ls-remote # and are better suited for integration tests } From a2bbf00bfc8289a39f71a52532d16fff53fe0740 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 18 Feb 2026 17:01:19 +0100 Subject: [PATCH 2/2] docs: add changelog entry for CMake variable GIT_TAG support Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53447fb8..28c31a86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- Updater - Support CMake `GIT_TAG` with variable references like `${FOO_REF}`, resolving and updating the corresponding `set()` definition ([#149](https://github.com/getsentry/github-workflows/pull/149)) + ## 3.2.1 ### Fixes