27 |
27 |
28 import javax.imageio.ImageIO; |
28 import javax.imageio.ImageIO; |
29 import java.awt.image.BufferedImage; |
29 import java.awt.image.BufferedImage; |
30 import java.io.*; |
30 import java.io.*; |
31 import java.nio.charset.StandardCharsets; |
31 import java.nio.charset.StandardCharsets; |
|
32 import java.nio.file.FileVisitResult; |
32 import java.nio.file.Files; |
33 import java.nio.file.Files; |
33 import java.nio.file.Path; |
34 import java.nio.file.Path; |
|
35 import java.nio.file.SimpleFileVisitor; |
|
36 import java.nio.file.StandardCopyOption; |
|
37 import java.nio.file.attribute.BasicFileAttributes; |
|
38 |
34 import java.nio.file.attribute.PosixFilePermission; |
39 import java.nio.file.attribute.PosixFilePermission; |
35 import java.nio.file.attribute.PosixFilePermissions; |
40 import java.nio.file.attribute.PosixFilePermissions; |
36 import java.text.MessageFormat; |
41 import java.text.MessageFormat; |
37 import java.util.*; |
42 import java.util.*; |
38 import java.util.regex.Pattern; |
43 import java.util.regex.Pattern; |
313 } |
318 } |
314 |
319 |
315 private boolean prepareProto(Map<String, ? super Object> params) |
320 private boolean prepareProto(Map<String, ? super Object> params) |
316 throws PackagerException, IOException { |
321 throws PackagerException, IOException { |
317 File appImage = StandardBundlerParam.getPredefinedAppImage(params); |
322 File appImage = StandardBundlerParam.getPredefinedAppImage(params); |
318 File appDir = null; |
|
319 |
323 |
320 // we either have an application image or need to build one |
324 // we either have an application image or need to build one |
321 if (appImage != null) { |
325 if (appImage != null) { |
322 appDir = new File(APP_IMAGE_ROOT.fetchFrom(params), |
|
323 APP_NAME.fetchFrom(params)); |
|
324 // copy everything from appImage dir into appDir/name |
326 // copy everything from appImage dir into appDir/name |
325 IOUtils.copyRecursive(appImage.toPath(), appDir.toPath()); |
327 IOUtils.copyRecursive(appImage.toPath(), |
|
328 getConfig_RootDirectory(params).toPath()); |
326 } else { |
329 } else { |
327 appDir = APP_BUNDLER.fetchFrom(params).doBundle(params, |
330 File bundleDir = APP_BUNDLER.fetchFrom(params).doBundle(params, |
328 APP_IMAGE_ROOT.fetchFrom(params), true); |
331 APP_IMAGE_ROOT.fetchFrom(params), true); |
329 } |
332 if (bundleDir == null) { |
330 return appDir != null; |
333 return false; |
|
334 } |
|
335 Files.move(bundleDir.toPath(), getConfig_RootDirectory( |
|
336 params).toPath(), StandardCopyOption.REPLACE_EXISTING); |
|
337 } |
|
338 return true; |
331 } |
339 } |
332 |
340 |
333 public File bundle(Map<String, ? super Object> params, |
341 public File bundle(Map<String, ? super Object> params, |
334 File outdir) throws PackagerException { |
342 File outdir) throws PackagerException { |
335 |
343 |
410 } |
419 } |
411 } |
420 } |
412 return count; |
421 return count; |
413 } |
422 } |
414 |
423 |
|
424 private void adjustPermissionsRecursive(File dir) throws IOException { |
|
425 Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() { |
|
426 @Override |
|
427 public FileVisitResult visitFile(Path file, |
|
428 BasicFileAttributes attrs) |
|
429 throws IOException { |
|
430 if (file.endsWith(".so") || !Files.isExecutable(file)) { |
|
431 setPermissions(file.toFile(), "rw-r--r--"); |
|
432 } else if (Files.isExecutable(file)) { |
|
433 setPermissions(file.toFile(), "rwxr-xr-x"); |
|
434 } |
|
435 return FileVisitResult.CONTINUE; |
|
436 } |
|
437 |
|
438 @Override |
|
439 public FileVisitResult postVisitDirectory(Path dir, IOException e) |
|
440 throws IOException { |
|
441 if (e == null) { |
|
442 setPermissions(dir.toFile(), "rwxr-xr-x"); |
|
443 return FileVisitResult.CONTINUE; |
|
444 } else { |
|
445 // directory iteration failed |
|
446 throw e; |
|
447 } |
|
448 } |
|
449 }); |
|
450 } |
|
451 |
415 private boolean prepareProjectConfig(Map<String, ? super Object> params) |
452 private boolean prepareProjectConfig(Map<String, ? super Object> params) |
416 throws IOException { |
453 throws IOException { |
417 Map<String, String> data = createReplacementData(params); |
454 Map<String, String> data = createReplacementData(params); |
418 File rootDir = LinuxAppBundler.getRootDir(APP_IMAGE_ROOT.fetchFrom( |
455 File rootDir = getConfig_RootDirectory(params); |
419 params), params); |
|
420 File binDir = new File(rootDir, "bin"); |
456 File binDir = new File(rootDir, "bin"); |
421 |
457 |
422 File iconTarget = getConfig_IconFile(binDir, params); |
458 File iconTarget = getConfig_IconFile(binDir, params); |
423 File icon = ICON_PNG.fetchFrom(params); |
459 File icon = ICON_PNG.fetchFrom(params); |
424 if (!StandardBundlerParam.isRuntimeInstaller(params)) { |
460 if (!StandardBundlerParam.isRuntimeInstaller(params)) { |
574 if (!addedEntry) { |
610 if (!addedEntry) { |
575 registrations.append(" xdg-mime install ") |
611 registrations.append(" xdg-mime install ") |
576 .append(LINUX_INSTALL_DIR.fetchFrom(params)) |
612 .append(LINUX_INSTALL_DIR.fetchFrom(params)) |
577 .append("/") |
613 .append("/") |
578 .append(data.get("APPLICATION_FS_NAME")) |
614 .append(data.get("APPLICATION_FS_NAME")) |
579 .append("/") |
615 .append("/bin/") |
580 .append(mimeInfoFile) |
616 .append(mimeInfoFile) |
581 .append("\n"); |
617 .append("\n"); |
582 |
618 |
583 deregistrations.append(" xdg-mime uninstall ") |
619 deregistrations.append(" xdg-mime uninstall ") |
584 .append(LINUX_INSTALL_DIR.fetchFrom(params)) |
620 .append(LINUX_INSTALL_DIR.fetchFrom(params)) |
585 .append("/") |
621 .append("/") |
586 .append(data.get("APPLICATION_FS_NAME")) |
622 .append(data.get("APPLICATION_FS_NAME")) |
587 .append("/") |
623 .append("/bin/") |
588 .append(mimeInfoFile) |
624 .append(mimeInfoFile) |
589 .append("\n"); |
625 .append("\n"); |
590 addedEntry = true; |
626 addedEntry = true; |
591 } else { |
627 } else { |
592 desktopMimes.append(";"); |
628 desktopMimes.append(";"); |
757 Map<String, ? super Object> params) throws IOException { |
793 Map<String, ? super Object> params) throws IOException { |
758 Map<String, String> data = new HashMap<>(); |
794 Map<String, String> data = new HashMap<>(); |
759 String launcher = LinuxAppImageBuilder.getLauncherRelativePath(params); |
795 String launcher = LinuxAppImageBuilder.getLauncherRelativePath(params); |
760 |
796 |
761 data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params)); |
797 data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params)); |
762 data.put("APPLICATION_FS_NAME", APP_NAME.fetchFrom(params)); |
798 data.put("APPLICATION_FS_NAME", |
|
799 getConfig_RootDirectory(params).getName()); |
763 data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params)); |
800 data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params)); |
764 data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params)); |
801 data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params)); |
765 data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params)); |
802 data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params)); |
766 data.put("APPLICATION_VERSION", VERSION.fetchFrom(params)); |
803 data.put("APPLICATION_VERSION", VERSION.fetchFrom(params)); |
767 data.put("APPLICATION_RELEASE", RELEASE.fetchFrom(params)); |
804 data.put("APPLICATION_RELEASE", RELEASE.fetchFrom(params)); |
774 data.put("APPLICATION_COPYRIGHT", COPYRIGHT.fetchFrom(params)); |
811 data.put("APPLICATION_COPYRIGHT", COPYRIGHT.fetchFrom(params)); |
775 data.put("APPLICATION_LICENSE_TEXT", LICENSE_TEXT.fetchFrom(params)); |
812 data.put("APPLICATION_LICENSE_TEXT", LICENSE_TEXT.fetchFrom(params)); |
776 data.put("APPLICATION_ARCH", getDebArch()); |
813 data.put("APPLICATION_ARCH", getDebArch()); |
777 data.put("APPLICATION_INSTALLED_SIZE", |
814 data.put("APPLICATION_INSTALLED_SIZE", |
778 Long.toString(getInstalledSizeKB(params))); |
815 Long.toString(getInstalledSizeKB(params))); |
779 String deps = LINUX_PACKAGE_DEPENDENCIES.fetchFrom(params); |
816 data.put("PACKAGE_DEPENDENCIES", LINUX_PACKAGE_DEPENDENCIES.fetchFrom( |
780 data.put("PACKAGE_DEPENDENCIES", |
817 params)); |
781 deps.isEmpty() ? "" : "Depends: " + deps); |
|
782 data.put("RUNTIME_INSTALLER", "" + |
818 data.put("RUNTIME_INSTALLER", "" + |
783 StandardBundlerParam.isRuntimeInstaller(params)); |
819 StandardBundlerParam.isRuntimeInstaller(params)); |
784 |
820 |
785 return data; |
821 return data; |
786 } |
822 } |
816 } |
852 } |
817 |
853 |
818 private File getConfig_CopyrightFile(Map<String, ? super Object> params) { |
854 private File getConfig_CopyrightFile(Map<String, ? super Object> params) { |
819 return Path.of(DEB_IMAGE_DIR.fetchFrom(params).getAbsolutePath(), "usr", |
855 return Path.of(DEB_IMAGE_DIR.fetchFrom(params).getAbsolutePath(), "usr", |
820 "share", "doc", BUNDLE_NAME.fetchFrom(params), "copyright").toFile(); |
856 "share", "doc", BUNDLE_NAME.fetchFrom(params), "copyright").toFile(); |
|
857 } |
|
858 |
|
859 private File getConfig_RootDirectory( |
|
860 Map<String, ? super Object> params) { |
|
861 return Path.of(APP_IMAGE_ROOT.fetchFrom(params).getAbsolutePath(), |
|
862 BUNDLE_NAME.fetchFrom(params)).toFile(); |
821 } |
863 } |
822 |
864 |
823 private File buildDeb(Map<String, ? super Object> params, |
865 private File buildDeb(Map<String, ? super Object> params, |
824 File outdir) throws IOException { |
866 File outdir) throws IOException { |
825 File outFile = new File(outdir, |
867 File outFile = new File(outdir, |