From 056c3fb5389688dafc8b84645a814e48d34075fb Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Wed, 10 Jul 2024 19:07:00 +0200 Subject: [PATCH] Better handling of MANIFEST.MF attributes Previously, the build script would add these two attributes irrespective whether or not they'd exist in the Graal artefacts: Specification-Version Implementation-Version With this patch, only updates to the Implementation-Version attribute are done based on the maven version in use. Specification-Version is only added if it's not yet there in a jar or source jar file. (cherry picked from commit 48c154e09da76394c09f3ed9b1ae03ed699d0df5) --- build.java | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/build.java b/build.java index 5ea095c..8cfc3d0 100644 --- a/build.java +++ b/build.java @@ -3,6 +3,8 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; @@ -33,6 +35,8 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.jar.Attributes; +import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -605,6 +609,8 @@ private static String required(String name, Map> args, bool class SequentialBuild { static final Logger LOG = LogManager.getLogger(SequentialBuild.class); + private static final String SPECIFICATION_VERSION_NAME = "Specification-Version"; + private static final String IMPLEMENTATION_VERSION_NAME = "Implementation-Version"; final FileSystem fs; final OperatingSystem os; final Mx mx; @@ -668,7 +674,7 @@ private BiConsumer amendOrCreateManifest(Options options, Tasks. } Files.createFile(manifestPath); } - Tasks.FileReplace.replace(new Tasks.FileReplace(manifestPath, amendManifest(options)), replace); + amendManifest(manifestPath, options); } catch (IOException e) { @@ -683,15 +689,31 @@ private BiConsumer amendOrCreateManifest(Options options, Tasks. * These attributes are accessed by Red Hat Build of Quarkus to verify that the correct artifacts are being used. * The value of Specification-Version is not that important, but the Implementation-Version should match the version of the native-image. */ - private static Function, List> amendManifest(Options options) - { - return lines -> - { - List result = lines.collect(Collectors.toList()); - result.add("Specification-Version: 0.0"); - result.add("Implementation-Version: " + options.mavenVersion); - return result; - }; + private static void amendManifest(Path manifestPath, Options options) + { + Manifest mf = null; + try (InputStream is = Files.newInputStream(manifestPath)) { + mf = new Manifest(is); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + Attributes attributes = mf.getMainAttributes(); + // Replace Implementation-Version if present, otherwise add it. + attributes.putValue(IMPLEMENTATION_VERSION_NAME, options.mavenVersion); + String specVers = attributes.getValue(SPECIFICATION_VERSION_NAME); + if (specVers == null) { + // Only add Specification-Version if not already present + attributes.putValue(SPECIFICATION_VERSION_NAME, "0.0"); + } + String manifestVers = attributes.getValue(Attributes.Name.MANIFEST_VERSION); + if (manifestVers == null) { + attributes.putValue("Manifest-Version", "1.0"); + } + try (OutputStream out = Files.newOutputStream(manifestPath, StandardOpenOption.TRUNCATE_EXISTING)) { + mf.write(out); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } } }