8301856: Generated .spec file for RPM installers uninstalls desktop launcher on update

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2023-11-27 22:28:38 +00:00
parent 726f854b14
commit 7848ed779b
16 changed files with 377 additions and 74 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, 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
@ -63,9 +63,10 @@ final class DesktopIntegration extends ShellCustomAction {
private static final String COMMANDS_INSTALL = "DESKTOP_COMMANDS_INSTALL";
private static final String COMMANDS_UNINSTALL = "DESKTOP_COMMANDS_UNINSTALL";
private static final String SCRIPTS = "DESKTOP_SCRIPTS";
private static final String COMMON_SCRIPTS = "COMMON_SCRIPTS";
private static final List<String> REPLACEMENT_STRING_IDS = List.of(
COMMANDS_INSTALL, COMMANDS_UNINSTALL, SCRIPTS);
COMMANDS_INSTALL, COMMANDS_UNINSTALL, SCRIPTS, COMMON_SCRIPTS);
private DesktopIntegration(PlatformPackage thePackage,
Map<String, ? super Object> params,
@ -229,8 +230,6 @@ final class DesktopIntegration extends ShellCustomAction {
shellCommands.applyTo(data);
}
boolean needCleanupScripts = !associations.isEmpty();
// Take care of additional launchers if there are any.
// Process every additional launcher as the main application launcher.
// Collect shell commands to install/uninstall integration with desktop
@ -241,10 +240,6 @@ final class DesktopIntegration extends ShellCustomAction {
List<String> uninstallShellCmds = new ArrayList<>(Arrays.asList(
data.get(COMMANDS_UNINSTALL)));
for (var integration: nestedIntegrations) {
if (!integration.associations.isEmpty()) {
needCleanupScripts = true;
}
Map<String, String> launcherData = integration.create();
installShellCmds.add(launcherData.get(COMMANDS_INSTALL));
@ -254,10 +249,8 @@ final class DesktopIntegration extends ShellCustomAction {
data.put(COMMANDS_INSTALL, stringifyShellCommands(installShellCmds));
data.put(COMMANDS_UNINSTALL, stringifyShellCommands(uninstallShellCmds));
if (needCleanupScripts) {
// Pull in desktop_utils.sh scrips library.
data.put(SCRIPTS, stringifyTextFile("desktop_utils.sh"));
}
data.put(COMMON_SCRIPTS, stringifyTextFile("common_utils.sh"));
data.put(SCRIPTS, stringifyTextFile("desktop_utils.sh"));
return data;
}
@ -295,7 +288,9 @@ final class DesktopIntegration extends ShellCustomAction {
registerDesktopFileCmd = String.join(" ", "xdg-desktop-menu",
"install", desktopFile.installPath().toString());
unregisterDesktopFileCmd = String.join(" ", "xdg-desktop-menu",
unregisterDesktopFileCmd = String.join(" ",
"do_if_file_belongs_to_single_package", desktopFile.
installPath().toString(), "xdg-desktop-menu",
"uninstall", desktopFile.installPath().toString());
}
@ -303,8 +298,10 @@ final class DesktopIntegration extends ShellCustomAction {
registerFileAssociationsCmd = String.join(" ", "xdg-mime",
"install",
mimeInfoFile.installPath().toString());
unregisterFileAssociationsCmd = String.join(" ", "xdg-mime",
"uninstall", mimeInfoFile.installPath().toString());
unregisterFileAssociationsCmd = String.join(" ",
"do_if_file_belongs_to_single_package", mimeInfoFile.
installPath().toString(), "xdg-mime", "uninstall",
mimeInfoFile.installPath().toString());
//
// Add manual cleanup of system files to get rid of
@ -320,26 +317,26 @@ final class DesktopIntegration extends ShellCustomAction {
// of non-existing desktop file.
//
String cleanUpCommand = String.join(" ",
"uninstall_default_mime_handler",
desktopFile.installPath().getFileName().toString(),
String.join(" ", getMimeTypeNamesFromFileAssociations()));
"do_if_file_belongs_to_single_package", desktopFile.
installPath().toString(),
"desktop_uninstall_default_mime_handler", desktopFile.
installPath().getFileName().toString(), String.join(
" ", getMimeTypeNamesFromFileAssociations()));
unregisterFileAssociationsCmd = stringifyShellCommands(
unregisterFileAssociationsCmd, cleanUpCommand);
}
void addIcon(String mimeType, Path iconFile) {
addIcon(mimeType, iconFile, getSquareSizeOfImage(iconFile.toFile()));
}
void addIcon(String mimeType, Path iconFile, int imgSize) {
imgSize = normalizeIconSize(imgSize);
final String dashMime = mimeType.replace('/', '-');
registerIconCmds.add(String.join(" ", "xdg-icon-resource",
"install", "--context", "mimetypes", "--size",
Integer.toString(imgSize), iconFile.toString(), dashMime));
unregisterIconCmds.add(String.join(" ", "xdg-icon-resource",
"uninstall", dashMime, "--size", Integer.toString(imgSize)));
unregisterIconCmds.add(String.join(" ",
"do_if_file_belongs_to_single_package", iconFile.toString(),
"xdg-icon-resource", "uninstall", dashMime, "--size",
Integer.toString(imgSize)));
}
void applyTo(Map<String, String> data) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -26,6 +26,8 @@ package jdk.jpackage.internal;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static jdk.jpackage.internal.OverridableResource.createResource;
@ -42,10 +44,24 @@ public final class LinuxLaunchersAsServices extends UnixLaunchersAsServices {
});
}
@Override
protected List<String> replacementStringIds() {
return LINUX_REPLACEMENT_STRING_IDS;
}
@Override
protected Map<String, String> createImpl() throws IOException {
var data = super.createImpl();
if (!data.isEmpty()) {
data.put(COMMON_SCRIPTS, stringifyTextFile("common_utils.sh"));
}
return data;
}
static ShellCustomAction create(PlatformPackage thePackage,
Map<String, Object> params) throws IOException {
if (StandardBundlerParam.isRuntimeInstaller(params)) {
return ShellCustomAction.nop(REPLACEMENT_STRING_IDS);
return ShellCustomAction.nop(LINUX_REPLACEMENT_STRING_IDS);
}
return new LinuxLaunchersAsServices(thePackage, params);
}
@ -84,4 +100,16 @@ public final class LinuxLaunchersAsServices extends UnixLaunchersAsServices {
private final static List<String> REQUIRED_PACKAGES = List.of("systemd",
"coreutils" /* /usr/bin/wc */, "grep");
private static final String COMMON_SCRIPTS = "COMMON_SCRIPTS";
private static final List<String> LINUX_REPLACEMENT_STRING_IDS;
static {
ArrayList<String> buf = new ArrayList<>();
buf.addAll(UnixLaunchersAsServices.REPLACEMENT_STRING_IDS);
buf.add(COMMON_SCRIPTS);
LINUX_REPLACEMENT_STRING_IDS = Collections.unmodifiableList(buf);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, 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
@ -155,7 +155,8 @@ abstract class LinuxPackageBundler extends AbstractBundler {
Map<String, String> data = createDefaultReplacementData(params);
for (var ca : customActions) {
data.putAll(ca.instance.create());
ShellCustomAction.mergeReplacementData(data, ca.instance.
create());
}
data.putAll(createReplacementData(params));

View File

@ -0,0 +1,23 @@
file_belongs_to_single_package ()
{
if [ ! -e "$1" ]; then
false
elif [ "$package_type" = rpm ]; then
test `rpm -q --whatprovides "$1" | wc -l` = 1
elif [ "$package_type" = deb ]; then
test `dpkg -S "$1" | wc -l` = 1
else
exit 1
fi
}
do_if_file_belongs_to_single_package ()
{
local file="$1"
shift
if file_belongs_to_single_package "$file"; then
"$@"
fi
}

View File

@ -2,7 +2,7 @@
# Remove $1 desktop file from the list of default handlers for $2 mime type
# in $3 file dumping output to stdout.
#
_filter_out_default_mime_handler ()
desktop_filter_out_default_mime_handler ()
{
local defaults_list="$3"
@ -50,7 +50,7 @@ EOF
# in $1 file.
# Result is saved in $1 file.
#
_uninstall_default_mime_handler ()
desktop_uninstall_default_mime_handler_0 ()
{
local defaults_list=$1
shift
@ -66,20 +66,20 @@ _uninstall_default_mime_handler ()
local v
local update=
for mime in "$@"; do
_filter_out_default_mime_handler "$desktop_file" "$mime" "$tmpfile1" > "$tmpfile2"
desktop_filter_out_default_mime_handler "$desktop_file" "$mime" "$tmpfile1" > "$tmpfile2"
v="$tmpfile2"
tmpfile2="$tmpfile1"
tmpfile1="$v"
if ! diff -q "$tmpfile1" "$tmpfile2" > /dev/null; then
update=yes
trace Remove $desktop_file default handler for $mime mime type from $defaults_list file
desktop_trace Remove $desktop_file default handler for $mime mime type from $defaults_list file
fi
done
if [ -n "$update" ]; then
cat "$tmpfile1" > "$defaults_list"
trace "$defaults_list" file updated
desktop_trace "$defaults_list" file updated
fi
rm -f "$tmpfile1" "$tmpfile2"
@ -90,15 +90,15 @@ _uninstall_default_mime_handler ()
# Remove $1 desktop file from the list of default handlers for $@ mime types
# in all known system defaults lists.
#
uninstall_default_mime_handler ()
desktop_uninstall_default_mime_handler ()
{
for f in /usr/share/applications/defaults.list /usr/local/share/applications/defaults.list; do
_uninstall_default_mime_handler "$f" "$@"
desktop_uninstall_default_mime_handler_0 "$f" "$@"
done
}
trace ()
desktop_trace ()
{
echo "$@"
}

View File

@ -23,16 +23,3 @@ unregister_services ()
fi
done
}
file_belongs_to_single_package ()
{
if [ ! -e "$1" ]; then
false
elif [ "$package_type" = rpm ]; then
test `rpm -q --whatprovides "$1" | wc -l` = 1
elif [ "$package_type" = deb ]; then
test `dpkg -S "$1" | wc -l` = 1
else
exit 1
fi
}

View File

@ -14,12 +14,13 @@ set -e
# the debian-policy package
package_type=deb
COMMON_SCRIPTS
LAUNCHER_AS_SERVICE_SCRIPTS
case "$1" in
install|upgrade)
if [ -n "$2" ]; then
true; LAUNCHER_AS_SERVICE_COMMANDS_UNINSTALL
:; LAUNCHER_AS_SERVICE_COMMANDS_UNINSTALL
fi
;;

View File

@ -18,6 +18,7 @@ set -e
package_type=deb
COMMON_SCRIPTS
DESKTOP_SCRIPTS
LAUNCHER_AS_SERVICE_SCRIPTS

View File

@ -83,13 +83,15 @@ LAUNCHER_AS_SERVICE_COMMANDS_INSTALL
%pre
package_type=rpm
COMMON_SCRIPTS
LAUNCHER_AS_SERVICE_SCRIPTS
if [ "$1" = 2 ]; then
true; LAUNCHER_AS_SERVICE_COMMANDS_UNINSTALL
if [ "$1" -gt 1 ]; then
:; LAUNCHER_AS_SERVICE_COMMANDS_UNINSTALL
fi
%preun
package_type=rpm
COMMON_SCRIPTS
DESKTOP_SCRIPTS
LAUNCHER_AS_SERVICE_SCRIPTS
DESKTOP_COMMANDS_UNINSTALL

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -34,6 +34,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -74,6 +75,26 @@ abstract class ShellCustomAction {
};
}
static void mergeReplacementData(Map<String, String> target,
Map<String, String> newValues) {
Objects.requireNonNull(target);
Objects.requireNonNull(newValues);
for (var kvp : newValues.entrySet()) {
String newValue = kvp.getValue();
String existingValue = target.putIfAbsent(kvp.getKey(), newValue);
if (existingValue != null) {
if (existingValue.isEmpty()) {
target.replace(kvp.getKey(), newValue);
} else if (!newValue.isEmpty() && !newValue.
equals(existingValue)) {
throw new IllegalArgumentException(String.format(
"Key [%s] value mismatch", kvp.getKey()));
}
}
}
}
protected static String stringifyShellCommands(String... commands) {
return stringifyShellCommands(Arrays.asList(commands));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -65,12 +65,12 @@ class UnixLaunchersAsServices extends ShellCustomAction {
}
@Override
final protected List<String> replacementStringIds() {
return List.of(COMMANDS_INSTALL, COMMANDS_UNINSTALL, SCRIPTS);
protected List<String> replacementStringIds() {
return REPLACEMENT_STRING_IDS;
}
@Override
final protected Map<String, String> createImpl() throws IOException {
protected Map<String, String> createImpl() throws IOException {
Map<String, String> data = new HashMap<>();
if (launchers.isEmpty()) {
@ -87,11 +87,7 @@ class UnixLaunchersAsServices extends ShellCustomAction {
Collectors.joining(" ")));
};
try {
data.put(SCRIPTS, stringifyTextFile("services_utils.sh"));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
data.put(SCRIPTS, stringifyTextFile("services_utils.sh"));
data.put(COMMANDS_INSTALL, strigifier.apply("register_services"));
data.put(COMMANDS_UNINSTALL, strigifier.apply("unregister_services"));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, 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
@ -76,6 +76,11 @@ public class AdditionalLauncher {
return this;
}
final public AdditionalLauncher setVerifyUninstalled(boolean value) {
verifyUninstalled = value;
return this;
}
final public AdditionalLauncher setLauncherAsService() {
return addRawProperties(LAUNCHER_AS_SERVICE);
}
@ -141,6 +146,13 @@ public class AdditionalLauncher {
final public void applyTo(PackageTest test) {
test.addInitializer(this::initialize);
test.addInstallVerifier(this::verify);
if (verifyUninstalled) {
test.addUninstallVerifier(this::verifyUninstalled);
}
}
final public void verifyRemovedInUpgrade(PackageTest test) {
test.addInstallVerifier(this::verifyUninstalled);
}
static void forEachAdditionalLauncher(JPackageCommand cmd,
@ -318,10 +330,40 @@ public class AdditionalLauncher {
}
}
private void verifyInstalled(JPackageCommand cmd, boolean installed) throws IOException {
if (TKit.isLinux() && !cmd.isImagePackageType() && !cmd.
isPackageUnpacked(String.format(
"Not verifying package and system .desktop files for [%s] launcher",
cmd.appLauncherPath(name)))) {
Path packageDesktopFile = LinuxHelper.getDesktopFile(cmd, name);
Path systemDesktopFile = LinuxHelper.getSystemDesktopFilesFolder().
resolve(packageDesktopFile.getFileName());
if (Files.exists(packageDesktopFile) && installed) {
TKit.assertFileExists(systemDesktopFile);
TKit.assertStringListEquals(Files.readAllLines(
packageDesktopFile),
Files.readAllLines(systemDesktopFile), String.format(
"Check [%s] and [%s] files are equal",
packageDesktopFile,
systemDesktopFile));
} else {
TKit.assertPathExists(packageDesktopFile, false);
TKit.assertPathExists(systemDesktopFile, false);
}
}
}
protected void verifyUninstalled(JPackageCommand cmd) throws IOException {
verifyInstalled(cmd, false);
Path launcherPath = cmd.appLauncherPath(name);
TKit.assertPathExists(launcherPath, false);
}
protected void verify(JPackageCommand cmd) throws IOException {
verifyIcon(cmd);
verifyShortcuts(cmd);
verifyDescription(cmd);
verifyInstalled(cmd, true);
Path launcherPath = cmd.appLauncherPath(name);
@ -394,6 +436,7 @@ public class AdditionalLauncher {
return str;
}
private boolean verifyUninstalled;
private List<String> javaOptions;
private List<String> defaultArguments;
private Path icon;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -23,6 +23,7 @@
package jdk.jpackage.test;
import java.io.IOException;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@ -30,6 +31,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -58,10 +60,16 @@ public final class LauncherAsServiceVerifier {
return this;
}
public Builder setAdditionalLauncherCallback(Consumer<AdditionalLauncher> v) {
additionalLauncherCallback = v;
return this;
}
public LauncherAsServiceVerifier create() {
Objects.requireNonNull(expectedValue);
return new LauncherAsServiceVerifier(launcherName, appOutputFileName,
expectedValue);
expectedValue,
launcherName != null ? additionalLauncherCallback : null);
}
public Builder applyTo(PackageTest pkg) {
@ -72,6 +80,7 @@ public final class LauncherAsServiceVerifier {
private String launcherName;
private String expectedValue;
private String appOutputFileName = "launcher-as-service.txt";
private Consumer<AdditionalLauncher> additionalLauncherCallback;
}
public static Builder build() {
@ -80,10 +89,12 @@ public final class LauncherAsServiceVerifier {
private LauncherAsServiceVerifier(String launcherName,
String appOutputFileName,
String expectedArgValue) {
String expectedArgValue,
Consumer<AdditionalLauncher> additionalLauncherCallback) {
this.expectedValue = expectedArgValue;
this.launcherName = launcherName;
this.appOutputFileName = Path.of(appOutputFileName);
this.additionalLauncherCallback = additionalLauncherCallback;
}
public void applyTo(PackageTest pkg) {
@ -233,7 +244,7 @@ public final class LauncherAsServiceVerifier {
outputFilePath.toString())
.addDefaultArguments(expectedValue)
.verifyOutput();
TKit.deleteIfExists(outputFilePath);
deleteOutputFile(outputFilePath);
}
});
pkg.addInstallVerifier(cmd -> {
@ -242,13 +253,13 @@ public final class LauncherAsServiceVerifier {
}
private void applyToAdditionalLauncher(PackageTest pkg) {
new AdditionalLauncher(launcherName) {
AdditionalLauncher al = new AdditionalLauncher(launcherName) {
@Override
protected void verify(JPackageCommand cmd) throws IOException {
if (canVerifyInstall(cmd)) {
delayInstallVerify();
super.verify(cmd);
TKit.deleteIfExists(appOutputFilePathVerify(cmd));
deleteOutputFile(appOutputFilePathVerify(cmd));
}
LauncherAsServiceVerifier.verify(cmd, launcherName);
}
@ -256,8 +267,26 @@ public final class LauncherAsServiceVerifier {
.addJavaOptions("-Djpackage.test.appOutput="
+ appOutputFilePathInitialize().toString())
.addJavaOptions("-Djpackage.test.noexit=true")
.addDefaultArguments(expectedValue)
.applyTo(pkg);
.addDefaultArguments(expectedValue);
Optional.ofNullable(additionalLauncherCallback).ifPresent(v -> v.accept(al));
al.applyTo(pkg);
}
private static void deleteOutputFile(Path file) throws IOException {
try {
TKit.deleteIfExists(file);
} catch (FileSystemException ex) {
if (TKit.isLinux() || TKit.isOSX()) {
// Probably "Operation no permitted" error. Try with "sudo" as the
// file is created by a launcher started under root account.
Executor.of("sudo", "rm", "-f").addArgument(file.toString()).
execute();
} else {
throw ex;
}
}
}
private static void verify(JPackageCommand cmd, String launcherName) throws
@ -337,6 +366,7 @@ public final class LauncherAsServiceVerifier {
private final String expectedValue;
private final String launcherName;
private final Path appOutputFileName;
private final Consumer<AdditionalLauncher> additionalLauncherCallback;
final static Set<PackageType> SUPPORTED_PACKAGES = Stream.of(LINUX, WINDOWS,
Set.of(MAC_PKG)).flatMap(x -> x.stream()).collect(Collectors.toSet());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, 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
@ -464,7 +464,7 @@ public final class LinuxHelper {
}
}
private static Path getSystemDesktopFilesFolder() {
static Path getSystemDesktopFilesFolder() {
return Stream.of("/usr/share/applications",
"/usr/local/share/applications").map(Path::of).filter(dir -> {
return Files.exists(dir.resolve("defaults.list"));
@ -558,12 +558,17 @@ public final class LinuxHelper {
final String xdgCmdName = "xdg-icon-resource";
Stream<String> scriptletBodyStream = scriptletBody.stream()
.filter(str -> str.startsWith(xdgCmdName))
.filter(str -> Pattern.compile(
"\\b" + dashMime + "\\b").matcher(str).find());
if (scriptletType == Scriptlet.PostInstall) {
scriptletBodyStream = scriptletBodyStream.filter(str -> str.
startsWith(xdgCmdName));
scriptletBodyStream = scriptletBodyStream.filter(str -> List.of(
str.split("\\s+")).contains(iconPathInPackage.toString()));
} else {
scriptletBodyStream = scriptletBodyStream.filter(str -> str.
contains(xdgCmdName)).filter(str -> str.startsWith(
"do_if_file_belongs_to_single_package"));
}
scriptletBodyStream.peek(xdgCmd -> {

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2023, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.file.Path;
import jdk.jpackage.test.AdditionalLauncher;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.LauncherAsServiceVerifier;
import jdk.jpackage.test.TKit;
/**
* Test how services and desktop integration align together in the same package.
* On Linux these features share common code in custom actions (common_utils.sh).
* Test correctness of integration of this code.
*
* The test is not intended to be executed by SQE. It is for internal use only
*/
/*
* @test
* @summary jpackage with desktop integration and services on Linux
* @library ../helpers
* @key jpackagePlatformPackage
* @requires jpackage.test.SQETest == null
* @build jdk.jpackage.test.*
* @requires (os.family == "linux")
* @modules jdk.jpackage/jdk.jpackage.internal
* @compile ServiceAndDesktopTest.java
* @run main/othervm/timeout=720 jdk.jpackage.test.Main
* --jpt-run=ServiceAndDesktopTest
*/
public class ServiceAndDesktopTest {
@Test
public static void test() {
var pkg = new PackageTest()
.configureHelloApp()
.addBundleDesktopIntegrationVerifier(true)
.addInitializer(cmd -> {
// Want a .desktop file for the main launcher
cmd.addArguments("--icon", GOLDEN_ICON.toString());
});
LauncherAsServiceVerifier.build().setLauncherName("foo").
setExpectedValue("Fun").setAdditionalLauncherCallback(al -> {
// Don't want .desktop file for service launcher
al.setNoIcon();
}).applyTo(pkg);
pkg.run();
}
private final static Path GOLDEN_ICON = TKit.TEST_SRC_ROOT.resolve(Path.of(
"resources", "icon" + TKit.ICON_SUFFIX));
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2023, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Map;
import java.nio.file.Path;
import jdk.jpackage.test.AdditionalLauncher;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.TKit;
/*
* @test
* @summary Linux upgrade testing
* @library ../helpers
* @key jpackagePlatformPackage
* @build jdk.jpackage.test.*
* @requires (os.family == "linux")
* @modules jdk.jpackage/jdk.jpackage.internal
* @compile UpgradeTest.java
* @run main/othervm/timeout=360 jdk.jpackage.test.Main
* --jpt-run=UpgradeTest
*/
public class UpgradeTest {
@Test
public void testDesktopFiles() {
// Create two packages with the same name but different versions.
// The first will have `launcherA`, and `launcherB` additional launchers.
// The second will have `launcherB`, and `launcherC` additional launchers.
// Launchers are configured in a way to have correpsonding .desktop files.
// These files will be installed in system directories.
// After the upgrade `launcherA`-related files must be deleted and
// `launcherB`-related files from the first package must be replaced with
// the files from the second package.
// Checks that correct files are installed in system directories
// encapsulated in AdditionalLauncher class.
var pkg = createPackageTest().disablePackageUninstaller();
var alA = createAdditionalLauncher("launcherA");
alA.applyTo(pkg);
createAdditionalLauncher("launcherB").addRawProperties(Map.entry(
"description", "Foo")).applyTo(pkg);
var pkg2 = createPackageTest().addInitializer(cmd -> {
cmd.addArguments("--app-version", "2.0");
});
alA.verifyRemovedInUpgrade(pkg2);
createAdditionalLauncher("launcherB").addRawProperties(Map.entry(
"description", "Bar")).applyTo(pkg2);
createAdditionalLauncher("launcherC").applyTo(pkg2);
new PackageTest.Group(pkg, pkg2).run();
}
private static PackageTest createPackageTest() {
return new PackageTest().configureHelloApp().addInitializer(
JPackageCommand::setInputToEmptyDirectory).addInitializer(
JPackageCommand::setFakeRuntime).
addBundleDesktopIntegrationVerifier(true);
}
private static AdditionalLauncher createAdditionalLauncher(String name) {
// Configure additionl launcher in a way to trigger jpackage create
// corresponding .desktop file.
return new AdditionalLauncher(name).setIcon(GOLDEN_ICON);
}
private final static Path GOLDEN_ICON = TKit.TEST_SRC_ROOT.resolve(Path.of(
"resources", "icon" + TKit.ICON_SUFFIX));
}