def _dependencyUpgrade( self, dryRun, replacementMap, ticketID ): """ Patches the CMakeLists.txt / packageVar.cmake / ... files (if necessary) to include different packages. """ Any.requireIsBool( dryRun ) Any.requireIsDict( replacementMap ) Any.requireIsTextNonEmpty( ticketID ) status1 = False status2 = False status3 = False modified = [] for old, new in replacementMap.items(): status1 |= self._replace( 'CMakeLists.txt', old, old, new, ticketID, dryRun ) status2 |= self._replace( 'packageVar.cmake', old, old, new, ticketID, dryRun ) status3 |= self._replace( 'pkgInfo.py', old, old, new, ticketID, dryRun ) if status1: modified.append( 'CMakeLists.txt' ) if status2: modified.append( 'packageVar.cmake' ) if status3: modified.append( 'pkgInfo.py' ) return modified
def updateComponentIndex(sitRootPath, sitProxyPath, dryRun): """ Cleans the index directory and creates all symlinks from scratch. """ Any.requireIsDir(sitRootPath) Any.requireIsDir(sitProxyPath) Any.requireIsBool(dryRun) ProxyDir.requireIsProxyDir(sitProxyPath) indexBaseDir = getIndexBaseDir(sitProxyPath) # We would like to start with a fresh indexBaseDir, however cannot delete # it because it also contains the DTBOS *.def files. Hence we only remove # subdirectories (corresponding to the RTMaps versions) within this # directories and keep *.def files as they are. See TBCORE-974). # #FastScript.remove( indexBaseDir ) for subDir in FastScript.getDirsInDir(indexBaseDir): path = os.path.join(indexBaseDir, subDir) FastScript.remove(path) for version in getVersionsAvailable(sitRootPath): dstDir = os.path.join(indexBaseDir, version) logging.debug('mkdir %s', dstDir) if not dryRun: FastScript.mkdir(dstDir) logging.debug('updating RTMaps component index...') registerDistributionPackages(sitRootPath, sitProxyPath, dryRun) registerNormalPackages(sitRootPath, dryRun) registerNormalPackages(sitProxyPath, dryRun)
def showSummary(self, state): """ Force showing (or not) a summary at the end of run(). """ Any.requireIsBool(state) self._summaryEnabled = state
def setIsFirstInstall( self, isFirstInstall ): """ You should set this boolean to true to mark the package as "new" upon the very first installation. """ Any.requireIsBool( isFirstInstall ) self._isFirstInstall = isFirstInstall
def _showAsList(package, reverse, missingOnly): """ Direcyly print list of [reverse] dependencies onto console. """ Any.requireIsInstance(package, BSTPackage.BSTPackage) Any.requireIsBool(reverse) data = package.revDepSet if reverse else package.depSet Any.requireIsSet(data) packageURLs = list(data) packageURLs.sort() for packageURL in packageURLs: Any.requireIsTextNonEmpty(packageURL) if missingOnly: try: if not ProjectProperties.isInstalled(packageURL): print(packageURL) except EnvironmentError: # unknown, treat as "not installed" print(packageURL) else: print(packageURL)
def __init__(self, packageName, packageVersion, values=None, outputDir=''): Any.requireIsTextNonEmpty(packageName) Any.requireIsTextNonEmpty(packageVersion) Any.requireIsText(outputDir) self.packageName = packageName self.packageVersion = packageVersion self.templateDir = templateDir self.templateDir_core = templateDir_core self.outputDir = outputDir self.dstDir = os.path.join(outputDir, packageName, packageVersion) # replacement map passed to templating engine self.values = { 'packageName': packageName, 'PACKAGENAME': packageName.upper(), 'packageVersion': packageVersion } try: if values is None: self.force = False else: Any.requireIsDict(values) Any.requireIsBool(values['force']) self.force = values['force'] except KeyError: # not defined self.force = False if os.path.exists(self.dstDir) and not self.force: raise ValueError('%s: directory already exists' % self.dstDir) if values: Any.requireIsDict(values) self.values.update(values)
def setEnabled(self, status, button='all'): Any.requireIsBool(status) Any.requireIsTextNonEmpty(button) if button == 'all': self._buildButton.setEnabled(status) self._cleanButton.setEnabled(status) self._globalInstButton.setEnabled(status) self._proxyInstButton.setEnabled(status and self.hasProxy) self._testButton.setEnabled(status) elif button == 'build': self._buildButton.setEnabled(status) elif button == 'clean': self._cleanButton.setEnabled(status) elif button == 'globalInstall': self._globalInstButton.setEnabled(status) elif button == 'proxyInstall': self._proxyInstButton.setEnabled(status and self.hasProxy) elif button == 'test': self._testButton.setEnabled(status) else: raise ValueError('unknown button: %s' % button)
def setWithX11Tunnel(self, withX11): """ Use SSH's X11 forwarding when executing commands on remote hosts? """ Any.requireIsBool(withX11) self.withX11Tunnel = withX11
def setAllowUnknownArgs(self, boolean): """ By default an error message will be displayed when an unknown option is passed. With setAllowUnknownArgs( True ) you allow such options, e.g. for later passing to another program. """ Any.requireIsBool(boolean) self._allowUnknown = boolean
def setDetached(self, detached): """ Set to True if the process shall continue to run after the current process terminates, effectively turning the executed process into a daemon. """ Any.requireIsBool(detached) self._detached = detached
def setDryRun(self, boolean): """ If 'dryRun' is True, nothing will actually happen but the command is just printed (for debugging purposes). """ Any.requireIsBool(boolean) self._dryRun = boolean logging.debug('VCS operating in dry-run mode: %s', self._dryRun)
def getSourceCodeCommand(self, asSubModule=False): Any.requireIsBool(asSubModule) Any.requireIsTextNonEmpty(self.url) if asSubModule: cmd = 'git submodule add %s' % self.url else: cmd = 'git clone %s' % self.url return cmd
def printFetchCommands(packageList, asSubModule=True): """ Prints the VCS fetch command for each package in the list. Duplicates will be removed, and output will be sorted for better readability, e.g.: asSubModule = True: git submodule add [email protected]:TECH_Team/BPL.git git submodule add [email protected]:ToolBOS/BasicComponents.git git submodule add [email protected]:ToolBOS/ToolBOSLib.git asSubModule = False: git clone [email protected]:TECH_Team/BPL.git git clone [email protected]:ToolBOS/BasicComponents.git git clone [email protected]:ToolBOS/ToolBOSLib.git """ Any.requireIsIterable(packageList) Any.requireIsBool(asSubModule) sitRootPath = SIT.getRootPath() commands = set() # avoids duplicates for canonicalPath in packageList: ProjectProperties.requireIsCanonicalPath(canonicalPath) installRoot = os.path.join(sitRootPath, canonicalPath) Any.requireIsExisting(installRoot) detector = PackageDetector.PackageDetector(installRoot) detector.retrieveMetaInfoFromSIT() vcsRoot = detector.vcsRoot if vcsRoot: Any.requireIsTextNonEmpty(vcsRoot) repo = VersionControl.auto(vcsRoot) if isinstance(repo, SVN.SVNRepository): repo.setConfiguredUserName() command = repo.getSourceCodeCommand() elif isinstance(repo, Git.RemoteGitRepository): command = repo.getSourceCodeCommand(asSubModule) else: raise TypeError('unexpected datatype: %s', type(repo)) else: command = '# VCS location unknown: %s' % canonicalPath commands.add(command) for command in sorted(commands): print(command)
def __init__( self, packagePath, isFirstInstall, msgType, message ): """ Creates a new global install log entry instance. """ Any.requireIsTextNonEmpty( packagePath ) Any.requireIsBool( isFirstInstall ) Any.requireIsTextNonEmpty( msgType ) Any.requireIsIn( msgType, ( 'NEW', 'FIX', 'DOC', 'IMP' ) ) self._date = datetime.now().strftime( "%Y-%m-%d %H:%M:%S" ) self._installRoot = '' self._packageCategory = '' self._packageName = '' self._packageVersion = '' self._maintainer = getuser() self._isFirstInstall = False self._msgType = 'NEW' self._message = '' self._fileName = None self._fileExt = 'xml' ( self._packageCategory, self._packageName, self._packageVersion ) = \ splitPath( packagePath ) Any.requireIsTextNonEmpty( self._packageCategory ) Any.requireIsTextNonEmpty( self._packageName ) Any.requireIsTextNonEmpty( self._packageVersion ) self.setIsFirstInstall( isFirstInstall ) self.setMsgType( msgType ) self.setMessage( message ) sitRootPath = getRootPath() timestamp = int( time() ) getFileName = lambda t: os.path.join( sitRootPath, 'Temporary', 'GlobalInstallLogfiles', 'GlobalInstall_%d.%s' % \ ( timestamp, self._fileExt ) ) fileName = getFileName( timestamp ) while os.path.exists( fileName ): logging.debug( 'global log entry %d exists, increasing to %d', timestamp, timestamp + 1 ) # if a logfile of this name already exists, try increasing the # timestamp timestamp += 1 fileName = getFileName( timestamp ) self.setFileName( fileName )
def uninstall(canonicalPath, cleanGlobalInstallation, dryRun=False): """ Delete a package from SIT, this includes: * Proxy SIT directory * Global SIT installation * BBCM *.def file * RTMaps index entry If 'cleanGlobalInstallation=True' the package will also be uninstalled from global SIT (if applicable). If False it will only be uninstalled from the proxy SIT. """ from ToolBOSCore.Platforms import Platforms from ToolBOSCore.Tools import RTMaps requireIsCanonicalPath(canonicalPath) Any.requireIsBool(dryRun) sitProxyPath = SIT.getPath() sitRootPath = SIT.getRootPath() Any.requireIsTextNonEmpty(sitProxyPath) Any.requireIsTextNonEmpty(sitRootPath) installRoot_proxy = os.path.join(sitProxyPath, canonicalPath) installRoot_root = os.path.join(sitRootPath, canonicalPath) rtmapsVersion = FastScript.getEnv('RTMAPS_VERSION') logging.info('uninstalling %s', canonicalPath) logging.info('cleaning proxy-installation') FastScript.remove(installRoot_proxy, dryRun) if cleanGlobalInstallation: logging.info('cleaning global-installation') FastScript.remove(installRoot_root, dryRun) if rtmapsVersion: Any.requireIsTextNonEmpty(rtmapsVersion) hostPlatform = Platforms.getHostPlatform() symlink_relHGR = RTMaps.getIndexFilePath_relHGR( canonicalPath, rtmapsVersion, hostPlatform) Any.requireIsTextNonEmpty(symlink_relHGR) symlinkPath = os.path.join(sitProxyPath, symlink_relHGR) Any.requireIsTextNonEmpty(symlinkPath) FastScript.remove(symlinkPath, dryRun) else: logging.debug( 'skipped searching for RTMaps index symlink (RTMaps not sourced)')
def copyBasePackages(srcRoot, dstRoot, packageList, verbose=True, ignore=None, resolveLTS=False, cacheDir=None): """ Copies all packages in the 'packageList' from the current srcRoot into dstRoot. Use the 'verbose' parameter to see/suppress a little progress information. 'ignore' might be a callable that will be given to shutil.copytree() for filtering-out undesired content. 'resolveLTS' indicates whether or not symlinks to LTS packages shall be resolved: True = copy content of LTS packages (resolve symlinks) False = keep LTS symlinks as they are If 'cacheDir' points to a SIT-like directory, packages aren't copied but instead linked there to speed-up, e.g. while debugging. """ Any.requireIsDir(srcRoot) Any.requireIsDir(dstRoot) Any.requireIsBool(verbose) Any.requireIsBool(resolveLTS) if ignore is not None: Any.requireIsCallable(ignore) if cacheDir is not None: Any.requireIsDirNonEmpty(cacheDir) for package in packageList: if cacheDir: symlink = os.path.join(dstRoot, package) target = os.path.join(cacheDir, package) FastScript.link(target, symlink) else: src = os.path.join(srcRoot, package) dst = os.path.join(dstRoot, package) _copyBasePackage(src, dst, verbose, ignore, resolveLTS)
def setLibraryCheck( self, status ): """ Toggle if LibIndex should detect if multiple versions of the same library clash. This may be used to detect incompatible components for RTBOS. Default: off (False) """ Any.requireIsBool( status ) self.libCheck = status if status: logging.debug( 'symbol-clash detection: enabled' ) else: logging.debug( 'symbol-clash detection: disabled' )
def registerNormalPackages(sitPath, dryRun=False): """ Searches the SIT for RTMaps packages and invokes registerHondaPackage() for each of them. """ Any.requireIsDir(sitPath) Any.requireIsBool(dryRun) sitProxyPath = SIT.getPath() ProxyDir.requireIsProxyDir(sitProxyPath) searchBaseDir = os.path.join(sitPath, 'Modules', 'RTMaps') # Any.requireIsTextNonEmpty( searchBaseDir ) # dir. might not exist Any.requireIsTextNonEmpty(searchBaseDir) indexBaseDir = getIndexBaseDir(sitProxyPath) # Any.requireIsDir( indexBaseDir ) # dir. might not exist Any.requireIsTextNonEmpty(indexBaseDir) logging.debug('SIT path: %s', sitPath) logging.debug('search basedir: %s', searchBaseDir) logging.debug('index basedir: %s', indexBaseDir) # find *.pck files logging.debug('scanning %s...', searchBaseDir) pckPaths = FastScript.findFiles(searchBaseDir, ext='.pck') Any.requireIsList(pckPaths) logging.debug('found HORP files:') logging.debug(pckPaths) # process each *.pck file (tokenize path and create symlink) for pckPath in pckPaths: # the *.pck file is located on the 3rd subdirectory level relative # to the installRoot, so compute the installRoot based on this tokens = pckPath.split(os.path.sep) installRoot = os.path.sep.join(tokens[:-3]) package = SIT.strip(installRoot) Any.requireIsDir(installRoot) Any.requireIsTextNonEmpty(package) try: registerNormalPackage(package, sitProxyPath, indexBaseDir, dryRun) except ValueError as e: logging.error(e)
def _retrieveFileStatus(self, againstServer=False): """ Queries information about the working copy and fills internal members, such as self.items """ from xml.dom import minidom Any.requireIsBool(againstServer) output = StringIO() self.status(againstServer, output, verbose=True, xml=True) Any.requireIsTextNonEmpty(output.getvalue()) dom = minidom.parseString(output.getvalue()) for entry in dom.getElementsByTagName('entry'): wcStatusData = entry.getElementsByTagName('wc-status')[0] try: dom = wcStatusData.getElementsByTagName('commit')[0] commit = AbstractVCS.Commit() commit.author = dom.getElementsByTagName('author')[0] commit.date = dom.getElementsByTagName('date')[0] commit.revision = int(dom.getAttribute('revision')) except IndexError: commit = None item = VersionedItem() item.lastCommit = commit item.path = entry.getAttribute('path') item.props = wcStatusData.getAttribute('props') item.type = wcStatusData.getAttribute('item') try: item.revision = int(wcStatusData.getAttribute('revision')) except ValueError: item.revision = -1 # use the revision of "." as the wc's main revision if item.path == '.': self.revision = item.revision self.items.add(item)
def _createTreeWidgetFromList(self, package, reverseMode): Any.requireMsg( Any.isInstance( package, BSTPackage.BSTPackage ) or \ Any.isInstance( package, DebianPackage ), 'unexpected datatype: %s' % type(package) ) Any.requireIsBool(reverseMode) Any.requireIsTextNonEmpty(package.url) result = self._createCellWidget(package) treeData = package.revDepTree if reverseMode else package.depTree if treeData: Any.requireIsList(treeData) for dep in treeData: child = self._createTreeWidgetFromList(dep, reverseMode) result.addChild(child) return result
def registerDistributionPackages(sitRootPath, sitProxyPath, dryRun=False): """ Searches the SIT for packages shipped with RTMaps itself (by Intempora). """ Any.requireIsDir(sitRootPath) ProxyDir.requireIsProxyDir(sitProxyPath) Any.requireIsBool(dryRun) platformList = getPlatformNames() rtmapsVersions = getVersionsAvailable(sitRootPath) Any.requireIsListNonEmpty(platformList) Any.requireIsListNonEmpty(rtmapsVersions) installBaseDir = os.path.join(sitRootPath, 'External', 'RTMaps') indexBaseDir = getIndexBaseDir(sitProxyPath) # Any.requireIsDir( indexBaseDir ) # dir. might not exist Any.requireIsTextNonEmpty(indexBaseDir) # find *.pck files shipped with RTMaps for rtmapsVersion in rtmapsVersions: logging.debug('searching for packages shipped with RTMaps %s', rtmapsVersion) for platform in platformList: searchPath = os.path.join(installBaseDir, rtmapsVersion, platform, 'packages') pckPaths = FastScript.findFiles(searchPath, ext='.pck') Any.requireIsList(pckPaths) for pckPath in pckPaths: pckFile = os.path.basename(pckPath) Any.requireIsTextNonEmpty(pckFile) symlink = os.path.join(indexBaseDir, rtmapsVersion, platform, pckFile) target = pckPath FastScript.link(target, symlink, dryRun)
def _convertToTree(package, reverse, recursive, showDuplicates, duplicateData): Any.requireIsInstance(package, AbstractPackage) Any.requireIsBool(reverse) Any.requireIsBool(recursive) Any.requireIsBool(showDuplicates) treeData = [] origData = package.revDepTree if reverse else package.depTree Any.requireIsList(origData) for depPackage in origData: Any.requireIsInstance(depPackage, AbstractPackage) if showDuplicates or depPackage.url not in duplicateData: treeData.append(depPackage.url) duplicateData.add(depPackage.url) if recursive: tmp = _convertToTree(depPackage, reverse, recursive, showDuplicates, duplicateData) if tmp: treeData.append(tmp) return treeData
def getDependenciesFromCurrentPackage(recursive=False, systemPackages=False): """ Assuming the current working directory to be a source package, it queries the dependencies and optionally all the recursive dependencies, too. """ from ToolBOSCore.Storage import CMakeLists from ToolBOSCore.Storage.PkgInfo import getPkgInfoContent Any.requireIsBool(recursive) Any.requireIsBool(systemPackages) fileName = 'CMakeLists.txt' Any.requireIsFileNonEmpty(fileName) fileContent = FastScript.getFileContent(fileName) Any.requireIsTextNonEmpty(fileContent) try: depList = getPkgInfoContent(dirName='.')['depends'] except (AssertionError, IOError, KeyError): depList = CMakeLists.getDependencies(fileContent) Any.requireIsList(depList) if recursive: result = [] cache = {} for dep in depList: result.append(dep) tmp = getDependencies(dep, recursive, cache, systemPackages) if tmp: # do not add empty lists result.append(tmp) else: result = depList return result
def bootstrap(dstPath, buildSDK=False, verbose=True, ignore=None, resolveLTS=False, cacheDir=None): """ Creates a new software installation tree by copying the most basic packages from the current tree. This will be sufficient to execute ToolBOS applications. If 'buildSDK' is set to True, also packages for compiling / building software will be copied into the dstPath. 'ignore' might be a callable that will be given to shutil.copytree() for filtering-out undesired content. 'resolveLTS' indicates whether or not symlinks to LTS packages shall be resolved: True = copy content of LTS packages (resolve symlinks) False = keep LTS symlinks as they are """ Any.requireIsTextNonEmpty(dstPath) Any.requireIsBool(buildSDK) Any.requireIsBool(verbose) Any.requireIsBool(resolveLTS) if ignore is not None: Any.requireIsCallable(ignore) if cacheDir is not None: Any.requireIsDirNonEmpty(cacheDir) srcRoot = getRootPath() dstRoot = dstPath # Any.RequireIsDir( srcRoot ) # not useful error reporting if not os.path.isdir(srcRoot): msg = "%s: Source SIT path does not exist (can't bootstrap from there)" % srcRoot raise RuntimeError(msg) FastScript.mkdir(dstRoot) # create if it does not exist, yet if buildSDK: packageList = getBuildRequirements() else: packageList = getMinRequirements() Any.requireIsListNonEmpty(packageList) copyBasePackages(srcRoot, dstRoot, packageList, verbose, ignore, resolveLTS, cacheDir) # make directory for component description files (*.def) modulesDir = os.path.join(dstRoot, 'Modules') indexDir = os.path.join(dstRoot, 'Modules', 'Index') FastScript.mkdir(indexDir) # will implicitely create the modulesDir os.chmod(modulesDir, 0o0777) os.chmod(indexDir, 0o0777)
def addPackage( self, canonicalPath, recursive, filterFunc ): """ Runs 'filterFunc' on the specified package. Does the same for all dependent packages if 'recursive=True'. """ Any.requireIsTextNonEmpty( canonicalPath ) Any.requireIsBool( recursive ) Any.requireIsCallable( filterFunc ) canonicalPath = strip( canonicalPath ) installRoot = self.sitPath + os.sep + canonicalPath if canonicalPath in self.pkgList: # avoid duplicates return if canonicalPath.startswith( 'deb://' ): # ignore Debian packages return if self._showProgress: logging.info( 'processing %s', canonicalPath ) if os.path.exists( installRoot + os.sep + 'SkipLibIndex' ): logging.debug( '%s: SkipLibIndex found' % canonicalPath ) else: filterFunc( self, canonicalPath ) if recursive: deps = getDependencies( project = canonicalPath, recursive = True, cache = self._depCache, systemPackages = False, sitPath = getPath() ) shortDepList = FastScript.reduceList( deps ) for package in shortDepList: if package not in self.pkgList: self.addPackage( package, False, filterFunc )
def link(target, symlink, dryRun=False): """ Creates a symlink, incl. all the necessary paths to it, and also prints a debug message. """ Any.requireIsTextNonEmpty(symlink) Any.requireIsTextNonEmpty(target) # allow initially broken links Any.requireIsBool(dryRun) # create destination directory (if it does not exist, yet) if not dryRun: mkdir(os.path.dirname(symlink)) # remove any existing link under that name (if existing) if not dryRun: remove(symlink) # create symlink if dryRun: logging.debug('[DRY-RUN] ln -s %s %s', target, symlink) else: logging.debug('ln -s %s %s', target, symlink) os.symlink(target, symlink)
def _createTreeWidgetFromSet(self, package, reverseMode): Any.requireMsg( Any.isInstance( package, BSTPackage.BSTPackage ) or \ Any.isInstance( package, DebianPackage ), 'unexpected datatype: %s' % type(package) ) Any.requireIsBool(reverseMode) treeData = list(package.revDepSet) if reverseMode else list( package.depSet) Any.requireIsList(treeData) treeData.sort() Any.requireIsTextNonEmpty(package.url) result = self._createCellWidget(package) factory = PackageFactory() for packageURL in treeData: dep = factory.create(packageURL) child = self._createCellWidget(dep) result.addChild(child) return result
def getLastCommit(self, short=False): """ Retrieves the ID of the last commit, in either normal (= long) or short form. Returns ID of last commit as string, or raises error if not a Git repository. """ Any.requireIsBool(short) output = StringIO() if short: cmd = "git rev-parse --short HEAD" else: cmd = "git rev-parse HEAD" FastScript.execProgram(cmd, stdout=output, stderr=output) result = output.getvalue().strip() logging.debug('found Git commit ID: %s', result) return result
def _showAsTree(package, reverse, recursive, showDuplicates): """ Convert BSTPackage-tree representation to traditional FastScript-tree format, to re-use existing code. """ Any.requireIsInstance(package, AbstractPackage) Any.requireIsBool(reverse) Any.requireIsBool(recursive) Any.requireIsBool(showDuplicates) treeData = _convertToTree(package, reverse, recursive, showDuplicates, set()) Any.requireIsList(treeData) treeText = FastScript.getTreeView(treeData) Any.requireIsText(treeText) print(treeText.strip())
def retrieveDependencies( self, recursive, normalDeps=True, buildDeps=False, recommendations=False, suggestions=False ): Any.requireIsNotNone( self.detector, 'Please call .open() first' ) Any.requireIsBool( recursive ) Any.requireIsBool( normalDeps ) Any.requireIsBool( buildDeps ) Any.requireIsBool( recommendations ) Any.requireIsBool( suggestions ) self.detector.retrieveMakefileInfo() self.depSet = set() self.depTree = list() debPrefix = 'deb://' sitPrefix = 'sit://' hostPlatform = getHostPlatform() if normalDeps: self.depSet = set( self.detector.dependencies ) try: self.depSet.update( self.detector.dependsArch[ hostPlatform ] ) except KeyError: pass # no such setting, this is OK if buildDeps: self.depSet.update( self.detector.buildDependencies ) try: self.depSet.update( self.detector.buildDependsArch[ hostPlatform ] ) except KeyError: pass # no such setting, this is OK # create a temporary copy of self.depSet while iterating, # otherwise leads to "RuntimeError: Set changed size during iteration" for packageURL in copy.copy( self.depSet ): ProjectProperties.requireIsURL( packageURL ) error = False if packageURL.startswith( sitPrefix ): depPkg = BSTProxyInstalledPackage( packageURL ) try: depPkg.open() if recursive: depPkg.retrieveDependencies( recursive, normalDeps, buildDeps, recommendations, suggestions ) else: depPkg.depSet = set() depPkg.depTree = list() except AssertionError as details: logging.debug( details ) depPkg.depSet = set() depPkg.depTree = list() error = True elif packageURL.startswith( debPrefix ): depPkg = DebianPackage( packageURL ) try: depPkg.retrieveDependencies() except EnvironmentError as details: logging.warning( details ) depPkg.depSet = set() depPkg.depTree = list() else: raise ValueError( 'Unknown URL prefix in "%s"' % packageURL ) if not error: self.depSet.update( depPkg.depSet ) self.depSet.add( packageURL ) self.depTree.append( depPkg )