This is an automated email from the ASF dual-hosted git repository.
ppkarwasz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/logging-flume.git
The following commit(s) were added to refs/heads/trunk by this push:
new c0d73dca Make the build reproducible by deriving version metadata from
the manifest (#489)
c0d73dca is described below
commit c0d73dcae30ecf10c343c83ac988d5c8d3ffb824
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Tue Aug 25 13:48:30 2026 +0200
Make the build reproducible by deriving version metadata from the manifest
(#489)
* Apply the `revision` convention to `flume-parent`
Every published module inherits from `flume-parent`, not from the
aggregator, so the CI-friendly properties have to be declared there as
well. Without them the release automation bumps only the aggregator and
the artifacts ship a stale version and build timestamp.
Assisted-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_011QwMh1JvFaPBgWEGrMgMj7
* Derive the version metadata from the JAR manifest
`saveVersion.sh` recorded the builder's user name, host, clock and a
checksum of the working copy, so no two builds agreed and the source
distribution, which carries no repository metadata, agreed with none.
The same facts now come from POM-derived manifest headers, which a Git
checkout and the source archive produce identically.
`getUser()` and `getSrcChecksum()` are deprecated for removal, and
`getRevision()` reports nothing until the build records a commit id
again.
Assisted-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_011QwMh1JvFaPBgWEGrMgMj7
* Fall back to the Maven descriptor on blank manifest headers
A present but empty header would have suppressed the fallback.
Assisted-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016zsFn1f2B32vcNoCeZSfn7
* Mention the "Unknown" sentinel in the `getDate` contract
The `@return` clause promised ISO-8601 unconditionally.
Assisted-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016zsFn1f2B32vcNoCeZSfn7
* Keep repository specifics out of the metadata test
Downstream builds override `<scm>`; assert only invariants, while
still rejecting tags that betray an unset `<scm><tag>`.
* Apply Spotless formatting
Assisted-By: Claude Fable 5 <[email protected]>
---
flume-ng-auth/pom.xml | 2 +-
flume-ng-channels/flume-file-channel/pom.xml | 2 +-
.../flume-spillable-memory-channel/pom.xml | 2 +-
flume-ng-channels/pom.xml | 2 +-
.../flume-ng-config-filter-api/pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
flume-ng-configfilters/pom.xml | 2 +-
flume-ng-configuration/pom.xml | 2 +-
flume-ng-core/pom.xml | 113 +----------
flume-ng-core/scripts/saveVersion.ps1 | 61 ------
flume-ng-core/scripts/saveVersion.sh | 69 -------
.../java/org/apache/flume/VersionAnnotation.java | 72 -------
.../java/org/apache/flume/tools/VersionInfo.java | 224 ++++++++++++++++-----
.../org/apache/flume/tools/TestVersionInfo.java | 158 ++++++++++++---
flume-ng-dist/pom.xml | 2 +-
.../flume-ganglia-monitor/pom.xml | 2 +-
.../flume-http-monitor/pom.xml | 2 +-
.../flume-prometheus-monitor/pom.xml | 2 +-
flume-ng-instrumentation/pom.xml | 2 +-
flume-ng-node/pom.xml | 2 +-
flume-ng-sdk/pom.xml | 16 +-
flume-ng-sources/flume-http-source/pom.xml | 2 +-
flume-ng-sources/flume-netcat-source/pom.xml | 2 +-
flume-ng-sources/flume-syslog-source/pom.xml | 2 +-
flume-ng-sources/flume-taildir-source/pom.xml | 2 +-
flume-ng-sources/pom.xml | 2 +-
flume-parent/pom.xml | 23 ++-
flume-tools/pom.xml | 2 +-
29 files changed, 364 insertions(+), 414 deletions(-)
diff --git a/flume-ng-auth/pom.xml b/flume-ng-auth/pom.xml
index e288313d..b13267f3 100644
--- a/flume-ng-auth/pom.xml
+++ b/flume-ng-auth/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-ng-channels/flume-file-channel/pom.xml
b/flume-ng-channels/flume-file-channel/pom.xml
index 245e4d56..6183926c 100644
--- a/flume-ng-channels/flume-file-channel/pom.xml
+++ b/flume-ng-channels/flume-file-channel/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-channels</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-channels</groupId>
diff --git a/flume-ng-channels/flume-spillable-memory-channel/pom.xml
b/flume-ng-channels/flume-spillable-memory-channel/pom.xml
index b891a42a..2fc1378d 100644
--- a/flume-ng-channels/flume-spillable-memory-channel/pom.xml
+++ b/flume-ng-channels/flume-spillable-memory-channel/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-channels</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-channels</groupId>
diff --git a/flume-ng-channels/pom.xml b/flume-ng-channels/pom.xml
index a8aeef90..42343fad 100644
--- a/flume-ng-channels/pom.xml
+++ b/flume-ng-channels/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-ng-configfilters/flume-ng-config-filter-api/pom.xml
b/flume-ng-configfilters/flume-ng-config-filter-api/pom.xml
index 5f4b9cd6..0fa090bd 100644
--- a/flume-ng-configfilters/flume-ng-config-filter-api/pom.xml
+++ b/flume-ng-configfilters/flume-ng-config-filter-api/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-configfilters</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<artifactId>flume-ng-config-filter-api</artifactId>
diff --git
a/flume-ng-configfilters/flume-ng-environment-variable-config-filter/pom.xml
b/flume-ng-configfilters/flume-ng-environment-variable-config-filter/pom.xml
index 78c30b0c..f0d39f5d 100644
--- a/flume-ng-configfilters/flume-ng-environment-variable-config-filter/pom.xml
+++ b/flume-ng-configfilters/flume-ng-environment-variable-config-filter/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-configfilters</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<artifactId>flume-ng-environment-variable-config-filter</artifactId>
diff --git
a/flume-ng-configfilters/flume-ng-external-process-config-filter/pom.xml
b/flume-ng-configfilters/flume-ng-external-process-config-filter/pom.xml
index 339fdfdb..1ae97a67 100644
--- a/flume-ng-configfilters/flume-ng-external-process-config-filter/pom.xml
+++ b/flume-ng-configfilters/flume-ng-external-process-config-filter/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-configfilters</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<artifactId>flume-ng-external-process-config-filter</artifactId>
diff --git a/flume-ng-configfilters/pom.xml b/flume-ng-configfilters/pom.xml
index 3a219835..7c6a1c74 100644
--- a/flume-ng-configfilters/pom.xml
+++ b/flume-ng-configfilters/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-ng-configuration/pom.xml b/flume-ng-configuration/pom.xml
index 8ab25fd6..0ae2b9d2 100644
--- a/flume-ng-configuration/pom.xml
+++ b/flume-ng-configuration/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
<artifactId>flume-ng-configuration</artifactId>
diff --git a/flume-ng-core/pom.xml b/flume-ng-core/pom.xml
index fa9857c8..2f8044fe 100644
--- a/flume-ng-core/pom.xml
+++ b/flume-ng-core/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
@@ -183,115 +183,4 @@
</plugin>
</plugins>
</build>
- <profiles>
- <profile>
- <id>not-windows</id>
- <activation>
- <os>
- <family>!Windows</family>
- </os>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-version</id>
- <goals>
- <goal>run</goal>
- </goals>
- <phase>generate-sources</phase>
- <configuration>
- <target>
- <mkdir
dir="${project.build.directory}/generated-sources/java" />
- <exec executable="sh">
- <arg line="${basedir}/scripts/saveVersion.sh
${project.version} ${project.build.directory}" />
- </exec>
- </target>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>add-source</id>
- <goals>
- <goal>add-source</goal>
- </goals>
- <phase>generate-sources</phase>
- <configuration>
- <sources>
- <source>target/generated-sources/java</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
- </build>
- </profile>
-
- <profile>
- <id>windows</id>
- <activation>
- <os>
- <family>Windows</family>
- </os>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-version</id>
- <goals>
- <goal>run</goal>
- </goals>
- <phase>generate-sources</phase>
- <configuration>
- <target>
- <mkdir
dir="${project.build.directory}/generated-sources/java/org/apache/flume" />
- <exec executable="powershell">
- <arg line="-executionpolicy unrestricted -file
${basedir}\scripts\saveVersion.ps1 ${project.version}
${project.build.directory}" />
- </exec>
- </target>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>add-source</id>
- <goals>
- <goal>add-source</goal>
- </goals>
- <phase>generate-sources</phase>
- <configuration>
- <sources>
- <source>target/generated-sources/java</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
- </build>
- </profile>
-
- </profiles>
-
</project>
diff --git a/flume-ng-core/scripts/saveVersion.ps1
b/flume-ng-core/scripts/saveVersion.ps1
deleted file mode 100644
index dff88134..00000000
--- a/flume-ng-core/scripts/saveVersion.ps1
+++ /dev/null
@@ -1,61 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This script is used to generate the annotation of package info that
-# records the version, revision, branch, url, user and timestamp.
-
-$version=$args[0]
-$buildDirectory=$args[1]
-$outputFile=
"$buildDirectory\generated-sources\java\org\apache\flume\package-info.java"
-$user = $Env:username
-$date = Get-Date
-
-cmd /c svn info 2>&1 | Out-Null
-if ( $LastExitCode -eq 0 ) {
- $revision=svn info | % { if( $_ -match "Last Changed Rev: (?<rev>.*)" ) {
$matches['rev'];} }
- $url=svn info | % { if( $_ -match "URL: (?<url>.*)" ) { $matches['url'];} }
- $branch= if( $url -match ".*(?<branch>(branches.*)|(tags.*)|(trunk.*))" ) {
$matches['branch']; } else { "Unknown"; }
-}
-else {
- cmd /c git rev-parse HEAD 2>&1 | Out-Null
- if ( $LastExitCode -eq 0 ) {
- $revision=$(git log -1 --pretty=format:"%H")
- $branch=$(git name-rev --name-only HEAD)
- $remote=$(git config branch.$branch.remote)
- $url=$(git config remote.$remote.url)
- }
- else {
- revision="Unknown"
- branch="Unknown"
- url="file://$cwd"
- }
-}
-
-$srcChecksum="N/A"
-
-
-$fileContent = @"
-/*
- * Generated by scripts/saveVersion.ps1
- */
-@VersionAnnotation(version="$version", revision="$revision", branch="$branch",
- user="$user", date="$date", url="$url",
- srcChecksum="$srcChecksum")
-package org.apache.flume;
-"@
-
-New-Item $outputFile -value $fileContent -force -type file
-
diff --git a/flume-ng-core/scripts/saveVersion.sh
b/flume-ng-core/scripts/saveVersion.sh
deleted file mode 100755
index ad3f8b19..00000000
--- a/flume-ng-core/scripts/saveVersion.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/sh
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This script is used to generate the annotation of package info that
-# records the version, revision, branch, url, user and timestamp.
-
-unset LANG
-unset LC_CTYPE
-unset LC_TIME
-version=$1
-buildDirectory=$2
-user=`whoami`
-date=`date`
-dir=`pwd`
-cwd=`dirname $dir`
-if [ -d ../.svn ]; then
- revision=`svn info ../ | sed -n -e 's/Last Changed Rev: \(.*\)/\1/p'`
- url=`svn info ../ | sed -n -e 's/URL: \(.*\)/\1/p'`
- branch=`echo $url | sed -n -e 's,.*\(branches/.*\)$,\1,p' \
- -e 's,.*\(tags/.*\)$,\1,p' \
- -e 's,.*trunk$,trunk,p'`
-elif git rev-parse HEAD 2>/dev/null > /dev/null ; then
- revision=`git log -1 --pretty=format:"%H"`
- hostname=`hostname`
- branch=`git branch | sed -n -e 's/^* //p'`
- url="git://${hostname}${cwd}"
-else
- revision="Unknown"
- branch="Unknown"
- url="file://$cwd"
-fi
-
-if [ -n "$(which md5sum)" ]; then
- srcChecksum=`find ../ -name '*.java' | grep -v generated-sources | LC_ALL=C
sort | \
- xargs md5sum | md5sum | cut -d ' ' -f 1`
-else
- srcChecksum=`find ../ -name '*.java' | grep -v generated-sources | LC_ALL=C
sort | \
- xargs md5 | md5 | cut -d ' ' -f 1`
-fi
-
-mkdir -p $buildDirectory/generated-sources/java/org/apache/flume/
-cat << EOF | \
- sed -e "s/VERSION/$version/" -e "s/USER/$user/" -e "s/DATE/$date/" \
- -e "s|URL|$url|" -e "s/REV/$revision/" \
- -e "s|BRANCH|$branch|" -e "s/SRCCHECKSUM/$srcChecksum/" \
- >
$buildDirectory/generated-sources/java/org/apache/flume/package-info.java
-/*
- * Generated by scripts/saveVersion.sh
- */
-@VersionAnnotation(version="VERSION", revision="REV", branch="BRANCH",
- user="USER", date="DATE", url="URL",
- srcChecksum="SRCCHECKSUM")
-package org.apache.flume;
-EOF
\ No newline at end of file
diff --git
a/flume-ng-core/src/main/java/org/apache/flume/VersionAnnotation.java
b/flume-ng-core/src/main/java/org/apache/flume/VersionAnnotation.java
deleted file mode 100644
index 06269ac3..00000000
--- a/flume-ng-core/src/main/java/org/apache/flume/VersionAnnotation.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flume;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * This class is about package attribute that captures
- * version info of Flume that was compiled.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.PACKAGE)
-public @interface VersionAnnotation {
-
- /**
- * Get the Flume version
- * @return the version string "1.1"
- */
- String version();
-
- /**
- * Get the subversion revision.
- * @return the revision number as a string (eg. "100755")
- */
- String revision();
-
- /**
- * Get the branch from which this was compiled.
- * @return The branch name, e.g. "trunk"
- */
- String branch();
-
- /**
- * Get the username that compiled Flume.
- */
- String user();
-
- /**
- * Get the date when Flume was compiled.
- * @return the date in unix 'date' format
- */
- String date();
-
- /**
- * Get the url for the subversion repository.
- */
- String url();
-
- /**
- * Get a checksum of the source files from which
- * Flume was compiled.
- * @return a string that uniquely identifies the source
- **/
- String srcChecksum();
-}
diff --git
a/flume-ng-core/src/main/java/org/apache/flume/tools/VersionInfo.java
b/flume-ng-core/src/main/java/org/apache/flume/tools/VersionInfo.java
index f5220e4d..0f646930 100644
--- a/flume-ng-core/src/main/java/org/apache/flume/tools/VersionInfo.java
+++ b/flume-ng-core/src/main/java/org/apache/flume/tools/VersionInfo.java
@@ -16,105 +16,229 @@
*/
package org.apache.flume.tools;
-import org.apache.flume.VersionAnnotation;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.lang3.StringUtils;
-/*
- * This class provides version info of Flume NG
+/**
+ * Provides the build metadata of the Flume artifact this class was loaded
from.
+ *
+ * <p>The values come from the manifest of that artifact, falling back to its
Maven descriptor when
+ * Flume has been shaded into another artifact and the manifest is no longer
its own. Every accessor
+ * returns {@value #UNKNOWN} rather than {@code null} when the information is
unavailable.
*/
-
public class VersionInfo {
- private static Package myPackage;
- private static VersionAnnotation version;
+ private static final String UNKNOWN = "Unknown";
+
+ private static final String GROUP_ID = "org.apache.flume";
+ private static final String ARTIFACT_ID = "flume-ng-core";
+
+ private static final String IMPLEMENTATION_TIMESTAMP =
"Implementation-Timestamp";
+ private static final String PURL = "Purl";
+ private static final String BUNDLE_SCM = "Bundle-SCM";
+
+ private static final String PURL_PREFIX = "pkg:maven/" + GROUP_ID + "/" +
ARTIFACT_ID + "@";
+ private static final String CLASS_PATH =
"org/apache/flume/tools/VersionInfo.class";
+ private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF";
+ private static final String POM_PROPERTIES_PATH =
+ "/META-INF/maven/" + GROUP_ID + "/" + ARTIFACT_ID +
"/pom.properties";
+
+ /** Matches one {@code name=value} pair of an OSGi header, with an
optionally quoted value. */
+ private static final Pattern SCM_ATTRIBUTE =
+
Pattern.compile("(?:^|,)\\s*([A-Za-z0-9_-]+)\\s*=\\s*(?:\"([^\"]*)\"|([^,]*))");
+
+ private static final Attributes MANIFEST = ownManifest();
+ private static final Properties POM_PROPERTIES = pomProperties();
+
+ private static final String VERSION = version(MANIFEST, POM_PROPERTIES);
+ private static final String PURL_VALUE = purl(MANIFEST, POM_PROPERTIES);
+ private static final String URL_VALUE =
orUnknown(scmAttribute(MANIFEST.getValue(BUNDLE_SCM), "url"));
+ private static final String TAG =
orUnknown(scmAttribute(MANIFEST.getValue(BUNDLE_SCM), "tag"));
+ private static final String DATE =
orUnknown(MANIFEST.getValue(IMPLEMENTATION_TIMESTAMP));
+
+ /**
+ * Reads the manifest of the artifact this class was loaded from.
+ *
+ * <p>Resolving it against the location of this class, instead of looking
up
+ * {@code META-INF/MANIFEST.MF} on the class path, keeps another artifact
from answering. Returns
+ * empty attributes when the manifest is missing or belongs to an artifact
Flume was shaded into.
+ */
+ private static Attributes ownManifest() {
+ URL self = VersionInfo.class.getResource("VersionInfo.class");
+ if (self == null) {
+ return new Attributes();
+ }
+ String location = self.toString();
+ if (!location.endsWith(CLASS_PATH)) {
+ return new Attributes();
+ }
+ String root = location.substring(0, location.length() -
CLASS_PATH.length());
+ try (InputStream stream = URI.create(root +
MANIFEST_PATH).toURL().openStream()) {
+ Attributes attributes = new Manifest(stream).getMainAttributes();
+ return isOwn(attributes) ? attributes : new Attributes();
+ } catch (IOException | RuntimeException ignored) {
+ return new Attributes();
+ }
+ }
+
+ private static Properties pomProperties() {
+ Properties properties = new Properties();
+ try (InputStream stream =
VersionInfo.class.getResourceAsStream(POM_PROPERTIES_PATH)) {
+ if (stream != null) {
+ properties.load(stream);
+ }
+ } catch (IOException | RuntimeException ignored) {
+ // Falls through to the empty properties.
+ }
+ return properties;
+ }
+
+ /** Tells whether the manifest describes this artifact rather than one
Flume was shaded into. */
+ static boolean isOwn(Attributes manifest) {
+ String purl = manifest.getValue(PURL);
+ return purl != null && purl.startsWith(PURL_PREFIX);
+ }
- static {
- myPackage = VersionAnnotation.class.getPackage();
- version = myPackage.getAnnotation(VersionAnnotation.class);
+ static String version(Attributes manifest, Properties pomProperties) {
+ String version =
manifest.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ return orUnknown(StringUtils.isNotBlank(version) ? version :
pomProperties.getProperty("version"));
+ }
+
+ static String purl(Attributes manifest, Properties pomProperties) {
+ String purl = manifest.getValue(PURL);
+ if (StringUtils.isBlank(purl)) {
+ String groupId = pomProperties.getProperty("groupId");
+ String artifactId = pomProperties.getProperty("artifactId");
+ String version = pomProperties.getProperty("version");
+ if (groupId != null && artifactId != null && version != null) {
+ purl = "pkg:maven/" + groupId + "/" + artifactId + "@" +
version;
+ }
+ }
+ return orUnknown(purl);
}
/**
- * Get the meta-data for the Flume package.
- * @return
+ * Returns one attribute of an OSGi {@code Bundle-SCM} header, or {@code
null} if absent.
+ *
+ * <p>The header is specified by OSGi Core R8, section 3.2.1, as a comma
separated list of
+ * {@code url}, {@code connection}, {@code developer-connection} and
{@code tag} attributes.
*/
- static Package getPackage() {
- return myPackage;
+ static String scmAttribute(String header, String attribute) {
+ if (header == null) {
+ return null;
+ }
+ Matcher matcher = SCM_ATTRIBUTE.matcher(header);
+ while (matcher.find()) {
+ if (attribute.equals(matcher.group(1))) {
+ String quoted = matcher.group(2);
+ return quoted != null ? quoted : matcher.group(3).trim();
+ }
+ }
+ return null;
+ }
+
+ private static String orUnknown(String value) {
+ return StringUtils.defaultIfBlank(value, UNKNOWN);
}
/**
- * Get the Flume version.
- * @return the Flume version string, eg. "1.1"
+ * Gets the Flume version.
+ *
+ * @return the Flume version string, eg. "2.0.0"
*/
public static String getVersion() {
- return version != null ? version.version() : "Unknown";
+ return VERSION;
+ }
+
+ /**
+ * Gets the Package URL of the Flume artifact this class was loaded from.
+ *
+ * @return the Package URL, eg.
"pkg:maven/org.apache.flume/[email protected]"
+ */
+ public static String getPurl() {
+ return PURL_VALUE;
}
/**
- * Get the subversion revision number for the root directory
- * @return the revision number, eg. "100755"
+ * Gets the source control revision this was built from.
+ *
+ * <p>The build no longer records a commit id, since it has to produce the
same artifact from a
+ * Git checkout and from the source distribution, which carries no
repository metadata.
+ *
+ * @return always "Unknown"
*/
public static String getRevision() {
- if (version != null && version.revision() != null &&
!version.revision().isEmpty()) {
- return version.revision();
- }
- return "Unknown";
+ return UNKNOWN;
}
/**
- * Get the branch on which this originated.
- * @return The branch name, e.g. "trunk" or "branches/branch-1.1"
+ * Gets the source control tag or branch this was built from.
+ *
+ * @return the tag, eg. "rel/2.0.0"
*/
public static String getBranch() {
- return version != null ? version.branch() : "Unknown";
+ return TAG;
}
/**
- * The date that Flume was compiled.
- * @return the compilation date in unix date format
+ * Gets the date Flume was built.
+ *
+ * @return the build date in ISO-8601 format, or "Unknown" if unavailable
*/
public static String getDate() {
- return version != null ? version.date() : "Unknown";
+ return DATE;
}
/**
- * The user that compiled Flume.
- * @return the username of the user
+ * Gets the user that compiled Flume.
+ *
+ * @return always "Unknown"
+ * @deprecated Recording the user would make the build unreproducible.
*/
+ @Deprecated(since = "2.0.0", forRemoval = true)
public static String getUser() {
- return version != null ? version.user() : "Unknown";
+ return UNKNOWN;
}
/**
- * Get the subversion URL for the root Flume directory.
+ * Gets the source control URL of the Flume repository.
+ *
+ * @return the repository URL
*/
public static String getUrl() {
- return version != null ? version.url() : "Unknown";
+ return URL_VALUE;
}
/**
- * Get the checksum of the source files from which Flume was
- * built.
- **/
+ * Gets the checksum of the source files Flume was built from.
+ *
+ * @return always "Unknown"
+ * @deprecated Use {@link #getPurl()} to identify the artifact, and verify
it against the
+ * checksums published with the release.
+ */
+ @Deprecated(since = "2.0.0", forRemoval = true)
public static String getSrcChecksum() {
- return version != null ? version.srcChecksum() : "Unknown";
+ return UNKNOWN;
}
- /**
- * Returns the build version info which includes version,
- * revision, user, date and source checksum
- */
+ /** Returns the build version info, which includes the version, the tag
and the build date. */
public static String getBuildVersion() {
- return VersionInfo.getVersion() + " from "
- + VersionInfo.getRevision() + " by "
- + VersionInfo.getUser() + " on "
- + VersionInfo.getDate() + " source checksum "
- + VersionInfo.getSrcChecksum();
+ return getVersion() + " from " + getBranch() + " built on " +
getDate();
}
public static void main(String[] args) {
System.out.println("Flume " + getVersion());
- System.out.println("Source code repository: " +
"https://git.apache.org/repos/asf/flume.git");
- System.out.println("Revision: " + getRevision());
- System.out.println("Compiled by " + getUser() + " on " + getDate());
- System.out.println("From source with checksum " + getSrcChecksum());
+ System.out.println("Package URL: " + getPurl());
+ System.out.println("Source code repository: " + getUrl());
+ System.out.println("Tag: " + getBranch());
+ System.out.println("Compiled on " + getDate());
}
}
diff --git
a/flume-ng-core/src/test/java/org/apache/flume/tools/TestVersionInfo.java
b/flume-ng-core/src/test/java/org/apache/flume/tools/TestVersionInfo.java
index 59457f96..b9276110 100644
--- a/flume-ng-core/src/test/java/org/apache/flume/tools/TestVersionInfo.java
+++ b/flume-ng-core/src/test/java/org/apache/flume/tools/TestVersionInfo.java
@@ -16,42 +16,154 @@
*/
package org.apache.flume.tools;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
+import java.net.URI;
+import java.time.Instant;
+import java.util.List;
+import java.util.Properties;
+import java.util.jar.Attributes;
import org.junit.Test;
public class TestVersionInfo {
- private static final Logger logger = LogManager.getLogger();
+ private static final String PURL =
"pkg:maven/org.apache.flume/[email protected]";
+
+ private static final String BUNDLE_SCM =
"url=\"https://gitbox.apache.org/repos/asf/logging-flume.git\","
+ +
"connection=\"scm:git:https://gitbox.apache.org/repos/asf/logging-flume.git\","
+ +
"developer-connection=\"scm:git:https://gitbox.apache.org/repos/asf/logging-flume.git\","
+ + "tag=\"rel/2.0.0\"";
/**
- * Make sure that Unknown is expected when no version info
+ * Checks the metadata of the artifact the test runs against.
+ *
+ * <p>BND writes the manifest to the output directory before the tests
run, so the values are
+ * available whether Flume is loaded from a JAR or from the compiled
classes.
*/
@Test
- public void testVersionInfoUnknown() {
+ public void testMetadataOfOwnArtifact() {
+ assertTrue(
+ "getVersion returned " + VersionInfo.getVersion(),
+ VersionInfo.getVersion().matches("\\d+\\.\\d+.*"));
+ assertTrue(
+ "getPurl returned " + VersionInfo.getPurl(),
+
VersionInfo.getPurl().startsWith("pkg:maven/org.apache.flume/flume-ng-core@"));
+ // Downstream builds override `<scm>`, so only check invariants:
+ // a valid URL, and a tag that does not betray an unset `<scm><tag>`.
+ assertTrue(
+ "getUrl returned " + VersionInfo.getUrl(),
+
URI.create(VersionInfo.getUrl()).toString().startsWith("https://"));
+ assertFalse(
+ "getBranch returned " + VersionInfo.getBranch(),
+ List.of("", "Unknown", "HEAD", "master", "main",
"trunk").contains(VersionInfo.getBranch()));
+ // Throws if the timestamp is not ISO-8601.
+ Instant.parse(VersionInfo.getDate());
+ assertTrue(
+ "getBuildVersion returned " + VersionInfo.getBuildVersion(),
+ VersionInfo.getBuildVersion().matches(".+ from .+ built on
.+"));
+ }
- logger.debug("Flume " + VersionInfo.getVersion());
- logger.debug("Subversion " + VersionInfo.getUrl() + " -r " +
VersionInfo.getRevision());
- logger.debug("Compiled by " + VersionInfo.getUser() + " on " +
VersionInfo.getDate());
- logger.debug("From source with checksum " +
VersionInfo.getSrcChecksum());
- logger.debug("Flume " + VersionInfo.getBuildVersion());
+ @Test
+ @SuppressWarnings({"deprecation", "removal"})
+ public void testUnrecordedMetadata() {
+ assertEquals("Unknown", VersionInfo.getRevision());
+ assertEquals("Unknown", VersionInfo.getUser());
+ assertEquals("Unknown", VersionInfo.getSrcChecksum());
+ }
- assertTrue("getVersion returned Unknown",
!VersionInfo.getVersion().equals("Unknown"));
- assertTrue("getUser returned Unknown",
!VersionInfo.getUser().equals("Unknown"));
- assertTrue("getUrl returned Unknown",
!VersionInfo.getUrl().equals("Unknown"));
- assertTrue(
- "getSrcChecksum returned Unknown",
!VersionInfo.getSrcChecksum().equals("Unknown"));
+ @Test
+ public void testVersionPrefersTheManifest() {
+ Attributes manifest = new Attributes();
+ manifest.putValue("Implementation-Version", "2.0.0");
+ assertEquals("2.0.0", VersionInfo.version(manifest,
pomProperties("1.11.0")));
+ }
- // check getBuildVersion() return format
- assertTrue(
- "getBuildVersion returned unexpected format",
- VersionInfo.getBuildVersion().matches(".+from.+by.+on.+source
checksum.+"));
+ @Test
+ public void testVersionFallsBackToPomProperties() {
+ assertEquals("1.11.0", VersionInfo.version(new Attributes(),
pomProperties("1.11.0")));
+ }
+
+ @Test
+ public void testVersionWithoutAnySource() {
+ assertEquals("Unknown", VersionInfo.version(new Attributes(), new
Properties()));
+ }
+
+ /** A present but blank header must not shadow the Maven descriptor. */
+ @Test
+ public void testVersionIgnoresBlankHeader() {
+ Attributes manifest = new Attributes();
+ manifest.putValue("Implementation-Version", " ");
+ assertEquals("1.11.0", VersionInfo.version(manifest,
pomProperties("1.11.0")));
+ }
+
+ @Test
+ public void testPurlPrefersTheManifest() {
+ Attributes manifest = new Attributes();
+ manifest.putValue("Purl", PURL);
+ assertEquals(PURL, VersionInfo.purl(manifest,
pomProperties("1.11.0")));
+ }
+
+ @Test
+ public void testPurlIsBuiltFromPomProperties() {
+ assertEquals(
+ "pkg:maven/org.apache.flume/[email protected]",
+ VersionInfo.purl(new Attributes(), pomProperties("1.11.0")));
+ }
+
+ @Test
+ public void testPurlWithoutAnySource() {
+ assertEquals("Unknown", VersionInfo.purl(new Attributes(), new
Properties()));
+ }
+
+ /** A present but blank header must not shadow the Maven descriptor. */
+ @Test
+ public void testPurlIgnoresBlankHeader() {
+ Attributes manifest = new Attributes();
+ manifest.putValue("Purl", " ");
+ assertEquals(
+ "pkg:maven/org.apache.flume/[email protected]",
VersionInfo.purl(manifest, pomProperties("1.11.0")));
+ }
+
+ /** A manifest of an artifact Flume was shaded into must not be mistaken
for our own. */
+ @Test
+ public void testForeignManifestIsRejected() {
+ Attributes foreign = new Attributes();
+ foreign.putValue("Purl", "pkg:maven/com.example/[email protected]");
+ foreign.putValue("Implementation-Version", "1.0.0");
+ assertFalse(VersionInfo.isOwn(foreign));
+ assertFalse(VersionInfo.isOwn(new Attributes()));
+
+ Attributes own = new Attributes();
+ own.putValue("Purl", PURL);
+ assertTrue(VersionInfo.isOwn(own));
+ }
+
+ @Test
+ public void testScmAttributes() {
+ assertEquals("rel/2.0.0", VersionInfo.scmAttribute(BUNDLE_SCM, "tag"));
+ assertEquals(
+ "https://gitbox.apache.org/repos/asf/logging-flume.git",
VersionInfo.scmAttribute(BUNDLE_SCM, "url"));
+ assertEquals(
+
"scm:git:https://gitbox.apache.org/repos/asf/logging-flume.git",
+ VersionInfo.scmAttribute(BUNDLE_SCM, "developer-connection"));
+ assertNull(VersionInfo.scmAttribute(BUNDLE_SCM, "revision"));
+ assertNull(VersionInfo.scmAttribute(null, "tag"));
+ }
+
+ /** OSGi only requires quoting for values with special characters. */
+ @Test
+ public void testScmAttributeWithoutQuotes() {
+ assertEquals("rel/2.0.0",
VersionInfo.scmAttribute("url=https://example.org,tag=rel/2.0.0", "tag"));
+ }
- // "Unknown" when build without svn or git
- assertNotNull("getRevision returned null", VersionInfo.getRevision());
- assertNotNull("getBranch returned null", VersionInfo.getBranch());
+ private static Properties pomProperties(String version) {
+ Properties properties = new Properties();
+ properties.setProperty("groupId", "org.apache.flume");
+ properties.setProperty("artifactId", "flume-ng-core");
+ properties.setProperty("version", version);
+ return properties;
}
}
diff --git a/flume-ng-dist/pom.xml b/flume-ng-dist/pom.xml
index 6e92bc1d..2faad49d 100644
--- a/flume-ng-dist/pom.xml
+++ b/flume-ng-dist/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-ng-instrumentation/flume-ganglia-monitor/pom.xml
b/flume-ng-instrumentation/flume-ganglia-monitor/pom.xml
index 1911b120..cb357256 100644
--- a/flume-ng-instrumentation/flume-ganglia-monitor/pom.xml
+++ b/flume-ng-instrumentation/flume-ganglia-monitor/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-instrumentation</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-instrumentation</groupId>
diff --git a/flume-ng-instrumentation/flume-http-monitor/pom.xml
b/flume-ng-instrumentation/flume-http-monitor/pom.xml
index 6c266c68..e1e33e69 100644
--- a/flume-ng-instrumentation/flume-http-monitor/pom.xml
+++ b/flume-ng-instrumentation/flume-http-monitor/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-instrumentation</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-instrumentation</groupId>
diff --git a/flume-ng-instrumentation/flume-prometheus-monitor/pom.xml
b/flume-ng-instrumentation/flume-prometheus-monitor/pom.xml
index 27b90fda..6d66a863 100644
--- a/flume-ng-instrumentation/flume-prometheus-monitor/pom.xml
+++ b/flume-ng-instrumentation/flume-prometheus-monitor/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-instrumentation</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-instrumentation</groupId>
diff --git a/flume-ng-instrumentation/pom.xml b/flume-ng-instrumentation/pom.xml
index e664afbb..1a049f90 100644
--- a/flume-ng-instrumentation/pom.xml
+++ b/flume-ng-instrumentation/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-ng-node/pom.xml b/flume-ng-node/pom.xml
index 40f6a4d0..5878f0f5 100644
--- a/flume-ng-node/pom.xml
+++ b/flume-ng-node/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-ng-sdk/pom.xml b/flume-ng-sdk/pom.xml
index bbe85ee1..c5b1d20d 100644
--- a/flume-ng-sdk/pom.xml
+++ b/flume-ng-sdk/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
@@ -90,6 +90,20 @@
<goals>
<goal>test-jar</goal>
</goals>
+ <configuration>
+ <!-- BND describes the main classes in a single manifest per
module, which `logging-parent`
+ feeds to every execution. Drop it here: the test JAR is not
that bundle, and its
+ Package URL needs the qualifiers of a classified artifact.
-->
+ <archive combine.self="override">
+ <manifest>
+
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ </manifest>
+ <manifestEntries>
+
<Purl>pkg:maven/${project.groupId}/${project.artifactId}@${project.version}?classifier=tests&type=test-jar</Purl>
+ </manifestEntries>
+ </archive>
+ </configuration>
</execution>
</executions>
</plugin>
diff --git a/flume-ng-sources/flume-http-source/pom.xml
b/flume-ng-sources/flume-http-source/pom.xml
index 43770d96..d7f2b585 100644
--- a/flume-ng-sources/flume-http-source/pom.xml
+++ b/flume-ng-sources/flume-http-source/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-sources</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-sources</groupId>
diff --git a/flume-ng-sources/flume-netcat-source/pom.xml
b/flume-ng-sources/flume-netcat-source/pom.xml
index d3292661..5c8becc1 100644
--- a/flume-ng-sources/flume-netcat-source/pom.xml
+++ b/flume-ng-sources/flume-netcat-source/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-sources</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-sources</groupId>
diff --git a/flume-ng-sources/flume-syslog-source/pom.xml
b/flume-ng-sources/flume-syslog-source/pom.xml
index e45b597f..1f0beb2f 100644
--- a/flume-ng-sources/flume-syslog-source/pom.xml
+++ b/flume-ng-sources/flume-syslog-source/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-sources</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-sources</groupId>
diff --git a/flume-ng-sources/flume-taildir-source/pom.xml
b/flume-ng-sources/flume-taildir-source/pom.xml
index 89edc395..d371c0f3 100644
--- a/flume-ng-sources/flume-taildir-source/pom.xml
+++ b/flume-ng-sources/flume-taildir-source/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-sources</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
</parent>
<groupId>org.apache.flume.flume-ng-sources</groupId>
diff --git a/flume-ng-sources/pom.xml b/flume-ng-sources/pom.xml
index 3318e3fd..5e12ea54 100644
--- a/flume-ng-sources/pom.xml
+++ b/flume-ng-sources/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>
diff --git a/flume-parent/pom.xml b/flume-parent/pom.xml
index f02aa175..8036ba0a 100644
--- a/flume-parent/pom.xml
+++ b/flume-parent/pom.xml
@@ -28,7 +28,7 @@
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<packaging>pom</packaging>
<name>Apache Flume Parent</name>
@@ -59,7 +59,7 @@
<scm child.scm.connection.inherit.append.path="false"
child.scm.developerConnection.inherit.append.path="false"
child.scm.url.inherit.append.path="false">
<connection>scm:git:https://gitbox.apache.org/repos/asf/logging-flume.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/logging-flume.git</developerConnection>
- <tag>rel/${project.version}</tag>
+ <tag>rel/${revision}</tag>
<url>https://gitbox.apache.org/repos/asf/logging-flume.git</url>
</scm>
@@ -75,12 +75,25 @@
<properties>
+ <revision>2.0.0-SNAPSHOT</revision>
+
<!-- Version of the artifacts released from the main `logging-flume`
repository -->
- <flume-project.version>2.0.0-SNAPSHOT</flume-project.version>
+ <flume-project.version>${revision}</flume-project.version>
<!-- The website is generated by Antora from `flume-project`: skip the
per-module `maven-site-plugin` sites. -->
<maven.site.skip>true</maven.site.skip>
- <!-- Update for year of distribution. Should be set by the
maven-release-plugin at release time. -->
-
<project.build.outputTimestamp>2022-01-02T00:00:00Z</project.build.outputTimestamp>
+ <!-- Dummy value; overwritten by CI at release time. Do not edit manually.
-->
+
<project.build.outputTimestamp>2026-01-01T00:00:00Z</project.build.outputTimestamp>
+
+ <!-- Append build metadata to the manifest generated by BND in
`logging-parent`.
+ `Bundle-SCM` is specified by OSGi Core R8, section 3.2.1;
`logging-parent` strips the header
+ because inheritance assembly corrupts `project.scm.url`. Flume sets
+ `child.scm.*.inherit.append.path="false"`, so its value is correct:
keep the header.
+ Neither the JAR File Specification nor OSGi define a header for the
build timestamp or the
+ Package URL, so `Implementation-Timestamp` and `Purl` are
Flume-specific. -->
+ <bnd-extra-config>-removeheaders: Bundle-DocURL,Bundle-Developers
+
+ Implementation-Timestamp: ${project.build.outputTimestamp}
+ Purl:
pkg:maven/${project.groupId}/${project.artifactId}@${project.version}</bnd-extra-config>
<!-- Set default encoding to UTF-8 to remove maven complaints -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/flume-tools/pom.xml b/flume-tools/pom.xml
index 7d58b3fb..9d3d65fb 100644
--- a/flume-tools/pom.xml
+++ b/flume-tools/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.flume</groupId>
<artifactId>flume-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>${revision}</version>
<relativePath>../flume-parent/pom.xml</relativePath>
</parent>