def _createArchive(self, archiveName, sourceDir, destDir, createDigests=True, extention=None) -> bool: if extention is None: extention = "." + CraftCore.settings.get("Packager", "7ZipArchiveType", "7z") if extention == ".7z" and CraftCore.compiler.isUnix: if self.package.path == "dev-utils/7zip" or not CraftCore.cache.findApplication( "7za"): extention = ".tar.xz" else: extention = ".tar.7z" archiveName = str((Path(destDir) / archiveName)) + extention if not utils.compress(archiveName, sourceDir): return False if createDigests: if not CraftCore.settings.getboolean("Packager", "CreateCache"): self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(archiveName) else: if CraftCore.settings.getboolean("ContinuousIntegration", "UpdateRepository", False): manifestUrls = [self.cacheRepositoryUrls()[0]] else: manifestUrls = None self._generateManifest(destDir, archiveName, manifestLocation=self.cacheLocation(), manifestUrls=manifestUrls) return True
def _createArchive(self, archiveName, sourceDir, destDir, createDigests=True) -> bool: archiveName = str((Path(destDir) / archiveName)) if not utils.compress(archiveName, sourceDir): return False if createDigests: if CraftCore.settings.getboolean( "Packager", "CreateCache") and CraftCore.settings.get( "Packager", "PackageType") == "SevenZipPackager": if CraftCore.settings.getboolean("ContinuousIntegration", "UpdateRepository", False): manifestUrls = [self.cacheRepositoryUrls()[0]] else: CraftCore.log.warning( f"Creating new cache, if you want to extend an existing cache, set \"[ContinuousIntegration]UpdateRepository = True\"" ) manifestUrls = None self._generateManifest(destDir, archiveName, manifestLocation=self.cacheLocation(), manifestUrls=manifestUrls) else: self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(archiveName) return True
def createPackage(self): """ create a package """ CraftCore.log.debug("packaging using the MacDMGPackager") defines = self.setDefaults(self.defines) # TODO: provide an image with dbg files if not self.internalCreatePackage(defines): return False appPath = self.getMacAppPath(defines) if not appPath: return False archive = os.path.normpath(self.archiveDir()) CraftCore.log.info(f"Packaging {appPath}") dmgDest = defines["setupname"] if os.path.exists(dmgDest): utils.deleteFile(dmgDest) appName = defines['appname'] + ".app" if not utils.system(["create-dmg", "--volname", os.path.basename(dmgDest), # Add a drop link to /Applications: "--icon", appName, "140", "150", "--app-drop-link", "350", "150", dmgDest, appPath]): return False if not CodeSign.signMacPackage(dmgDest): return False CraftHash.createDigestFiles(dmgDest) return True
def _compress(self, archiveName, sourceDir, destDir): utils.deleteFile(archiveName) app = CraftCore.cache.findApplication("7za") kw = {} progressFlags = [] if CraftCore.cache.checkCommandOutputFor(app, "-bs"): progressFlags = ["-bso2", "-bsp1"] kw["stderr"] = subprocess.PIPE archive = os.path.join(destDir, archiveName) if os.path.isfile(archive): utils.deleteFile(archive) cmd = [app, "a", "-r", archive, os.path.join(sourceDir, "*")] + progressFlags if not utils.system(cmd, displayProgress=True, **kw): CraftCore.log.critical(f"while packaging. cmd: {cmd}") if not CraftCore.settings.getboolean("Packager", "CreateCache"): self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(archive) else: if CraftCore.settings.getboolean("ContinuousIntegration", "UpdateRepository", False): manifestUrls = [self.cacheRepositoryUrls()[0]] else: manifestUrls = None self._generateManifest(destDir, archiveName, manifestLocation=self.cacheLocation(), manifestUrls=manifestUrls)
def _compress(self, archiveName, sourceDir, destDir, createDigests=True) -> bool: archive = os.path.join(destDir, archiveName) utils.createDir(os.path.dirname(archive)) if os.path.isfile(archive): utils.deleteFile(archive) if OsUtils.isUnix(): if not self.__xz(archive, sourceDir): return False else: if not self.__7z(archive, sourceDir): return False if createDigests: if not CraftCore.settings.getboolean("Packager", "CreateCache"): self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(archive) else: if CraftCore.settings.getboolean("ContinuousIntegration", "UpdateRepository", False): manifestUrls = [self.cacheRepositoryUrls()[0]] else: manifestUrls = None self._generateManifest(destDir, archiveName, manifestLocation=self.cacheLocation(), manifestUrls=manifestUrls) return True
def _compress(self, archiveName, sourceDir, destDir): utils.deleteFile(archiveName) app = utils.utilsCache.findApplication("7za") kw = {} progressFlags = "" if utils.utilsCache.checkCommandOutputFor(app, "-bs"): progressFlags = " -bso2 -bsp1" kw["stderr"] = subprocess.PIPE archive = os.path.join(destDir, archiveName) if os.path.isfile(archive): utils.deleteFile(archive) cmd = f"\"{app}\" a {progressFlags} -r \"{archive}\" \"{sourceDir}/*\"" if not utils.system(cmd, displayProgress=True, **kw): craftDebug.log.critical(f"while packaging. cmd: {cmd}") if not craftSettings.getboolean("Packager", "CreateCache"): CraftHash.createDigestFiles(archive) else: cacheFilePath = os.path.join(self.cacheLocation(), "manifest.json") if os.path.exists(cacheFilePath): with open(cacheFilePath, "rt+") as cacheFile: cache = json.load(cacheFile) else: cache = {} if not str(self) in cache: cache[str(self)] = {} cache[str(self)][archiveName] = { "checksum": CraftHash.digestFile(archive, CraftHash.HashAlgorithm.SHA256) } with open(cacheFilePath, "wt+") as cacheFile: json.dump(cache, cacheFile, sort_keys=True, indent=2)
def createPackage(self): """ create a package """ if not self.isNsisInstalled(): return False craftDebug.log.debug("packaging using the NullsoftInstallerPackager") self.internalCreatePackage() self.preArchive() self.generateNSISInstaller() CraftHash.createDigestFiles(self.defines["setupname"]) return True
def createPackage(self): """ create a package """ CraftCore.log.debug("packaging using the MacDMGPackager") self.internalCreatePackage() self.preArchive() self._setDefaults() archive = self.archiveDir() appPath = os.path.join(archive, self.defines['apppath'], f"{self.defines['appname']}.app") if os.path.exists(os.path.join(archive, "lib/plugins")): utils.mergeTree(os.path.join(archive, "lib/plugins"), os.path.join(appPath, "Contents/PlugIns/")) targetLibdir = os.path.join(appPath, "Contents/Frameworks/") if not os.path.exists(targetLibdir): os.makedirs(targetLibdir) if os.path.exists(os.path.join(archive, "lib")): utils.mergeTree(os.path.join(archive, "lib"), targetLibdir) if os.path.exists(os.path.join(archive, "share")): utils.mergeTree(os.path.join(archive, "share"), os.path.join(appPath, "Contents/Resources/")) utils.mergeTree(os.path.join(archive, "bin"), os.path.join(appPath, "Contents/MacOS/")) env = os.environ env['DYLD_LIBRARY_PATH'] = os.path.join(CraftStandardDirs.craftRoot(), "lib") if not utils.systemWithoutShell([ "dylibbundler", "-of", "-b", "-p", "@executable_path/../Frameworks", "-d", targetLibdir, "-x", f"{appPath}/Contents/MacOS/{self.defines['appname']}" ], env=env): CraftCore.log.warning("Failed to run dylibbundler") if not utils.systemWithoutShell([ "macdeployqt", appPath, "-always-overwrite", "-dmg", "-verbose=2" ], env=env): CraftCore.log.warning("Failed to run macdeployqt!") dmgSrc = appPath.replace(".app", ".dmg") dmgDest = os.path.join(self.packageDestinationDir(), os.path.basename(dmgSrc)) utils.copyFile(dmgSrc, dmgDest, linkOnly=False) CraftHash.createDigestFiles(dmgDest) return True
def createPackage(self): """ create a package """ if not self.isNsisInstalled(): return False CraftCore.log.debug("packaging using the NullsoftInstallerPackager") if CraftCore.compiler.isMSVC(): # we use the redist installer self.ignoredPackages.append("libs/runtime") self.internalCreatePackage() self.generateNSISInstaller() destDir, archiveName = os.path.split(self.defines["setupname"]) self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(self.defines["setupname"]) return True
def createPackage(self): """ create a package """ if not self.isNsisInstalled(): return False CraftCore.log.debug("packaging using the NullsoftInstallerPackager") if not super().createPackage(): return False if not self.generateNSISInstaller(): return False destDir, archiveName = os.path.split(self.setupName) self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(self.setupName) return True
def createPackage(self): """ create a package """ CraftCore.log.debug("packaging using the MacDMGPackager") if not CraftCore.cache.findApplication("packagesutil"): CraftCore.log.critical( "Craft requires dev-utils/packagesdev to create a package, please install dev-utils/packagesdev\n" "\t'craft dev-utils/packagesdev'") return False defines = self.setDefaults(self.defines) if not "pkgproj" in defines: CraftCore.log.error( "Cannot not create .pkg because no .pkgproj was defined.") return False if not self.internalCreatePackage( defines, seperateSymbolFiles=True, packageSymbols=True): return False packageDest = Path(defines["setupname"]) if packageDest.exists(): utils.deleteFile(packageDest) pkgprojPath = defines["pkgproj"] # set output file basename packagesutil = CraftCore.cache.findApplication("packagesutil") if not utils.system([ packagesutil, '--file', pkgprojPath, 'set', 'project', 'name', packageDest.stem ]): return False packagesbuild = CraftCore.cache.findApplication("packagesbuild") if not utils.system([ packagesbuild, "-v", '--reference-folder', os.path.dirname(self.getMacAppPath(defines)), '--build-folder', packageDest.parent, pkgprojPath ]): return False if not CodeSign.signMacPackage(packageDest): return False CraftHash.createDigestFiles(packageDest) return True
def createPackage(self): """ create a package """ if not self.isInnoInstalled(): return False CraftCore.log.debug("packaging using the InnoSetupPackager") defines = self.setDefaults(self.defines) if not self.internalCreatePackage(defines, True): return False if not self.generateInnoInstaller(defines): return False destDir, archiveName = os.path.split(defines["setupname"]) self._generateManifest(destDir, archiveName) CraftHash.createDigestFiles(defines["setupname"]) return True
def createPackage(self): """ create a package """ CraftCore.log.debug("packaging using the MacDMGPackager") if not self.internalCreatePackage(): return False self._setDefaults() archive = os.path.normpath(self.archiveDir()) appPath = self.defines['apppath'] if not appPath: apps = glob.glob(os.path.join(archive, f"**/{self.defines['appname']}.app"), recursive=True) if len(apps) != 1: CraftCore.log.error(f"Failed to detect {self.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 = apps[0] appPath = os.path.join(archive, appPath) appPath = os.path.normpath(appPath) CraftCore.log.info(f"Packaging {appPath}") targetLibdir = os.path.join(appPath, "Contents", "Frameworks") utils.createDir(targetLibdir) moveTargets = [ (os.path.join(archive, "lib", "plugins"), os.path.join(appPath, "Contents", "PlugIns")), (os.path.join(archive, "plugins"), os.path.join(appPath, "Contents", "PlugIns")), (os.path.join(archive, "lib"), targetLibdir), (os.path.join(archive, "share"), os.path.join(appPath, "Contents", "Resources"))] if not appPath.startswith(archive): moveTargets += [(os.path.join(archive, "bin"), os.path.join(appPath, "Contents", "MacOS"))] for src, dest in moveTargets: if os.path.exists(src): if not utils.mergeTree(src, dest): return False with utils.ScopedEnv({'DYLD_FALLBACK_LIBRARY_PATH' : os.path.join(CraftStandardDirs.craftRoot(), "lib")}): if not utils.system(["dylibbundler", "--overwrite-files", "--bundle-deps", "--install-path", "@executable_path/../Frameworks", "--dest-dir", targetLibdir, "--fix-file", os.path.join(appPath, "Contents", "MacOS", self.defines['appname'])]): return False if not utils.system(["macdeployqt", appPath, "-always-overwrite", "-verbose=1"]): return False name = self.binaryArchiveName(fileType="", includeRevision=True) dmgDest = os.path.join(self.packageDestinationDir(), f"{name}.dmg") if os.path.exists(dmgDest): utils.deleteFile(dmgDest) if not utils.system(["create-dmg", "--volname", name, dmgDest, appPath]): return False CraftHash.createDigestFiles(dmgDest) return True
def test_createDigestFiles(self): # TODO: check file content algorithms = CraftHash.HashAlgorithm.__members__.values() CraftHash.createDigestFiles(self.tmpFile, algorithms=algorithms) for algorithm in algorithms: self.assertEquals(os.path.exists(self.tmpFile + algorithm.fileEnding()), True)
def createPackage(self): """ create a package """ CraftCore.log.debug("packaging using the MacDMGPackager") if not self.internalCreatePackage(): return False self._setDefaults() archive = os.path.normpath(self.archiveDir()) appPath = self.defines['apppath'] if not appPath: apps = glob.glob(os.path.join(archive, f"**/{self.defines['appname']}.app"), recursive=True) if len(apps) != 1: CraftCore.log.error( f"Failed to detect {self.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 = apps[0] appPath = os.path.join(archive, appPath) appPath = os.path.normpath(appPath) CraftCore.log.info(f"Packaging {appPath}") targetLibdir = os.path.join(appPath, "Contents", "Frameworks") utils.createDir(targetLibdir) moveTargets = [(os.path.join(archive, "lib", "plugins"), os.path.join(appPath, "Contents", "PlugIns")), (os.path.join(archive, "plugins"), os.path.join(appPath, "Contents", "PlugIns")), (os.path.join(archive, "lib"), targetLibdir), (os.path.join(archive, "share"), os.path.join(appPath, "Contents", "Resources"))] if not appPath.startswith(archive): moveTargets += [(os.path.join(archive, "bin"), os.path.join(appPath, "Contents", "MacOS"))] for src, dest in moveTargets: if os.path.exists(src): if not utils.mergeTree(src, dest): return False dylibbundler = MacDylibBundler(appPath) with utils.ScopedEnv({ 'DYLD_FALLBACK_LIBRARY_PATH': targetLibdir + ":" + os.path.join(CraftStandardDirs.craftRoot(), "lib") }): CraftCore.log.info("Bundling main binary dependencies...") mainBinary = Path(appPath, "Contents", "MacOS", self.defines['appname']) if not dylibbundler.bundleLibraryDependencies(mainBinary): return False # Fix up the library dependencies of files in Contents/Frameworks/ CraftCore.log.info("Bundling library dependencies...") if not dylibbundler.fixupAndBundleLibsRecursively( "Contents/Frameworks"): return False CraftCore.log.info("Bundling plugin dependencies...") if not dylibbundler.fixupAndBundleLibsRecursively( "Contents/PlugIns"): return False if not utils.system( ["macdeployqt", appPath, "-always-overwrite", "-verbose=1"]): return False # macdeployqt might just have added some explicitly blacklisted files blackList = Path(self.packageDir(), "mac_blacklist.txt") if blackList.exists(): blackList = [self.read_blacklist(str(blackList))] # use it as whitelist as we want only matches, ignore all others matches = utils.filterDirectoryContent( appPath, whitelist=lambda x, root: self.blacklisted(x, blackList), blacklist=lambda x, root: True) for f in matches: CraftCore.log.info(f"Remove blacklisted file: {f}") utils.deleteFile(f) # macdeployqt adds some more plugins so we fix the plugins after calling macdeployqt dylibbundler.checkedLibs = set( ) # ensure we check all libs again (but # we should not need to make any changes) CraftCore.log.info( "Fixing plugin dependencies after macdeployqt...") if not dylibbundler.fixupAndBundleLibsRecursively( "Contents/PlugIns"): return False CraftCore.log.info( "Fixing library dependencies after macdeployqt...") if not dylibbundler.fixupAndBundleLibsRecursively( "Contents/Frameworks"): return False # Finally sanity check that we don't depend on absolute paths from the builder CraftCore.log.info( "Checking for absolute library paths in package...") found_bad_dylib = False # Don't exit immeditately so that we log all the bad libraries before failing: if not dylibbundler.areLibraryDepsOkay(mainBinary): found_bad_dylib = True CraftCore.log.error( "Found bad library dependency in main binary %s", mainBinary) if not dylibbundler.checkLibraryDepsRecursively( "Contents/Frameworks"): CraftCore.log.error( "Found bad library dependency in bundled libraries") found_bad_dylib = True if not dylibbundler.checkLibraryDepsRecursively( "Contents/PlugIns"): CraftCore.log.error( "Found bad library dependency in bundled plugins") found_bad_dylib = True if found_bad_dylib: CraftCore.log.error( "Cannot not create .dmg since the .app contains a bad library depenency!" ) return False name = self.binaryArchiveName(fileType="", includeRevision=True) dmgDest = os.path.join(self.packageDestinationDir(), f"{name}.dmg") if os.path.exists(dmgDest): utils.deleteFile(dmgDest) appName = self.defines['appname'] + ".app" if not utils.system([ "create-dmg", "--volname", name, # Add a drop link to /Applications: "--icon", appName, "140", "150", "--app-drop-link", "350", "150", dmgDest, appPath ]): return False CraftHash.createDigestFiles(dmgDest) return True