diff --git a/.gitignore b/.gitignore index c0e9df34b..e6968023c 100644 --- a/.gitignore +++ b/.gitignore @@ -119,8 +119,8 @@ test-*.html # Configuration.java is auto-generated at build time from Configuration.java.in. # It is NOT tracked by git to avoid constant rebase conflicts on the injected -# git hash / date / build timestamp. The build (Gradle / Maven) recreates it -# automatically from the template on a fresh clone. +# git hash / date / build timestamp. The build (Gradle / Maven) regenerates it +# from the template before compilation. # To capture a specific build's version info: git add -f /Configuration.java src/main/java/org/perlonjava/core/Configuration.java diff --git a/build.gradle b/build.gradle index 42d4b352d..2d7277553 100644 --- a/build.gradle +++ b/build.gradle @@ -92,32 +92,31 @@ cyclonedxBom { // // Configuration.java is NOT tracked by git (it is listed in .gitignore). // The canonical template is Configuration.java.in, which is tracked and contains -// placeholder values. This task copies the template to Configuration.java when -// the file is absent (e.g. after a fresh clone) and then patches in the real -// git hash, commit date, and build timestamp. +// placeholder values. Always regenerate from that template so version and other +// configuration changes cannot leave a stale generated source in an existing +// checkout, then patch in the real git hash, commit date, and build timestamp. def configFilePath = layout.projectDirectory.file('src/main/java/org/perlonjava/core/Configuration.java') def configTemplPath = layout.projectDirectory.file('src/main/java/org/perlonjava/core/Configuration.java.in') tasks.register('injectGitInfo') { - description = 'Copies Configuration.java.in → Configuration.java (if needed) and injects git info' + description = 'Regenerates Configuration.java from its template and injects build metadata' group = 'build' - // Declare inputs/outputs for configuration cache compatibility def configFile = configFilePath.asFile def templateFile = configTemplPath.asFile + + inputs.file(configTemplPath) + outputs.file(configFilePath) + // The build timestamp and current git revision are dynamic inputs. + outputs.upToDateWhen { false } doLast { - // If Configuration.java is absent (fresh clone, gitignored), recreate it - // from the committed template so the compiler has a valid source file. - if (!configFile.exists()) { - if (templateFile.exists()) { - configFile.text = templateFile.text - logger.lifecycle("Created Configuration.java from template") - } else { - logger.warn("Neither Configuration.java nor Configuration.java.in found; skipping git info injection") - return - } + if (!templateFile.exists()) { + throw new GradleException("Configuration template not found: ${templateFile}") } + + // Never carry configuration values forward from a previous build. + def content = templateFile.text // Get git commit info using Runtime.exec def gitCommitId = 'dev' @@ -141,8 +140,6 @@ tasks.register('injectGitInfo') { // Only update if we got valid values if (gitCommitId && gitCommitId != 'dev') { - def content = configFile.text - // Use safe pattern matching for quoted string values content = content.replaceAll( /(gitCommitId\s*=\s*)"[^"]*"/, @@ -162,10 +159,10 @@ tasks.register('injectGitInfo') { /(buildTimestamp\s*=\s*)"[^"]*"/, "\$1\"${buildTimestamp}\"" ) - - configFile.text = content - logger.lifecycle("Injected git info: ${gitCommitId} (${gitCommitDate})") } + + configFile.text = content + logger.lifecycle("Regenerated Configuration.java and injected git info: ${gitCommitId} (${gitCommitDate})") } } diff --git a/pom.xml b/pom.xml index a8aa3c4da..322704852 100644 --- a/pom.xml +++ b/pom.xml @@ -365,22 +365,25 @@ -c &2 + exit 1 fi -if [ -f "$CONFIG_FILE" ]; then - GIT_COMMIT_ID=$(git rev-parse --short HEAD 2>/dev/null || echo "dev") - GIT_COMMIT_DATE=$(git log -1 --format=%cs HEAD 2>/dev/null || echo "unknown") - if [ "$GIT_COMMIT_ID" != "dev" ]; then - perl -i -pe "s/(gitCommitId\\s*=\\s*)\"[^\"]*\"/\$1\"$GIT_COMMIT_ID\"/" "$CONFIG_FILE" - perl -i -pe "s/(gitCommitDate\\s*=\\s*)\"[^\"]*\"/\$1\"$GIT_COMMIT_DATE\"/" "$CONFIG_FILE" - echo "Injected git info: $GIT_COMMIT_ID ($GIT_COMMIT_DATE)" - fi +cp "$TEMPLATE_FILE" "$CONFIG_FILE" +GIT_COMMIT_ID=$(git rev-parse --short HEAD 2>/dev/null || echo "dev") +GIT_COMMIT_DATE=$(git log -1 --format=%cs HEAD 2>/dev/null || echo "unknown") +BUILD_TIMESTAMP=$(LC_ALL=C date "+%b %e %Y %H:%M:%S") +if [ "$GIT_COMMIT_ID" != "dev" ]; then + perl -i -pe "s/(gitCommitId\\s*=\\s*)\"[^\"]*\"/\$1\"$GIT_COMMIT_ID\"/" "$CONFIG_FILE" + perl -i -pe "s/(gitCommitDate\\s*=\\s*)\"[^\"]*\"/\$1\"$GIT_COMMIT_DATE\"/" "$CONFIG_FILE" + perl -i -pe "s/(buildTimestamp\\s*=\\s*)\"[^\"]*\"/\$1\"$BUILD_TIMESTAMP\"/" "$CONFIG_FILE" fi +echo "Regenerated Configuration.java and injected git info: $GIT_COMMIT_ID ($GIT_COMMIT_DATE)" ]]> diff --git a/scripts/inject-git-info.ps1 b/scripts/inject-git-info.ps1 index 36806dbc9..2594a536c 100644 --- a/scripts/inject-git-info.ps1 +++ b/scripts/inject-git-info.ps1 @@ -1,40 +1,39 @@ # inject-git-info.ps1 -# Injects git commit ID and date into Configuration.java for Windows builds. -# Configuration.java is gitignored; this script recreates it from -# Configuration.java.in when the file is absent (e.g. after a fresh clone). +# Regenerates Configuration.java and injects build metadata for Windows builds. +# Configuration.java is gitignored; always recreate it from the tracked template +# so an existing checkout cannot retain stale version or configuration values. $ConfigFile = "src/main/java/org/perlonjava/core/Configuration.java" $TemplateFile = "src/main/java/org/perlonjava/core/Configuration.java.in" -# Recreate from template if absent (fresh clone / gitignored) -if (-not (Test-Path $ConfigFile)) { - if (Test-Path $TemplateFile) { - Copy-Item $TemplateFile $ConfigFile - Write-Host "Created Configuration.java from template" - } else { - Write-Host "Neither Configuration.java nor Configuration.java.in found; skipping" - exit 0 - } +if (-not (Test-Path $TemplateFile)) { + Write-Error "Configuration template not found: $TemplateFile" + exit 1 } -if (Test-Path $ConfigFile) { - try { - $GitCommitId = git rev-parse --short HEAD 2>$null - $GitCommitDate = git log -1 --format=%cs HEAD 2>$null - - if ($GitCommitId -and $GitCommitId -ne "dev") { - $content = Get-Content $ConfigFile -Raw - - # Replace gitCommitId value - $content = $content -replace '(gitCommitId\s*=\s*)"[^"]*"', ('$1"' + $GitCommitId + '"') - - # Replace gitCommitDate value - $content = $content -replace '(gitCommitDate\s*=\s*)"[^"]*"', ('$1"' + $GitCommitDate + '"') - - Set-Content $ConfigFile -Value $content -NoNewline - Write-Host "Injected git info: $GitCommitId ($GitCommitDate)" - } - } catch { - Write-Host "Git info injection skipped: $_" +Copy-Item $TemplateFile $ConfigFile -Force -ErrorAction Stop + +try { + $GitCommitId = git rev-parse --short HEAD 2>$null + $GitCommitDate = git log -1 --format=%cs HEAD 2>$null + + if ($GitCommitId -and $GitCommitId -ne "dev") { + $BuildTimestamp = (Get-Date).ToString( + "MMM dd yyyy HH:mm:ss", + [System.Globalization.CultureInfo]::InvariantCulture + ) -replace '^(\w{3}) 0', '$1 ' + $content = Get-Content $ConfigFile -Raw + + $content = $content -replace '(gitCommitId\s*=\s*)"[^"]*"', ('$1"' + $GitCommitId + '"') + $content = $content -replace '(gitCommitDate\s*=\s*)"[^"]*"', ('$1"' + $GitCommitDate + '"') + $content = $content -replace '(buildTimestamp\s*=\s*)"[^"]*"', ('$1"' + $BuildTimestamp + '"') + + Set-Content $ConfigFile -Value $content -NoNewline } +} catch { + $GitCommitId = "dev" + $GitCommitDate = "unknown" + Write-Host "Git info injection skipped: $_" } + +Write-Host "Regenerated Configuration.java and injected git info: $GitCommitId ($GitCommitDate)" diff --git a/src/main/java/org/perlonjava/core/Configuration.java.in b/src/main/java/org/perlonjava/core/Configuration.java.in index 2621763ee..58ec4ef16 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java.in +++ b/src/main/java/org/perlonjava/core/Configuration.java.in @@ -51,7 +51,7 @@ public final class Configuration { /** * Build timestamp in Perl 5 "Compiled at" format (e.g., "Apr 7 2026 11:20:00"). - * Automatically populated by Gradle during build. + * Automatically populated by Gradle/Maven during build. * Parsed by App::perlbrew and other tools via: perl -V | grep "Compiled at" * DO NOT EDIT MANUALLY - this value is replaced at build time. */