diff --git a/bin/Packager/DesktopEntry.py b/bin/Packager/DesktopEntry.py index 649998829..2f618853b 100644 --- a/bin/Packager/DesktopEntry.py +++ b/bin/Packager/DesktopEntry.py @@ -1,73 +1,70 @@ # -*- coding: utf-8 -*- # Copyright Hannah von Reth # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. import io from pathlib import Path from Packager.PackagerBase import * from shells import Powershell class DesktopEntry(PackagerBase): def createPackage(self): defines = self.setDefaults(self.defines) if CraftCore.compiler.isMacOS: - if 'executable' in defines: - target = defines["executable"] - else: - target = self.getMacAppPath(defines) + target = (os.path.relpath(self.getMacAppPath(defines, self.imageDir()), self.imageDir())) targetBundle = os.path.join(CraftCore.standardDirs.craftRoot(), target) targetPlist = os.path.join(targetBundle, "Contents/Info.plist") with io.StringIO() as binaryLog: utils.system(["defaults", "read", targetPlist, "CFBundleExecutable"], stdout=binaryLog) targetBinary = binaryLog.getvalue().strip() with io.StringIO() as iconLog: utils.system(["defaults", "read", targetPlist, "CFBundleIconFile"], stdout=iconLog) targetIcon = iconLog.getvalue().strip() if not targetBinary: return False targetShimBundle = os.path.join("/Applications/Craft", os.path.basename(target)) shim = os.path.join(targetShimBundle, "Contents/MacOS", targetBinary) if not utils.createDir(os.path.join(targetShimBundle, "Contents/MacOS")): return False if not utils.createDir(os.path.join(targetShimBundle, "Contents/Resources")): return False if not utils.createShim(shim, sys.executable, [os.path.join(CraftCore.standardDirs.craftBin(), "craft.py"), "--run-detached", "open", targetBundle], useAbsolutePath=True): return False if not utils.copyFile(targetPlist, os.path.join(targetShimBundle, "Contents/Info.plist"), linkOnly=False): return False if targetIcon and not utils.copyFile(os.path.join(targetBundle, "Contents/Resources", targetIcon), os.path.join(targetShimBundle, "Contents/Resources", targetIcon), linkOnly=False): return False elif CraftCore.compiler.isWindows: for shortcut in self.defines["shortcuts"]: shim = Path(CraftCore.standardDirs.craftRoot()) / "wrapper" / shortcut["name"] target = Path(CraftCore.standardDirs.craftRoot()) / shortcut["target"] if not utils.createShim(shim, sys.executable, [os.path.join(CraftCore.standardDirs.craftBin(), "craft.py"), "--run-detached", target]): return False craftName = Path(CraftCore.standardDirs.craftRoot()).name if not utils.installShortcut(f"{craftName}/{shortcut['name']} {craftName}", shim, target.parent, os.path.join(CraftCore.standardDirs.craftRoot(), shortcut["target"]), shortcut.get("desciption", f"{shortcut['name']} from {CraftCore.standardDirs.craftRoot()}")): return False return True diff --git a/bin/Packager/PackagerBase.py b/bin/Packager/PackagerBase.py index 5ab955120..7177e5b5a 100644 --- a/bin/Packager/PackagerBase.py +++ b/bin/Packager/PackagerBase.py @@ -1,92 +1,93 @@ # # copyright (c) 2009 Ralf Habacker # # Packager base import datetime import json import glob from CraftBase import * from Utils import CraftHash from Utils.CraftManifest import * from CraftDebug import deprecated class PackagerBase(CraftBase): """ provides a generic interface for packagers and implements basic package creating stuff """ @InitGuard.init_once def __init__(self): CraftBase.__init__(self) self.whitelist_file = [] self.blacklist_file = [] self.defines = {} self.ignoredPackages = [] def setDefaults(self, defines: {str:str}) -> {str:str}: defines = dict(defines) defines.setdefault("architecture", CraftCore.compiler.architecture) defines.setdefault("company", "KDE e.V.") defines.setdefault("productname", self.subinfo.displayName) defines.setdefault("display_name", self.subinfo.displayName) defines.setdefault("description", self.subinfo.description) defines.setdefault("icon", os.path.join(CraftCore.standardDirs.craftBin(), "data", "icons", "craft.ico")) defines.setdefault("icon_png", os.path.join(CraftCore.standardDirs.craftBin(), "data", "icons", "craftyBENDER.png")) defines.setdefault("icon_png_44", defines["icon_png"]) defines.setdefault("license", "") defines.setdefault("version", self.sourceRevision() if self.subinfo.hasSvnTarget() else self.version) defines.setdefault("website", self.subinfo.webpage if self.subinfo.webpage else "https://community.kde.org/Craft") # mac defines.setdefault("apppath", "") defines.setdefault("appname", self.package.name.lower()) return defines - def getMacAppPath(self, defines): + def getMacAppPath(self, defines, lookupPath = None): + lookPath = os.path.normpath(lookupPath if lookupPath else self.archiveDir()) appPath = defines['apppath'] if not appPath: - image = os.path.normpath(self.imageDir()) - apps = glob.glob(os.path.join(image, f"**/{defines['appname']}.app"), recursive=True) + apps = glob.glob(os.path.join(lookPath, f"**/{defines['appname']}.app"), recursive=True) if len(apps) != 1: CraftCore.log.error(f"Failed to detect {defines['appname']}.app for {self}, please provide a correct self.defines['apppath'] or a relative path to the app as self.defines['apppath']") return False - appPath = os.path.relpath(apps[0], image) + appPath = apps[0] + appPath = os.path.join(lookPath, appPath) return os.path.normpath(appPath) def preArchive(self): utils.abstract() def archiveDir(self): return os.path.join(self.buildRoot(), "archive") # """ create a package """ def createPackage(self): utils.abstract() def _generateManifest(self, destDir, archiveName, manifestLocation=None, manifestUrls=None): if not manifestLocation: manifestLocation = destDir manifestLocation = os.path.join(manifestLocation, "manifest.json") archiveFile = os.path.join(destDir, archiveName) name = archiveName if not os.path.isabs(archiveName) else os.path.relpath(archiveName, destDir) manifest = CraftManifest.load(manifestLocation, urls=manifestUrls) entry = manifest.get(str(self)) entry.addFile(name, CraftHash.digestFile(archiveFile, CraftHash.HashAlgorithm.SHA256), version=self.version) manifest.dump(manifestLocation) @property def shortcuts(self) -> []: """ Return a list of shortcuts we want installe""" out = [] if "shortcuts" in self.defines: out += self.defines["shortcuts"] return out