11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.jpackage.internal;
27
28 import javax.imageio.ImageIO;
29 import java.awt.image.BufferedImage;
30 import java.io.*;
31 import java.nio.file.Files;
32 import java.nio.file.attribute.PosixFilePermission;
33 import java.nio.file.attribute.PosixFilePermissions;
34 import java.text.MessageFormat;
35 import java.util.*;
36 import java.util.regex.Pattern;
37
38 import static jdk.jpackage.internal.StandardBundlerParam.*;
39 import static jdk.jpackage.internal.LinuxAppBundler.ICON_PNG;
40 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR;
41 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES;
42
43 public class LinuxDebBundler extends AbstractBundler {
44
45 private static final ResourceBundle I18N = ResourceBundle.getBundle(
46 "jdk.jpackage.internal.resources.LinuxResources");
47
48 public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER =
49 new StandardBundlerParam<>(
50 "linux.app.bundler",
51 LinuxAppBundler.class,
52 params -> new LinuxAppBundler(),
53 (s, p) -> null);
54
55 // Debian rules for package naming are used here
56 // https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source
138 String.class,
139 params -> VENDOR.fetchFrom(params) + " <"
140 + EMAIL.fetchFrom(params) + ">",
141 (s, p) -> s);
142
143 public static final BundlerParamInfo<String> SECTION =
144 new StandardBundlerParam<>(
145 Arguments.CLIOptions.LINUX_CATEGORY.getId(),
146 String.class,
147 params -> "misc",
148 (s, p) -> s);
149
150 public static final BundlerParamInfo<String> LICENSE_TEXT =
151 new StandardBundlerParam<> (
152 "linux.deb.licenseText",
153 String.class,
154 params -> {
155 try {
156 String licenseFile = LICENSE_FILE.fetchFrom(params);
157 if (licenseFile != null) {
158 return Files.readString(new File(licenseFile).toPath());
159 }
160 } catch (Exception e) {
161 Log.verbose(e);
162 }
163 return "Unknown";
164 },
165 (s, p) -> s);
166
167 public static final BundlerParamInfo<String> XDG_FILE_PREFIX =
168 new StandardBundlerParam<> (
169 "linux.xdg-prefix",
170 String.class,
171 params -> {
172 try {
173 String vendor;
174 if (params.containsKey(VENDOR.getID())) {
175 vendor = VENDOR.fetchFrom(params);
176 } else {
177 vendor = "jpackage";
178 }
179 String appName = APP_NAME.fetchFrom(params);
180
181 return (appName + "-" + vendor).replaceAll("\\s", "");
182 } catch (Exception e) {
183 Log.verbose(e);
184 }
185 return "unknown-MimeInfo.xml";
186 },
698 data,
699 VERBOSE.fetchFrom(params),
700 RESOURCE_DIR.fetchFrom(params));
701 w.write(content);
702 }
703 setPermissions(getConfig_PostinstallFile(params), "rwxr-xr-x");
704
705 try (Writer w = Files.newBufferedWriter(
706 getConfig_PostrmFile(params).toPath())) {
707 String content = preprocessTextResource(
708 getConfig_PostrmFile(params).getName(),
709 I18N.getString("resource.deb-postrm-script"),
710 DEFAULT_POSTRM_TEMPLATE,
711 data,
712 VERBOSE.fetchFrom(params),
713 RESOURCE_DIR.fetchFrom(params));
714 w.write(content);
715 }
716 setPermissions(getConfig_PostrmFile(params), "rwxr-xr-x");
717
718 try (Writer w = Files.newBufferedWriter(
719 getConfig_CopyrightFile(params).toPath())) {
720 String content = preprocessTextResource(
721 getConfig_CopyrightFile(params).getName(),
722 I18N.getString("resource.deb-copyright-file"),
723 DEFAULT_COPYRIGHT_TEMPLATE,
724 data,
725 VERBOSE.fetchFrom(params),
726 RESOURCE_DIR.fetchFrom(params));
727 w.write(content);
728 }
729
730 return true;
731 }
732
733 private Map<String, String> createReplacementData(
734 Map<String, ? super Object> params) throws IOException {
735 Map<String, String> data = new HashMap<>();
736 String launcher = LinuxAppImageBuilder.getLauncherRelativePath(params);
737
738 data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
739 data.put("APPLICATION_FS_NAME", APP_NAME.fetchFrom(params));
740 data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params));
741 data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params));
742 data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params));
743 data.put("APPLICATION_VERSION", VERSION.fetchFrom(params));
744 data.put("APPLICATION_RELEASE", RELEASE.fetchFrom(params));
745 data.put("APPLICATION_SECTION", SECTION.fetchFrom(params));
746 data.put("APPLICATION_LAUNCHER_FILENAME", launcher);
747 data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params));
748 data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params));
776 return new File(CONFIG_DIR.fetchFrom(params), "control");
777 }
778
779 private File getConfig_PreinstallFile(Map<String, ? super Object> params) {
780 return new File(CONFIG_DIR.fetchFrom(params), "preinst");
781 }
782
783 private File getConfig_PrermFile(Map<String, ? super Object> params) {
784 return new File(CONFIG_DIR.fetchFrom(params), "prerm");
785 }
786
787 private File getConfig_PostinstallFile(Map<String, ? super Object> params) {
788 return new File(CONFIG_DIR.fetchFrom(params), "postinst");
789 }
790
791 private File getConfig_PostrmFile(Map<String, ? super Object> params) {
792 return new File(CONFIG_DIR.fetchFrom(params), "postrm");
793 }
794
795 private File getConfig_CopyrightFile(Map<String, ? super Object> params) {
796 return new File(CONFIG_DIR.fetchFrom(params), "copyright");
797 }
798
799 private File buildDeb(Map<String, ? super Object> params,
800 File outdir) throws IOException {
801 File outFile = new File(outdir,
802 FULL_PACKAGE_NAME.fetchFrom(params)+".deb");
803 Log.verbose(MessageFormat.format(I18N.getString(
804 "message.outputting-to-location"), outFile.getAbsolutePath()));
805
806 outFile.getParentFile().mkdirs();
807
808 // run dpkg
809 ProcessBuilder pb = new ProcessBuilder(
810 "fakeroot", TOOL_DPKG_DEB, "-b",
811 FULL_PACKAGE_NAME.fetchFrom(params),
812 outFile.getAbsolutePath());
813 pb = pb.directory(DEB_IMAGE_DIR.fetchFrom(params).getParentFile());
814 IOUtils.exec(pb);
815
816 Log.verbose(MessageFormat.format(I18N.getString(
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.jpackage.internal;
27
28 import javax.imageio.ImageIO;
29 import java.awt.image.BufferedImage;
30 import java.io.*;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.nio.file.attribute.PosixFilePermission;
35 import java.nio.file.attribute.PosixFilePermissions;
36 import java.text.MessageFormat;
37 import java.util.*;
38 import java.util.regex.Pattern;
39 import java.util.stream.Stream;
40
41 import static jdk.jpackage.internal.StandardBundlerParam.*;
42 import static jdk.jpackage.internal.LinuxAppBundler.ICON_PNG;
43 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR;
44 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES;
45
46 public class LinuxDebBundler extends AbstractBundler {
47
48 private static final ResourceBundle I18N = ResourceBundle.getBundle(
49 "jdk.jpackage.internal.resources.LinuxResources");
50
51 public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER =
52 new StandardBundlerParam<>(
53 "linux.app.bundler",
54 LinuxAppBundler.class,
55 params -> new LinuxAppBundler(),
56 (s, p) -> null);
57
58 // Debian rules for package naming are used here
59 // https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source
141 String.class,
142 params -> VENDOR.fetchFrom(params) + " <"
143 + EMAIL.fetchFrom(params) + ">",
144 (s, p) -> s);
145
146 public static final BundlerParamInfo<String> SECTION =
147 new StandardBundlerParam<>(
148 Arguments.CLIOptions.LINUX_CATEGORY.getId(),
149 String.class,
150 params -> "misc",
151 (s, p) -> s);
152
153 public static final BundlerParamInfo<String> LICENSE_TEXT =
154 new StandardBundlerParam<> (
155 "linux.deb.licenseText",
156 String.class,
157 params -> {
158 try {
159 String licenseFile = LICENSE_FILE.fetchFrom(params);
160 if (licenseFile != null) {
161 StringBuilder contentBuilder = new StringBuilder();
162 try (Stream<String> stream = Files.lines(Path.of(
163 licenseFile), StandardCharsets.UTF_8)) {
164 stream.forEach(s -> contentBuilder.append(s).append(
165 "\n"));
166 }
167 return contentBuilder.toString();
168 }
169 } catch (Exception e) {
170 Log.verbose(e);
171 }
172 return "Unknown";
173 },
174 (s, p) -> s);
175
176 public static final BundlerParamInfo<String> COPYRIGHT_FILE =
177 new StandardBundlerParam<>(
178 Arguments.CLIOptions.LINUX_DEB_COPYRIGHT_FILE.getId(),
179 String.class,
180 params -> null,
181 (s, p) -> s);
182
183 public static final BundlerParamInfo<String> XDG_FILE_PREFIX =
184 new StandardBundlerParam<> (
185 "linux.xdg-prefix",
186 String.class,
187 params -> {
188 try {
189 String vendor;
190 if (params.containsKey(VENDOR.getID())) {
191 vendor = VENDOR.fetchFrom(params);
192 } else {
193 vendor = "jpackage";
194 }
195 String appName = APP_NAME.fetchFrom(params);
196
197 return (appName + "-" + vendor).replaceAll("\\s", "");
198 } catch (Exception e) {
199 Log.verbose(e);
200 }
201 return "unknown-MimeInfo.xml";
202 },
714 data,
715 VERBOSE.fetchFrom(params),
716 RESOURCE_DIR.fetchFrom(params));
717 w.write(content);
718 }
719 setPermissions(getConfig_PostinstallFile(params), "rwxr-xr-x");
720
721 try (Writer w = Files.newBufferedWriter(
722 getConfig_PostrmFile(params).toPath())) {
723 String content = preprocessTextResource(
724 getConfig_PostrmFile(params).getName(),
725 I18N.getString("resource.deb-postrm-script"),
726 DEFAULT_POSTRM_TEMPLATE,
727 data,
728 VERBOSE.fetchFrom(params),
729 RESOURCE_DIR.fetchFrom(params));
730 w.write(content);
731 }
732 setPermissions(getConfig_PostrmFile(params), "rwxr-xr-x");
733
734 getConfig_CopyrightFile(params).getParentFile().mkdirs();
735 String customCopyrightFile = COPYRIGHT_FILE.fetchFrom(params);
736 if (customCopyrightFile != null) {
737 IOUtils.copyFile(new File(customCopyrightFile),
738 getConfig_CopyrightFile(params));
739 } else {
740 try (Writer w = Files.newBufferedWriter(
741 getConfig_CopyrightFile(params).toPath())) {
742 String content = preprocessTextResource(
743 getConfig_CopyrightFile(params).getName(),
744 I18N.getString("resource.copyright-file"),
745 DEFAULT_COPYRIGHT_TEMPLATE,
746 data,
747 VERBOSE.fetchFrom(params),
748 RESOURCE_DIR.fetchFrom(params));
749 w.write(content);
750 }
751 }
752
753 return true;
754 }
755
756 private Map<String, String> createReplacementData(
757 Map<String, ? super Object> params) throws IOException {
758 Map<String, String> data = new HashMap<>();
759 String launcher = LinuxAppImageBuilder.getLauncherRelativePath(params);
760
761 data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
762 data.put("APPLICATION_FS_NAME", APP_NAME.fetchFrom(params));
763 data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params));
764 data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params));
765 data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params));
766 data.put("APPLICATION_VERSION", VERSION.fetchFrom(params));
767 data.put("APPLICATION_RELEASE", RELEASE.fetchFrom(params));
768 data.put("APPLICATION_SECTION", SECTION.fetchFrom(params));
769 data.put("APPLICATION_LAUNCHER_FILENAME", launcher);
770 data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params));
771 data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params));
799 return new File(CONFIG_DIR.fetchFrom(params), "control");
800 }
801
802 private File getConfig_PreinstallFile(Map<String, ? super Object> params) {
803 return new File(CONFIG_DIR.fetchFrom(params), "preinst");
804 }
805
806 private File getConfig_PrermFile(Map<String, ? super Object> params) {
807 return new File(CONFIG_DIR.fetchFrom(params), "prerm");
808 }
809
810 private File getConfig_PostinstallFile(Map<String, ? super Object> params) {
811 return new File(CONFIG_DIR.fetchFrom(params), "postinst");
812 }
813
814 private File getConfig_PostrmFile(Map<String, ? super Object> params) {
815 return new File(CONFIG_DIR.fetchFrom(params), "postrm");
816 }
817
818 private File getConfig_CopyrightFile(Map<String, ? super Object> params) {
819 return Path.of(DEB_IMAGE_DIR.fetchFrom(params).getAbsolutePath(), "usr",
820 "share", "doc", BUNDLE_NAME.fetchFrom(params), "copyright").toFile();
821 }
822
823 private File buildDeb(Map<String, ? super Object> params,
824 File outdir) throws IOException {
825 File outFile = new File(outdir,
826 FULL_PACKAGE_NAME.fetchFrom(params)+".deb");
827 Log.verbose(MessageFormat.format(I18N.getString(
828 "message.outputting-to-location"), outFile.getAbsolutePath()));
829
830 outFile.getParentFile().mkdirs();
831
832 // run dpkg
833 ProcessBuilder pb = new ProcessBuilder(
834 "fakeroot", TOOL_DPKG_DEB, "-b",
835 FULL_PACKAGE_NAME.fetchFrom(params),
836 outFile.getAbsolutePath());
837 pb = pb.directory(DEB_IMAGE_DIR.fetchFrom(params).getParentFile());
838 IOUtils.exec(pb);
839
840 Log.verbose(MessageFormat.format(I18N.getString(
|