From 510d1248abc80204f4300e2ad82913fca21e1950 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Fri, 26 Jun 2026 19:42:55 -0500 Subject: [PATCH] fix: prevent duplicate tags in Joomla manifests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit version_bump, version_set_platform, and version_check all used unlimited preg_replace on tags. If a duplicate ever got introduced (merge conflict, manual edit), every subsequent CI bump faithfully updated both copies — perpetuating the duplicate forever. Fix: use limit=1 for the primary replacement, then collapse any remaining duplicate lines in a second pass. Claude-Session: https://claude.ai/code/session_01MbEjBtsSjPuTWhqqrMS2wG --- cli/version_bump.php | 9 +++++++-- cli/version_check.php | 7 +++++-- cli/version_set_platform.php | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cli/version_bump.php b/cli/version_bump.php index c416b24..7e17791 100644 --- a/cli/version_bump.php +++ b/cli/version_bump.php @@ -214,7 +214,8 @@ class VersionBumpCli extends CliFramework $newContent = preg_replace( $xmlPattern, '${1}' . $newBase . '', - $content + $content, + 1 ); } else { $xmlPattern = '#\d{2}\.\d{2}\.\d{2}' @@ -222,9 +223,13 @@ class VersionBumpCli extends CliFramework $newContent = preg_replace( $xmlPattern, "{$newFull}", - $content + $content, + 1 ); } + if ($newContent !== null) { + $newContent = preg_replace('#(\s*[^<]*)\s*[^<]*#', '$1', $newContent); + } if ($newContent !== null && $newContent !== $content) { file_put_contents($xmlFile, $newContent); $updatedFiles[] = substr($xmlFile, strlen($root) + 1); diff --git a/cli/version_check.php b/cli/version_check.php index 42dee12..b601532 100644 --- a/cli/version_check.php +++ b/cli/version_check.php @@ -131,9 +131,11 @@ class VersionCheckCli extends CliFramework $updated = preg_replace( $vPat, "{$highestVersion}", - $content + $content, + 1 ); if ($updated !== null) { + $updated = preg_replace('#(\s*[^<]*)\s*[^<]*#', '$1', $updated); file_put_contents($mokoManifest, $updated); } echo " Fixed: .mokogitea/manifest.xml -> {$highestVersion}\n"; } @@ -185,8 +187,9 @@ class VersionCheckCli extends CliFramework if (!file_exists($file)) { continue; } $content = file_get_contents($file); - $updated = preg_replace('#[^<]*#', "{$highestVersion}", $content); + $updated = preg_replace('#[^<]*#', "{$highestVersion}", $content, 1); if ($updated !== null) { + $updated = preg_replace('#(\s*[^<]*)\s*[^<]*#', '$1', $updated); file_put_contents($file, $updated); } echo " Fixed: {$source} -> {$highestVersion}\n"; } diff --git a/cli/version_set_platform.php b/cli/version_set_platform.php index 79e1c15..526c0e6 100644 --- a/cli/version_set_platform.php +++ b/cli/version_set_platform.php @@ -164,8 +164,12 @@ class VersionSetPlatformCli extends CliFramework $updated = preg_replace( '|[^<]*|', "{$version}", - $content + $content, + 1 ); + if ($updated !== null) { + $updated = preg_replace('#(\s*[^<]*)\s*[^<]*#', '$1', $updated); + } if ($updated !== null && $updated !== $content) { file_put_contents($file, $updated); $relPath = str_replace($root . '/', '', $file);