mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-01 03:30:34 +00:00
8357404: jpackage should attempt to get a package version from the JDK's release file if the --version option is not specified [v9]
This commit is contained in:
parent
17707867d4
commit
fc97db8a10
@ -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.StandardOption.APP_VERSION;
|
||||
import static jdk.jpackage.internal.cli.StandardOption.LINUX_APP_CATEGORY;
|
||||
import static jdk.jpackage.internal.cli.StandardOption.LINUX_DEB_MAINTAINER_EMAIL;
|
||||
import static jdk.jpackage.internal.cli.StandardOption.LINUX_MENU_GROUP;
|
||||
@ -37,8 +38,9 @@ import static jdk.jpackage.internal.cli.StandardOption.LINUX_RPM_LICENSE_TYPE;
|
||||
import static jdk.jpackage.internal.cli.StandardOption.LINUX_SHORTCUT_HINT;
|
||||
import static jdk.jpackage.internal.model.StandardPackageType.LINUX_DEB;
|
||||
import static jdk.jpackage.internal.model.StandardPackageType.LINUX_RPM;
|
||||
|
||||
import java.util.Optional;
|
||||
import jdk.jpackage.internal.cli.Options;
|
||||
import jdk.jpackage.internal.model.DottedVersion;
|
||||
import jdk.jpackage.internal.model.Launcher;
|
||||
import jdk.jpackage.internal.model.LinuxApplication;
|
||||
import jdk.jpackage.internal.model.LinuxDebPackage;
|
||||
@ -50,6 +52,10 @@ 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();
|
||||
|
||||
@ -67,7 +73,20 @@ final class LinuxFromOptions {
|
||||
|
||||
appBuilder.launchers().map(LinuxPackagingPipeline::normalizeShortcuts).ifPresent(appBuilder::launchers);
|
||||
|
||||
return LinuxApplication.create(appBuilder.create());
|
||||
var app = appBuilder.create();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LinuxApplication.create(app);
|
||||
}
|
||||
|
||||
static LinuxRpmPackage createLinuxRpmPackage(Options options, LinuxRpmSystemEnvironment sysEnv) {
|
||||
@ -101,7 +120,7 @@ final class LinuxFromOptions {
|
||||
|
||||
private static LinuxPackageBuilder createLinuxPackageBuilder(Options options, LinuxSystemEnvironment sysEnv, StandardPackageType type) {
|
||||
|
||||
final var app = createLinuxApplication(options);
|
||||
final var app = createLinuxApplication(options, Optional.of(type));
|
||||
|
||||
final var superPkgBuilder = createPackageBuilder(options, app, type);
|
||||
|
||||
@ -118,4 +137,15 @@ final class LinuxFromOptions {
|
||||
return pkgBuilder;
|
||||
}
|
||||
|
||||
static String normalizeRpmVersion(String version) {
|
||||
// RPM does not support "-" symbol in version. In some case
|
||||
// we might have "-" from "release" file version.
|
||||
// Normalize version if it has "-" symbols. All other supproted version
|
||||
// formats by "release" file should be supported by RPM.
|
||||
if (version.contains("-")) {
|
||||
return DottedVersion.lazy(version).toComponentsString();
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,10 +231,7 @@ final class MacFromOptions {
|
||||
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 MacOS version.
|
||||
UnaryOperator<String> versionNormalizer = version -> {
|
||||
return normalizeVersion(version);
|
||||
};
|
||||
app = ApplicationBuilder.normalizeVersion(app, app.version(), versionNormalizer);
|
||||
app = ApplicationBuilder.normalizeVersion(app, app.version(), MacFromOptions::normalizeVersion);
|
||||
}
|
||||
|
||||
final var appBuilder = new MacApplicationBuilder(app);
|
||||
@ -358,11 +355,6 @@ final class MacFromOptions {
|
||||
// When reading from release file it can be 1 or 3 or maybe more.
|
||||
// We will always normalize to 3 components if needed.
|
||||
DottedVersion ver = DottedVersion.lazy(version);
|
||||
if (ver.getComponentsCount() > 3) {
|
||||
return ver.trim(3).pad(3).toComponentsString();
|
||||
} else {
|
||||
// We should drop any characters. For example: "-ea".
|
||||
return ver.toComponentsString();
|
||||
}
|
||||
return ver.trim(3).toComponentsString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,12 +37,11 @@ import java.util.stream.Stream;
|
||||
public final class DottedVersion {
|
||||
|
||||
private DottedVersion(String version, boolean greedy) {
|
||||
this.value = version;
|
||||
if (version.isEmpty()) {
|
||||
if (greedy) {
|
||||
throw new IllegalArgumentException(I18N.getString("error.version-string-empty"));
|
||||
} else {
|
||||
this.components = new BigInteger[0];
|
||||
this.components = new Component[0];
|
||||
this.suffix = "";
|
||||
}
|
||||
} else {
|
||||
@ -58,7 +57,7 @@ public final class DottedVersion {
|
||||
}
|
||||
|
||||
try {
|
||||
return new BigInteger(digits);
|
||||
return new Component(digits);
|
||||
} catch (NumberFormatException ex) {
|
||||
if (!greedy) {
|
||||
return null;
|
||||
@ -68,7 +67,7 @@ public final class DottedVersion {
|
||||
digits));
|
||||
}
|
||||
}
|
||||
}).takeWhile(Objects::nonNull).toArray(BigInteger[]::new);
|
||||
}).takeWhile(Objects::nonNull).toArray(Component[]::new);
|
||||
suffix = ds.getUnprocessedString();
|
||||
if (!suffix.isEmpty() && greedy) {
|
||||
ds.throwException();
|
||||
@ -76,6 +75,11 @@ public final class DottedVersion {
|
||||
}
|
||||
}
|
||||
|
||||
private DottedVersion(Component[] components, String suffix) {
|
||||
this.components = components;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
private static class DigitsSupplier {
|
||||
|
||||
DigitsSupplier(String input) {
|
||||
@ -211,9 +215,31 @@ public final class DottedVersion {
|
||||
return Arrays.deepEquals(this.components, other.components);
|
||||
}
|
||||
|
||||
public DottedVersion trim(int limit) {
|
||||
if (limit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (limit >= components.length) {
|
||||
return this;
|
||||
} else {
|
||||
return new DottedVersion(Arrays.copyOf(components, limit), suffix);
|
||||
}
|
||||
}
|
||||
|
||||
public DottedVersion pad(int limit) {
|
||||
if (limit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (limit <= components.length) {
|
||||
return this;
|
||||
} else {
|
||||
var newComponents = Arrays.copyOf(components, limit);
|
||||
Arrays.fill(newComponents, components.length, newComponents.length, Component.ZERO);
|
||||
return new DottedVersion(newComponents, suffix);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
return Stream.of(components).map(Component::toString).collect(Collectors.joining(".")) + suffix;
|
||||
}
|
||||
|
||||
public String getUnprocessedSuffix() {
|
||||
@ -221,35 +247,7 @@ public final class DottedVersion {
|
||||
}
|
||||
|
||||
public String toComponentsString() {
|
||||
return Stream.of(components).map(BigInteger::toString).collect(Collectors.joining("."));
|
||||
}
|
||||
|
||||
public DottedVersion trim(int componentLimit) {
|
||||
if (componentLimit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (components.length > componentLimit) {
|
||||
components = Arrays.stream(components).limit(componentLimit)
|
||||
.toArray(BigInteger[]::new);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DottedVersion pad(int componentLimit) {
|
||||
if (componentLimit <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (components.length < componentLimit) {
|
||||
final int origLength = components.length;
|
||||
components = Arrays.copyOf(components, componentLimit);
|
||||
Arrays.fill(components, origLength, components.length,
|
||||
new BigInteger("0"));
|
||||
}
|
||||
|
||||
return this;
|
||||
return Stream.of(components).map(Component::parsedValue).map(BigInteger::toString).collect(Collectors.joining("."));
|
||||
}
|
||||
|
||||
public int getComponentsCount() {
|
||||
@ -257,10 +255,27 @@ public final class DottedVersion {
|
||||
}
|
||||
|
||||
public BigInteger[] getComponents() {
|
||||
return components;
|
||||
return Stream.of(components).map(Component::parsedValue).toArray(BigInteger[]::new);
|
||||
}
|
||||
|
||||
private BigInteger[] components;
|
||||
private final String value;
|
||||
private record Component(BigInteger parsedValue, String strValue) {
|
||||
Component {
|
||||
Objects.requireNonNull(parsedValue);
|
||||
Objects.requireNonNull(strValue);
|
||||
}
|
||||
|
||||
Component(String strValue) {
|
||||
this(new BigInteger(strValue), strValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return strValue;
|
||||
}
|
||||
|
||||
static final Component ZERO = new Component(BigInteger.ZERO, "0");
|
||||
}
|
||||
|
||||
private final Component[] components;
|
||||
private final String suffix;
|
||||
}
|
||||
|
||||
@ -86,10 +86,7 @@ final class WinFromOptions {
|
||||
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 Windows version.
|
||||
UnaryOperator<String> versionNormalizer = version -> {
|
||||
return normalizeVersion(version);
|
||||
};
|
||||
app = ApplicationBuilder.normalizeVersion(app, app.version(), versionNormalizer);
|
||||
app = ApplicationBuilder.normalizeVersion(app, app.version(), WinFromOptions::normalizeVersion);
|
||||
}
|
||||
|
||||
return WinApplication.create(app);
|
||||
@ -137,7 +134,7 @@ final class WinFromOptions {
|
||||
// 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".
|
||||
|
||||
@ -248,6 +248,11 @@ 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()) {
|
||||
@ -259,6 +264,8 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.jpackage.internal.model.DottedVersion;
|
||||
import jdk.jpackage.internal.util.PathUtils;
|
||||
import jdk.jpackage.internal.util.function.ThrowingConsumer;
|
||||
import jdk.jpackage.test.LauncherShortcut.InvokeShortcutSpec;
|
||||
@ -127,6 +128,18 @@ public final class LinuxHelper {
|
||||
getDefaultPackageArch(packageType)) + packageType.getSuffix();
|
||||
}
|
||||
|
||||
static String getNormalizedRpmVersion(String version) {
|
||||
// RPM does not support "-" symbol in version. In some case
|
||||
// we might have "-" from "release" file version.
|
||||
// Normalize version if it has "-" symbols. All other supproted version
|
||||
// formats by "release" file should be supported by RPM.
|
||||
if (version.contains("-")) {
|
||||
return DottedVersion.lazy(version).toComponentsString();
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
public static Stream<Path> getPackageFiles(JPackageCommand cmd) {
|
||||
cmd.verifyIsOfType(PackageType.LINUX);
|
||||
|
||||
|
||||
@ -1114,11 +1114,7 @@ public final class MacHelper {
|
||||
// macOS requires 1, 2 or 3 components version string.
|
||||
// We will always normalize to 3 components if needed.
|
||||
DottedVersion ver = DottedVersion.lazy(version);
|
||||
if (ver.getComponentsCount() > 3) {
|
||||
return ver.trim(3).pad(3).toComponentsString();
|
||||
} else {
|
||||
return ver.toComponentsString();
|
||||
}
|
||||
return ver.trim(3).toComponentsString();
|
||||
}
|
||||
|
||||
static Path getInstallationDirectory(JPackageCommand cmd) {
|
||||
|
||||
@ -61,7 +61,7 @@ public class WindowsHelper {
|
||||
// Windows requires 2 or 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();
|
||||
|
||||
@ -32,8 +32,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@ -41,34 +44,26 @@ public class DottedVersionTest {
|
||||
|
||||
public record TestConfig(String input,
|
||||
Function<String, DottedVersion> createVersion, String expectedSuffix,
|
||||
int expectedComponentCount, String expectedToComponent, int numberOfComponents) {
|
||||
int expectedComponentCount, String expectedToComponent) {
|
||||
|
||||
TestConfig(String input, Type type, int expectedComponentCount, String expectedToComponent) {
|
||||
this(input, type.createVersion, "", expectedComponentCount, expectedToComponent, -1);
|
||||
this(input, type.createVersion, "", expectedComponentCount, expectedToComponent);
|
||||
}
|
||||
|
||||
TestConfig(String input, Type type, int expectedComponentCount) {
|
||||
this(input, type.createVersion, "", expectedComponentCount, input, -1);
|
||||
}
|
||||
|
||||
TestConfig(String input, Type type, String expectedToComponent, int numberOfComponents) {
|
||||
this(input, type.createVersion, "", -1, expectedToComponent, numberOfComponents);
|
||||
this(input, type.createVersion, "", expectedComponentCount, input);
|
||||
}
|
||||
|
||||
static TestConfig greedy(String input, int expectedComponentCount, String expectedToComponent) {
|
||||
return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, expectedToComponent, -1);
|
||||
return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, expectedToComponent);
|
||||
}
|
||||
|
||||
static TestConfig greedy(String input, int expectedComponentCount) {
|
||||
return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, input, -1);
|
||||
return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, input);
|
||||
}
|
||||
|
||||
static TestConfig lazy(String input, String expectedSuffix, int expectedComponentCount, String expectedToComponent) {
|
||||
return new TestConfig(input, Type.LAZY.createVersion, expectedSuffix, expectedComponentCount, expectedToComponent, -1);
|
||||
}
|
||||
|
||||
static TestConfig lazy(String input, String expectedToComponent, int numberOfComponents) {
|
||||
return new TestConfig(input, Type.LAZY.createVersion, "", -1, expectedToComponent, numberOfComponents);
|
||||
return new TestConfig(input, Type.LAZY.createVersion, expectedSuffix, expectedComponentCount, expectedToComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,42 +119,99 @@ public class DottedVersionTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testTrim(TestConfig cfg) {
|
||||
var dv = cfg.createVersion.apply(cfg.input());
|
||||
assertEquals(cfg.expectedToComponent(),
|
||||
dv.trim(cfg.numberOfComponents()).toComponentsString());
|
||||
}
|
||||
|
||||
private static List<TestConfig> testTrim() {
|
||||
List<TestConfig> data = new ArrayList<>();
|
||||
data.addAll(List.of(
|
||||
TestConfig.lazy("", "", 0),
|
||||
TestConfig.lazy("1", "", 0),
|
||||
TestConfig.lazy("1.2.3", "1", 1),
|
||||
TestConfig.lazy("1.2.3", "1.2", 2),
|
||||
TestConfig.lazy("1.2.3", "1.2.3", 3),
|
||||
TestConfig.lazy("1.2.3", "1.2.3", 4)
|
||||
));
|
||||
return data;
|
||||
public void testTrim(DottedVersion ver, String expectedStr, int limit) {
|
||||
var expected = DottedVersion.lazy(expectedStr);
|
||||
var actual = ver.trim(limit);
|
||||
assertEquals(expected, actual);
|
||||
if (limit >= ver.getComponents().length) {
|
||||
assertSame(ver, actual);
|
||||
} else {
|
||||
assertNotSame(ver, actual);
|
||||
}
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testPad(TestConfig cfg) {
|
||||
var dv = cfg.createVersion.apply(cfg.input());
|
||||
assertEquals(cfg.expectedToComponent(),
|
||||
dv.pad(cfg.numberOfComponents()).toComponentsString());
|
||||
public void testTrimNegative(DottedVersion ver, int limit) {
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> {
|
||||
ver.trim(limit);
|
||||
});
|
||||
}
|
||||
|
||||
private static List<TestConfig> testPad() {
|
||||
List<TestConfig> data = new ArrayList<>();
|
||||
data.addAll(List.of(
|
||||
TestConfig.lazy("", "0", 1),
|
||||
TestConfig.lazy("1", "1", 1),
|
||||
TestConfig.lazy("1", "1.0", 2),
|
||||
TestConfig.lazy("1.2.3", "1.2.3.0.0", 5)
|
||||
));
|
||||
return data;
|
||||
private static Stream<Arguments> testTrim() {
|
||||
|
||||
var testCases = new ArrayList<Arguments>();
|
||||
|
||||
for (var suffix : List.of("", ".foo")) {
|
||||
testCases.addAll(List.of(
|
||||
Arguments.of("1.02.3" + suffix, "" + suffix, 0),
|
||||
Arguments.of("1.02.3" + suffix, "1" + suffix, 1),
|
||||
Arguments.of("1.02.3" + suffix, "1.02" + suffix, 2),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3" + suffix, 3),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3" + suffix, 4)
|
||||
));
|
||||
}
|
||||
|
||||
return testCases.stream().map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testTrimNegative() {
|
||||
return Stream.of(
|
||||
Arguments.of("10.5.foo", -1)
|
||||
).map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testPad(DottedVersion ver, String expectedStr, int limit) {
|
||||
var expected = DottedVersion.lazy(expectedStr);
|
||||
var actual = ver.pad(limit);
|
||||
assertEquals(expected, actual);
|
||||
if (limit <= ver.getComponents().length) {
|
||||
assertSame(ver, actual);
|
||||
} else {
|
||||
assertNotSame(ver, actual);
|
||||
}
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testPadNegative(DottedVersion ver, int limit) {
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> {
|
||||
ver.pad(limit);
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testPad() {
|
||||
|
||||
var testCases = new ArrayList<Arguments>();
|
||||
|
||||
for (var suffix : List.of("", ".foo")) {
|
||||
testCases.addAll(List.of(
|
||||
Arguments.of("" + suffix, "" + suffix, 0),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3" + suffix, 0),
|
||||
Arguments.of("" + suffix, "0" + suffix, 1),
|
||||
Arguments.of("1" + suffix, "1" + suffix, 1),
|
||||
Arguments.of("1" + suffix, "1.0" + suffix, 2),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3.0.0" + suffix, 5)
|
||||
));
|
||||
}
|
||||
|
||||
return testCases.stream().map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testPadNegative() {
|
||||
return Stream.of(
|
||||
Arguments.of("10.5.foo", -1)
|
||||
).map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
private static Arguments mapFirstStringToDottedVersion(Arguments v) {
|
||||
var objs = v.get();
|
||||
objs[0] = DottedVersion.lazy((String)objs[0]);
|
||||
return Arguments.of(objs);
|
||||
}
|
||||
|
||||
record InvalidVersionTestSpec(String version, String invalidComponent) {
|
||||
|
||||
@ -44,41 +44,43 @@ public class RuntimeVersionReaderTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"27.1.2, true",
|
||||
"27.1.2, false",
|
||||
"27.1.2-ea, true",
|
||||
"27.1.2-ea, false"
|
||||
"\"27.1.2\"",
|
||||
"27.1.2",
|
||||
"\"27.1.2-ea\"",
|
||||
"27.1.2-ea",
|
||||
"\"27.1.2+15\"",
|
||||
"27.1.2+15"
|
||||
})
|
||||
public void test_release_file_with_version(String version,
|
||||
boolean quoteVersion, @TempDir Path workdir) {
|
||||
public void test_release_file_with_version(String version, @TempDir Path workdir) {
|
||||
final var value = RuntimeVersionReader.readVersion(
|
||||
createPropFileWithValue(workdir, "JAVA_VERSION", version, quoteVersion));
|
||||
createPropFileWithValue(workdir, "JAVA_VERSION", version));
|
||||
assertTrue(value.isPresent());
|
||||
value.ifPresent(val -> {
|
||||
assertEquals(version, value.get().toString());
|
||||
// Version return by readVersion is always unquoted
|
||||
String expectedVersion = version.replaceAll("^\"|\"$", "");
|
||||
assertEquals(expectedVersion, value.get().toString());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"7.1.2+foo, true",
|
||||
"foo, true",
|
||||
"'', true",
|
||||
"7.1.2+foo, false",
|
||||
"foo, false",
|
||||
"'', false"
|
||||
"\"7.1.2+foo\"",
|
||||
"\"foo\"",
|
||||
"\"\"",
|
||||
"7.1.2+foo",
|
||||
"foo",
|
||||
"''"
|
||||
})
|
||||
public void test_release_file_with_invalid_version(String version,
|
||||
boolean quoteVersion, @TempDir Path workdir) {
|
||||
public void test_release_file_with_invalid_version(String version, @TempDir Path workdir) {
|
||||
final var value = RuntimeVersionReader.readVersion(
|
||||
createPropFileWithValue(workdir, "JAVA_VERSION", version, quoteVersion));
|
||||
createPropFileWithValue(workdir, "JAVA_VERSION", version));
|
||||
assertFalse(value.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_release_file_without_version(@TempDir Path workdir) {
|
||||
final var value = RuntimeVersionReader.readVersion(
|
||||
createPropFileWithValue(workdir, "JDK_VERSION", "27.1.2", true));
|
||||
createPropFileWithValue(workdir, "JDK_VERSION", "\"27.1.2\""));
|
||||
assertFalse(value.isPresent());
|
||||
}
|
||||
|
||||
@ -88,15 +90,10 @@ public class RuntimeVersionReaderTest {
|
||||
assertFalse(value.isPresent());
|
||||
}
|
||||
|
||||
private Path createPropFileWithValue(Path workdir, String name, String value,
|
||||
boolean quoteValue) {
|
||||
private Path createPropFileWithValue(Path workdir, String name, String value) {
|
||||
Path releaseFile = workdir.resolve("release");
|
||||
Properties props = new Properties();
|
||||
if (quoteValue) {
|
||||
props.setProperty(name, "\"" + value + "\"");
|
||||
} else {
|
||||
props.setProperty(name, value);
|
||||
}
|
||||
props.setProperty(name, value);
|
||||
|
||||
try (Writer writer = Files.newBufferedWriter(releaseFile)) {
|
||||
props.store(writer, null);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -62,13 +62,25 @@ public final class AppVersionTest {
|
||||
"3.3"}},
|
||||
{"7.8", "com.other/com.other.Hello", new String[]{"--app-version",
|
||||
"4", "--app-version", "7.8"}},
|
||||
// Pick version from jar
|
||||
{"3.10.17", "com.other/com.other.Hello@3.10.17", null},
|
||||
// Ignore version in jar if --app-version given
|
||||
{"7.5.81", "com.other/com.other.Hello@3.10.17", new String[]{
|
||||
"--app-version", "7.5.81"}}
|
||||
}));
|
||||
|
||||
if (TKit.isWindows()) {
|
||||
// Windows will normalize unsupproted number of components
|
||||
// for jar, module or release file versions.
|
||||
data.addAll(List.of(new Object[][]{
|
||||
// Pick version from jar
|
||||
{"3.10.17.0", "com.other/com.other.Hello@3.10.17", null},
|
||||
}));
|
||||
} else {
|
||||
data.addAll(List.of(new Object[][]{
|
||||
// Pick version from jar
|
||||
{"3.10.17", "com.other/com.other.Hello@3.10.17", null},
|
||||
}));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +28,9 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import jdk.jpackage.internal.util.MacBundle;
|
||||
import jdk.jpackage.test.AppImageFile;
|
||||
import jdk.jpackage.test.HelloApp;
|
||||
import jdk.jpackage.test.JavaAppDesc;
|
||||
@ -53,9 +55,8 @@ import jdk.jpackage.test.TKit;
|
||||
|
||||
public final class ModulePathTest3 {
|
||||
|
||||
public ModulePathTest3(String jlinkOutputSubdir, String runtimeSubdir) {
|
||||
this.jlinkOutputSubdir = Path.of(jlinkOutputSubdir);
|
||||
this.runtimeSubdir = Path.of(runtimeSubdir);
|
||||
public ModulePathTest3(RuntimeType runtimeType) {
|
||||
this.runtimeType = Objects.requireNonNull(runtimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,8 +75,24 @@ public final class ModulePathTest3 {
|
||||
HelloApp.createBundle(appDesc, moduleOutputDir);
|
||||
|
||||
final Path workDir = TKit.createTempDirectory("runtime").resolve("data");
|
||||
final Path jlinkOutputDir = workDir.resolve(jlinkOutputSubdir);
|
||||
Files.createDirectories(jlinkOutputDir.getParent());
|
||||
final Path jlinkOutputDir;
|
||||
switch (runtimeType) {
|
||||
case IMAGE -> {
|
||||
jlinkOutputDir = workDir;
|
||||
}
|
||||
case MAC_BUNDLE -> {
|
||||
var macBundle = new MacBundle(workDir);
|
||||
|
||||
// Create macOS bundle structure sufficient to pass jpackage validation.
|
||||
Files.createDirectories(macBundle.homeDir().getParent());
|
||||
Files.createDirectories(macBundle.macOsDir());
|
||||
Files.createFile(macBundle.infoPlistFile());
|
||||
jlinkOutputDir = macBundle.homeDir();
|
||||
}
|
||||
default -> {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
new Executor()
|
||||
.setToolProvider(JavaTool.JLINK)
|
||||
@ -90,21 +107,13 @@ public final class ModulePathTest3 {
|
||||
"--strip-native-commands")
|
||||
.execute();
|
||||
|
||||
if (TKit.isOSX()) {
|
||||
// MacBundle requires valid bundle
|
||||
if (Files.exists(workDir.resolve("Contents/Home"))) {
|
||||
Files.createFile(workDir.resolve("Contents/Info.plist"));
|
||||
Files.createDirectories(workDir.resolve("Contents/MacOS"));
|
||||
}
|
||||
}
|
||||
|
||||
JPackageCommand cmd = new JPackageCommand()
|
||||
.setDefaultAppName()
|
||||
.setPackageType(PackageType.IMAGE)
|
||||
.setDefaultInputOutput()
|
||||
.removeArgumentWithValue("--input")
|
||||
.addArguments("--module", appDesc.moduleName() + "/" + appDesc.className())
|
||||
.setArgumentValue("--runtime-image", workDir.resolve(runtimeSubdir));
|
||||
.setArgumentValue("--runtime-image", workDir);
|
||||
|
||||
cmd.executeAndAssertHelloAppImageCreated();
|
||||
|
||||
@ -116,23 +125,25 @@ public final class ModulePathTest3 {
|
||||
}
|
||||
|
||||
@Parameters
|
||||
public static Collection<?> data() {
|
||||
final List<String[]> paths = new ArrayList<>();
|
||||
paths.add(new String[] { "", "" });
|
||||
public static Collection<Object[]> data() {
|
||||
final List<RuntimeType> testCases = new ArrayList<>();
|
||||
testCases.add(RuntimeType.IMAGE);
|
||||
if (TKit.isOSX()) {
|
||||
// On OSX jpackage should accept both runtime root and runtime home
|
||||
// directories.
|
||||
paths.add(new String[] { "Contents/Home", "" });
|
||||
testCases.add(RuntimeType.MAC_BUNDLE);
|
||||
}
|
||||
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
for (var pathCfg : paths) {
|
||||
data.add(new Object[] { pathCfg[0], pathCfg[1] });
|
||||
}
|
||||
|
||||
return data;
|
||||
return testCases.stream().map(v -> {
|
||||
return new Object[] {v};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private final Path jlinkOutputSubdir;
|
||||
private final Path runtimeSubdir;
|
||||
public enum RuntimeType {
|
||||
IMAGE,
|
||||
MAC_BUNDLE,
|
||||
;
|
||||
}
|
||||
|
||||
private final RuntimeType runtimeType;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,18 +24,20 @@
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import jdk.jpackage.internal.util.MacBundle;
|
||||
import jdk.jpackage.test.Annotations.Parameters;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Executor;
|
||||
import jdk.jpackage.test.HelloApp;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.JavaAppDesc;
|
||||
import jdk.jpackage.test.JavaTool;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.HelloApp;
|
||||
|
||||
|
||||
/*
|
||||
@ -50,9 +52,8 @@ import jdk.jpackage.test.HelloApp;
|
||||
|
||||
public final class NoMPathRuntimeTest {
|
||||
|
||||
public NoMPathRuntimeTest(String jlinkOutputSubdir, String runtimeSubdir) {
|
||||
this.jlinkOutputSubdir = Path.of(jlinkOutputSubdir);
|
||||
this.runtimeSubdir = Path.of(runtimeSubdir);
|
||||
public NoMPathRuntimeTest(RuntimeType runtimeType) {
|
||||
this.runtimeType = Objects.requireNonNull(runtimeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -65,8 +66,24 @@ public final class NoMPathRuntimeTest {
|
||||
cmd.executePrerequisiteActions();
|
||||
|
||||
final Path workDir = TKit.createTempDirectory("runtime").resolve("data");
|
||||
final Path jlinkOutputDir = workDir.resolve(jlinkOutputSubdir);
|
||||
Files.createDirectories(jlinkOutputDir.getParent());
|
||||
final Path jlinkOutputDir;
|
||||
switch (runtimeType) {
|
||||
case IMAGE -> {
|
||||
jlinkOutputDir = workDir;
|
||||
}
|
||||
case MAC_BUNDLE -> {
|
||||
var macBundle = new MacBundle(workDir);
|
||||
|
||||
// Create macOS bundle structure sufficient to pass jpackage validation.
|
||||
Files.createDirectories(macBundle.homeDir().getParent());
|
||||
Files.createDirectories(macBundle.macOsDir());
|
||||
Files.createFile(macBundle.infoPlistFile());
|
||||
jlinkOutputDir = macBundle.homeDir();
|
||||
}
|
||||
default -> {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
// List of modules required for test app.
|
||||
final var modules = new String[] {
|
||||
@ -74,7 +91,7 @@ public final class NoMPathRuntimeTest {
|
||||
"java.desktop"
|
||||
};
|
||||
|
||||
Executor jlink = new Executor()
|
||||
new Executor()
|
||||
.setToolProvider(JavaTool.JLINK)
|
||||
.dumpOutput()
|
||||
.addArguments(
|
||||
@ -82,26 +99,17 @@ public final class NoMPathRuntimeTest {
|
||||
"--output", jlinkOutputDir.toString(),
|
||||
"--strip-debug",
|
||||
"--no-header-files",
|
||||
"--no-man-pages");
|
||||
|
||||
jlink.addArguments("--add-modules", appDesc.moduleName(),
|
||||
"--module-path", Path.of(cmd.getArgumentValue("--module-path"))
|
||||
.resolve("hello.jar").toString());
|
||||
|
||||
jlink.execute();
|
||||
|
||||
if (TKit.isOSX()) {
|
||||
// MacBundle requires valid bundle
|
||||
if (Files.exists(workDir.resolve("Contents/Home"))) {
|
||||
Files.createFile(workDir.resolve("Contents/Info.plist"));
|
||||
Files.createDirectories(workDir.resolve("Contents/MacOS"));
|
||||
}
|
||||
}
|
||||
"--no-man-pages"
|
||||
)
|
||||
.addArguments(
|
||||
"--add-modules", appDesc.moduleName(),
|
||||
"--module-path", Path.of(cmd.getArgumentValue("--module-path")).resolve("hello.jar").toString()
|
||||
).execute();
|
||||
|
||||
// non-modular jar in current dir caused error whe no module-path given
|
||||
cmd.removeArgumentWithValue("--module-path");
|
||||
|
||||
cmd.setArgumentValue("--runtime-image", workDir.resolve(runtimeSubdir));
|
||||
cmd.setArgumentValue("--runtime-image", workDir);
|
||||
Path junkJar = null;
|
||||
try {
|
||||
// create a non-modular jar in the current directory
|
||||
@ -118,24 +126,26 @@ public final class NoMPathRuntimeTest {
|
||||
}
|
||||
|
||||
@Parameters
|
||||
public static Collection<?> data() {
|
||||
public static Collection<Object[]> data() {
|
||||
|
||||
final List<String[]> paths = new ArrayList<>();
|
||||
paths.add(new String[] { "", "" });
|
||||
final List<RuntimeType> testCases = new ArrayList<>();
|
||||
testCases.add(RuntimeType.IMAGE);
|
||||
if (TKit.isOSX()) {
|
||||
// On OSX jpackage should accept both runtime root and runtime home
|
||||
// directories.
|
||||
paths.add(new String[] { "Contents/Home", "" });
|
||||
testCases.add(RuntimeType.MAC_BUNDLE);
|
||||
}
|
||||
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
for (var pathCfg : paths) {
|
||||
data.add(new Object[] { pathCfg[0], pathCfg[1] });
|
||||
}
|
||||
|
||||
return data;
|
||||
return testCases.stream().map(v -> {
|
||||
return new Object[] {v};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private final Path jlinkOutputSubdir;
|
||||
private final Path runtimeSubdir;
|
||||
public enum RuntimeType {
|
||||
IMAGE,
|
||||
MAC_BUNDLE,
|
||||
;
|
||||
}
|
||||
|
||||
private final RuntimeType runtimeType;
|
||||
}
|
||||
|
||||
@ -115,6 +115,26 @@ 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) {
|
||||
testReleaseFileVersion(version, true, Optional.empty(), packageTypes);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameter(value = {"17.21.3-ea", "17.21.3", "LINUX_RPM"}, ifOS = LINUX)
|
||||
public static void testValidReleaseFileVersion(String version, String normalizedVersion, PackageType... packageTypes) {
|
||||
testReleaseFileVersion(version, true, Optional.of(normalizedVersion), packageTypes);
|
||||
}
|
||||
|
||||
@Test
|
||||
// 27
|
||||
@Parameter(value = {"27"}, ifOS = {LINUX, MACOS})
|
||||
@ -126,10 +146,8 @@ public class RuntimePackageTest {
|
||||
@Parameter(value = {"27.1.2.3"}, ifOS = {LINUX, WINDOWS})
|
||||
// 27.1.2.3.4
|
||||
@Parameter(value = {"27.1.2.3.4"}, ifOS = LINUX)
|
||||
// 17.21.3-ea
|
||||
@Parameter(value = {"17.21.3-ea"}, ifOS = LINUX)
|
||||
public static void testReleaseFileVersion(String version) {
|
||||
testReleaseFileVersion(version, version);
|
||||
public static void testValidReleaseFileVersion(String version) {
|
||||
testReleaseFileVersion(version, true, Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -145,9 +163,18 @@ public class RuntimePackageTest {
|
||||
// 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 testReleaseFileVersion(String version, String normalizedVersion) {
|
||||
new PackageTest()
|
||||
.addInitializer(cmd -> {
|
||||
public static void testValidReleaseFileVersion(String version, String normalizedVersion) {
|
||||
testReleaseFileVersion(version, true, Optional.of(normalizedVersion));
|
||||
}
|
||||
|
||||
private static void testReleaseFileVersion(String version,
|
||||
boolean validReleaseFileVersion, Optional<String> normalizedVersion,
|
||||
PackageType... packageTypes) {
|
||||
var test = new PackageTest();
|
||||
if (packageTypes.length != 0) {
|
||||
test.forTypes(packageTypes);
|
||||
}
|
||||
test.addInitializer(cmd -> {
|
||||
// Remove --input parameter from jpackage command line as we don't
|
||||
// create input directory in the test and jpackage fails
|
||||
// if --input references non existant directory.
|
||||
@ -167,15 +194,17 @@ public class RuntimePackageTest {
|
||||
props.store(writer, null);
|
||||
}
|
||||
|
||||
// Validate output
|
||||
cmd.validateOutput(JPackageStringBundle.MAIN
|
||||
.cannedFormattedString("message.release-version",
|
||||
version, runtimeImage.toString()));
|
||||
// Normalization message is only printed if we did normalization.
|
||||
if (!version.equals(normalizedVersion)) {
|
||||
// Validate output only if release version is valid for release file
|
||||
if (validReleaseFileVersion) {
|
||||
cmd.validateOutput(JPackageStringBundle.MAIN
|
||||
.cannedFormattedString("message.version-normalized",
|
||||
normalizedVersion, version));
|
||||
.cannedFormattedString("message.release-version",
|
||||
version, runtimeImage.toString()));
|
||||
// Normalization message is only printed if we did normalization.
|
||||
normalizedVersion.ifPresent(nv -> {
|
||||
cmd.validateOutput(JPackageStringBundle.MAIN
|
||||
.cannedFormattedString("message.version-normalized",
|
||||
nv, version));
|
||||
});
|
||||
}
|
||||
})
|
||||
// Just create package. It is enough to verify version in bundle name.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user