def open( self, package=None ): if self.url: ProjectProperties.requireIsURL( self.url ) package = ProjectProperties.splitURL( self.url )[1] else: ProjectProperties.requireIsCanonicalPath( package ) topLevelDir = os.path.join( SIT.getRootPath(), package ) super( BSTGloballyInstalledPackage, self ).open( topLevelDir )
def _findMatdoc(self): sitPath = SIT.getRootPath() package = getConfigOption('package_matdoc') fileName = 'matdoc' exePath = os.path.join(sitPath, package, 'bin', fileName) if os.path.exists(exePath): return exePath else: logging.warning('%s: No such file', exePath) return fileName # default to 'matdoc'
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 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 printBuildCommands(orderedList): """ Prints the build-instruction for each package in the list, e.g.: build src/ToolBOSCore build src/ToolBOSLib build src/IniConfigFile build src/Middleware Note: The list shall already be sorted according to build order! """ Any.requireIsListNonEmpty(orderedList) sitRootPath = SIT.getRootPath() commands = [] for canonicalPath in orderedList: ProjectProperties.requireIsCanonicalPath(canonicalPath) installRoot = os.path.join(sitRootPath, canonicalPath) Any.requireIsExisting(installRoot) detector = PackageDetector.PackageDetector(installRoot) detector.retrieveMetaInfoFromSIT() vcsRelPath = detector.vcsRelPath vcsRoot = detector.vcsRoot if vcsRoot: Any.requireIsTextNonEmpty(vcsRoot) repo = VersionControl.auto(vcsRoot) repoName = repo.getRepositoryName() if vcsRelPath: location = os.path.join('src', repoName, vcsRelPath) else: location = os.path.join('src', repoName) command = 'build %s' % location else: command = '# build %s# location unknown' % canonicalPath.ljust(70) commands.append(command) for command in commands: print(command)
class BSTGloballyInstalledPackage( BSTInstalledPackage ): """ Represents a software package which is installed in the Global SIT of the site running ToolBOS SDK. """ _sitPath = SIT.getRootPath() def open( self, package=None ): if self.url: ProjectProperties.requireIsURL( self.url ) package = ProjectProperties.splitURL( self.url )[1] else: ProjectProperties.requireIsCanonicalPath( package ) topLevelDir = os.path.join( SIT.getRootPath(), package ) super( BSTGloballyInstalledPackage, self ).open( topLevelDir )
def test_createProxyDir(self): sitProxyPath = tempfile.mkdtemp(prefix='test-') sitRootPath = SIT.getRootPath() canonicalPath = ToolBOSSettings.canonicalPath Any.requireIsDir(sitRootPath) # proxy directory must not exist, yet (function would refuse otherwise) FastScript.remove(sitProxyPath) ProxyDir.createProxyDir(sitRootPath, sitProxyPath) Any.requireIsDir(os.path.join(sitProxyPath, 'Libraries')) Any.requireIsDir(os.path.join(sitProxyPath, 'Modules/BBCM')) Any.requireIsDir(os.path.join(sitProxyPath, 'Libraries')) self.assertTrue( os.path.islink(os.path.join(sitProxyPath, canonicalPath))) self.assertTrue( os.path.islink(os.path.join(sitProxyPath, 'External/java/1.8'))) FastScript.remove(sitProxyPath)
def isDeprecated(canonicalPath): """ Checks from the filesystem if the specified package (canonical path) is flagged as deprecated. Returns True if either of these files exists: <sitRoot>/Libraries/Spam/42.0/deprecated.txt <sitRoot>/Libraries/Spam/deprecated.txt or if the canonicalPath is listed in the file <sitPath>/Temporary/CIA/1.0/deprecatedOverride.txt. """ requireIsCanonicalPath(canonicalPath) filename = 'deprecated.txt' sitRoot = SIT.getRootPath() pkgPath = os.path.join(sitRoot, canonicalPath) check1 = os.path.join(sitRoot, os.path.dirname(canonicalPath), filename) check2 = os.path.join(sitRoot, canonicalPath, filename) # if package is not present in SIT we can't give reliable information # if it is deprecated or not if not os.path.exists(pkgPath): raise ValueError("%s: Package not installed in SIT" % canonicalPath) if os.path.exists(check1) or os.path.exists(check2): return True # check CIA operator "sudo override" overrideFile = os.path.join(SIT.getPath(), 'Temporary/CIA/1.0/deprecatedOverride.txt') if os.path.exists(overrideFile): for line in FastScript.getFileContent(overrideFile, splitLines=True): if line.strip() == canonicalPath: return True return False
def _findDoxygen(self): sitPath = SIT.getRootPath() package = getConfigOption('package_doxygen') hostPlatform = getHostPlatform() fileName = 'doxygen' exePath = os.path.join(sitPath, package, 'bin', hostPlatform, fileName) if os.path.exists(exePath): return exePath else: logging.debug('%s: No such file', exePath) logging.debug('falling back to "doxygen" in $PATH') found = ProcessEnv.which('doxygen') if found: logging.debug('using doxygen from $PATH: %s', found) return found else: raise EnvironmentError( '"doxygen" neither found in SIT nor installed locally')
def setDeprecated(canonicalPath, allVersions=False, message=''): """ Deprecate a version of a package. canonicalPath is used to deprecate the package. If allVersions is True, all versions are deprecated. message will be written into deprecated.txt. """ requireIsCanonicalPath(canonicalPath) Any.requireIsText(message) if message: reason = message + '\n' else: reason = message if allVersions: relPath = os.path.dirname(canonicalPath) else: relPath = canonicalPath absPath = os.path.join(SIT.getRootPath(), relPath) filePath = os.path.join(absPath, "deprecated.txt") if os.path.exists(absPath): try: FastScript.setFileContent(filePath, reason) logging.info('%s deprecated', relPath) logging.debug('Created file %s', filePath) except (IOError, OSError) as e: logging.warning(e) logging.error('Could not deprecate %s', relPath) return False else: logging.warning('%s is not installed!', relPath) return False return True
def __init__(self, model): super(DependenciesDialog, self).__init__() Any.requireIsInstance(model, QtPackageModel.BSTPackageModel) numColumns = 4 self._model = model self._treeMode = True self._reverseMode = False self._tree = None self._treeWidget = QTreeWidget() self._red = QColor(255, 120, 120) self._green = QColor(220, 255, 220) self._grey = QColor(240, 240, 240) self._canonicalPath = self._model.getCanonicalPath() self._sitProxyPath = SIT.getPath() self._sitRootPath = SIT.getRootPath() self._hasProxy = ProxyDir.isProxyDir(self._sitProxyPath) # obtain data and create one QTreeWidgetItem for each self._data1 = self._model.getDependencySet() self._data2 = self._model.getDependencyTree() self._data3 = self._model.getReverseDependencySet() self._data4 = self._model.getReverseDependencyTree() self._aptCmd = self._model.getDepInstallCmd_APT() logging.debug('data1: %s', self._data1) logging.debug('data2: %s', self._data2) logging.debug('data3: %s', self._data3) logging.debug('data4: %s', self._data4) depsEnabled = self._data1 is not None and self._data2 is not None revDepsEnabled = self._data3 is not None and self._data4 is not None if depsEnabled: self._tree1 = self._createTreeWidgetFromSet(self._data1, False) self._tree2 = self._createTreeWidgetFromList(self._data2, False) if revDepsEnabled: self._tree3 = self._createTreeWidgetFromSet(self._data3, True) self._tree4 = self._createTreeWidgetFromList(self._data4, True) if not depsEnabled and not revDepsEnabled: logging.error('unable to show dependency-dialog') return depsTooltip = 'low-level packages needed by the current one' if revDepsEnabled: revDepsTooltip = 'high-level packages which use the current one' else: revDepsTooltip = 'not globally installed --> no reverse dependencies' self._depRadio_direct = QRadioButton('&dependencies') self._depRadio_direct.setChecked(True) self._depRadio_direct.setToolTip(depsTooltip) self._depRadio_direct.clicked.connect(self._showDependencies) self._depRadio_reverse = QRadioButton('&reverse dependencies') self._depRadio_reverse.setToolTip(revDepsTooltip) self._depRadio_reverse.setEnabled(revDepsEnabled) self._depRadio_reverse.clicked.connect(self._showReverseDependencies) depSelectLayout = QVBoxLayout() depSelectLayout.addWidget(self._depRadio_direct) depSelectLayout.addWidget(self._depRadio_reverse) depSelectWidget = QGroupBox('direction') depSelectWidget.setLayout(depSelectLayout) # initial / default view: show own dependencies as tree self._tree = self._tree2 self._updateView() self._treeWidget.setColumnCount(numColumns) self._treeWidget.setRootIsDecorated( False) # top-left has no parent line self._treeWidget.setSortingEnabled(False) header = self._treeWidget.header() header.setStretchLastSection(False) header.setSectionResizeMode( 0, QHeaderView.Stretch) # stretch first column headerWidget = QTreeWidgetItem([ 'dependency', 'installed in proxy SIT', 'installed in global SIT', 'installed locally' ]) for i in range(1, numColumns): header.setSectionResizeMode(i, QHeaderView.ResizeToContents) headerWidget.setTextAlignment(i, Qt.AlignCenter) self._treeWidget.setHeaderItem(headerWidget) self._aptLabel = QLabel('Debian/Ubuntu packages needed:') self._aptWidget = QTextEdit(self._aptCmd) self._aptWidget.setFixedHeight(100) self._aptWidget.setFontFamily("Courier New") self._aptWidget.setReadOnly(True) toggleView = QPushButton('&toggle tree/flat view') toggleView.pressed.connect(self._toggleTree) self._expandButton = QPushButton('&expand all') self._expandButton.pressed.connect(self._treeWidget.expandAll) self._collapseButton = QPushButton('&collapse all') self._collapseButton.pressed.connect(self._treeWidget.collapseAll) self._collapseButton.pressed.connect( lambda: self._tree.setExpanded(True)) closeButton = QPushButton('&OK') closeButton.pressed.connect(self.close) buttonLayout = QHBoxLayout() buttonLayout.setAlignment(Qt.AlignRight) buttonLayout.addWidget(toggleView) buttonLayout.addSpacing(1) buttonLayout.addWidget(self._expandButton) buttonLayout.addWidget(self._collapseButton) buttonLayout.addWidget(closeButton) buttonWidget = QWidget() buttonWidget.setLayout(buttonLayout) mainLayout = QVBoxLayout() mainLayout.addWidget(depSelectWidget) mainLayout.addWidget(self._treeWidget) mainLayout.addWidget(self._aptLabel) mainLayout.addWidget(self._aptWidget) mainLayout.addWidget(buttonWidget) # noinspection PyArgumentList screen = QApplication.desktop().screenGeometry() dialogWidth = screen.width() * 0.5 dialogHeight = screen.height() * 0.75 self.setLayout(mainLayout) self.setWindowTitle('Dependencies of %s' % self._canonicalPath) self.resize(dialogWidth, dialogHeight) self.move(screen.center() - self.rect().center()) # center self.show()
try: bstpkg_global.open(canonicalPath) bstpkg_global.retrieveReverseDependencies(True) except AssertionError as details: # most likely: package is not globally installed logging.info(details) bstpkg_global.revDepSet = set() Any.requireIsSet(bstpkg_src.depSet) Any.requireIsSet(bstpkg_global.revDepSet) fullSet = bstpkg_src.depSet | bstpkg_global.revDepSet sitProxyPath = SIT.getPath() sitRootPath = SIT.getRootPath() installStatus = {} installStatusLocal = {} installStatusProxy = {} installStatusGlobal = {} logging.debug('retrieving install status of [reverse-]dependencies...') for packageURL in fullSet: protocol, remainder = ProjectProperties.splitURL(packageURL) # _installStatus is the generic form, holding the installStatus # for Debian packages (= locally) and SIT packages (= in proxy) # since those are the effective locations for compiling sources if protocol == 'deb':