8357404: jpackage should attempt to get a package version from the JDK's release file if the --version option is not specified [v10]

This commit is contained in:
alexander_matveev 2026-02-12 19:26:42 -08:00
parent 6a644426c6
commit a7d5c14ebd
6 changed files with 54 additions and 58 deletions

View File

@ -27,6 +27,7 @@ package jdk.jpackage.internal;
import static jdk.jpackage.internal.FromOptions.buildApplicationBuilder;
import static jdk.jpackage.internal.FromOptions.createPackageBuilder;
import static jdk.jpackage.internal.LinuxPackagingPipeline.APPLICATION_LAYOUT;
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_LINUX_RPM;
import static jdk.jpackage.internal.cli.StandardOption.APP_VERSION;
import static jdk.jpackage.internal.cli.StandardOption.LINUX_APP_CATEGORY;
import static jdk.jpackage.internal.cli.StandardOption.LINUX_DEB_MAINTAINER_EMAIL;
@ -52,10 +53,6 @@ import jdk.jpackage.internal.model.StandardPackageType;
final class LinuxFromOptions {
static LinuxApplication createLinuxApplication(Options options) {
return createLinuxApplication(options, Optional.empty());
}
static LinuxApplication createLinuxApplication(Options options, Optional<StandardPackageType> type) {
final var launcherFromOptions = new LauncherFromOptions().faWithDefaultDescription();
@ -78,11 +75,9 @@ final class LinuxFromOptions {
if (!APP_VERSION.containsIn(options)) {
// User didn't explicitly specify the version on the command line. jpackage derived it from the input.
// In this case it should ensure the derived value is valid RPM version.
if (type.isPresent()) {
if (type.get().equals(LINUX_RPM)) {
app = ApplicationBuilder.normalizeVersion(app, app.version(),
LinuxFromOptions::normalizeRpmVersion);
}
if (OptionUtils.bundlingOperation(options) == CREATE_LINUX_RPM) {
app = ApplicationBuilder.normalizeVersion(app, app.version(),
LinuxFromOptions::normalizeRpmVersion);
}
}
@ -120,7 +115,7 @@ final class LinuxFromOptions {
private static LinuxPackageBuilder createLinuxPackageBuilder(Options options, LinuxSystemEnvironment sysEnv, StandardPackageType type) {
final var app = createLinuxApplication(options, Optional.of(type));
final var app = createLinuxApplication(options);
final var superPkgBuilder = createPackageBuilder(options, app, type);

View File

@ -43,8 +43,6 @@ import static jdk.jpackage.internal.cli.StandardOption.WIN_UPDATE_URL;
import static jdk.jpackage.internal.cli.StandardOption.WIN_UPGRADE_UUID;
import static jdk.jpackage.internal.model.StandardPackageType.WIN_MSI;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.function.UnaryOperator;
import jdk.jpackage.internal.cli.Options;
@ -130,11 +128,11 @@ final class WinFromOptions {
}
static String normalizeVersion(String version) {
// Windows requires 2 or 4 components version string.
// Windows requires between 2 and 4 components version string.
// When reading from release file it can be 1 or 3 or maybe more.
// We will always normalize to 4 components if needed.
DottedVersion ver = DottedVersion.lazy(version);
if (ver.getComponentsCount() != 2 && ver.getComponentsCount() != 4) {
if (ver.getComponentsCount() < 2 || ver.getComponentsCount() > 4) {
return ver.trim(4).pad(4).toComponentsString();
} else {
// We should drop any characters. For example: "-ea".

View File

@ -248,11 +248,6 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
return getArgumentValue("--input", () -> null, Path::of);
}
private boolean isLinuxRpmPackageType() {
return TKit.isLinux() && (PackageType.LINUX_RPM == getArgumentValue("--type",
() -> null, PACKAGE_TYPES::get));
}
public String version() {
return Optional.ofNullable(getArgumentValue("--app-version")).or(() -> {
if (isRuntime()) {
@ -260,15 +255,18 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
Path.of(getArgumentValue("--runtime-image")));
final var releaseFile = RuntimeImageUtils.getReleaseFilePath(runtimeHome);
return RuntimeVersionReader.readVersion(releaseFile).map(releaseVersion -> {
if (TKit.isWindows()) {
return WindowsHelper.getNormalizedVersion(releaseVersion.toString());
} else if (TKit.isOSX()) {
return MacHelper.getNormalizedVersion(releaseVersion.toString());
} else if (isLinuxRpmPackageType()) {
return LinuxHelper.getNormalizedRpmVersion(releaseVersion.toString());
} else {
return releaseVersion.toString();
switch (packageType()) {
case WIN_EXE, WIN_MSI -> {
return WindowsHelper.getNormalizedVersion(releaseVersion.toString());
}
case MAC_DMG, MAC_PKG -> {
return MacHelper.getNormalizedVersion(releaseVersion.toString());
}
case LINUX_RPM -> {
return LinuxHelper.getNormalizedRpmVersion(releaseVersion.toString());
}
}
return releaseVersion.toString();
});
} else {
return Optional.empty();

View File

@ -42,7 +42,6 @@ import java.io.UncheckedIOException;
import java.lang.constant.ClassDesc;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.LinkOption;

View File

@ -58,10 +58,10 @@ public class WindowsHelper {
}
static String getNormalizedVersion(String version) {
// Windows requires 2 or 4 components version string.
// Windows requires between 2 and 4 components version string.
// We will always normalize to 4 components if needed.
DottedVersion ver = DottedVersion.lazy(version);
if (ver.getComponentsCount() != 2 && ver.getComponentsCount() != 4) {
if (ver.getComponentsCount() < 2 || ver.getComponentsCount() > 4) {
return ver.trim(4).pad(4).toComponentsString();
} else {
return ver.toComponentsString();

View File

@ -39,6 +39,7 @@ import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.JPackageStringBundle;
import jdk.jpackage.test.JPackageOutputValidator;
import jdk.jpackage.test.LinuxHelper;
import jdk.jpackage.test.MacHelper;
import jdk.jpackage.test.PackageTest;
@ -115,14 +116,6 @@ public class RuntimePackageTest {
.run(Action.CREATE_AND_UNPACK);
}
@Test
@Parameter(value = {"foo"})
@Parameter(value = {""})
@Parameter(value = {"17.21.3+foo"})
public static void testInvalidReleaseFileVersion(String version) {
testReleaseFileVersion(version, false, Optional.empty());
}
@Test
@Parameter(value = {"17.21.3-ea", "LINUX_DEB"}, ifOS = LINUX)
public static void testValidReleaseFileVersion(String version, PackageType... packageTypes) {
@ -136,35 +129,38 @@ public class RuntimePackageTest {
}
@Test
// Invalid versions
@Parameter(value = {"foo", "1.0"})
@Parameter(value = {"", "1.0"})
@Parameter(value = {"17.21.3+foo", "1.0"})
// 27
@Parameter(value = {"27"}, ifOS = {LINUX, MACOS})
@Parameter(value = {"27", "27.0.0.0"}, ifOS = WINDOWS)
// 27.1
@Parameter(value = {"27.1"})
// 27.1.2
@Parameter(value = {"27.1.2"}, ifOS = {LINUX, MACOS})
@Parameter(value = {"27.1.2"})
// 27.1.2.3
@Parameter(value = {"27.1.2.3"}, ifOS = {LINUX, WINDOWS})
// 27.1.2.3.4
@Parameter(value = {"27.1.2.3.4"}, ifOS = LINUX)
public static void testValidReleaseFileVersion(String version) {
testReleaseFileVersion(version, true, Optional.empty());
}
@Test
// 27
@Parameter(value = {"27", "27.0.0.0"}, ifOS = WINDOWS)
// 27.1.2
@Parameter(value = {"27.1.2", "27.1.2.0"}, ifOS = WINDOWS)
// 27.1.2.3
@Parameter(value = {"27.1.2.3", "27.1.2"}, ifOS = MACOS)
// 27.1.2.3.4
@Parameter(value = {"27.1.2.3.4"}, ifOS = LINUX)
@Parameter(value = {"27.1.2.3.4", "27.1.2"}, ifOS = MACOS)
@Parameter(value = {"27.1.2.3.4", "27.1.2.3"}, ifOS = WINDOWS)
// 17.21.3-ea
@Parameter(value = {"17.21.3-ea", "17.21.3"}, ifOS = MACOS)
@Parameter(value = {"17.21.3-ea", "17.21.3.0"}, ifOS = WINDOWS)
public static void testValidReleaseFileVersion(String version, String normalizedVersion) {
testReleaseFileVersion(version, true, Optional.of(normalizedVersion));
public static void testValidReleaseFileVersion(String version, String... appVersion) {
if (version.equals("1.0")) {
// This is a special case of the default app version. Don't use it as a test input.
throw new IllegalArgumentException();
}
if (appVersion.length == 0) {
testReleaseFileVersion(version, false, Optional.of(version));
} else {
boolean isValid = !appVersion[0].equals("1.0");
testReleaseFileVersion(version, isValid, Optional.of(appVersion[0]));
}
}
private static void testReleaseFileVersion(String version,
@ -196,14 +192,24 @@ public class RuntimePackageTest {
// Validate output only if release version is valid for release file
if (validReleaseFileVersion) {
cmd.validateOutput(JPackageStringBundle.MAIN
var releaseVersionStr = JPackageStringBundle.MAIN
.cannedFormattedString("message.release-version",
version, runtimeImage.toString()));
version, runtimeImage.toString());
new JPackageOutputValidator()
.expectMatchingStrings(releaseVersionStr)
.matchTimestamps()
.stripTimestamps()
.applyTo(cmd);
// Normalization message is only printed if we did normalization.
normalizedVersion.ifPresent(nv -> {
cmd.validateOutput(JPackageStringBundle.MAIN
.cannedFormattedString("message.version-normalized",
nv, version));
var versionNormalizedStr = JPackageStringBundle.MAIN
.cannedFormattedString("message.version-normalized",
nv, version);
new JPackageOutputValidator()
.expectMatchingStrings(versionNormalizedStr)
.matchTimestamps()
.stripTimestamps()
.applyTo(cmd);
});
}
})