Esempio n. 1
0
    def test_findProxyInstallations(self):
        # check if user has a valid proxy:
        sitRootPath = SIT.getParentPath()
        sitProxyPath = SIT.getPath()

        Any.requireIsDir(sitRootPath)
        Any.requireIsDir(sitProxyPath)
        ProxyDir.requireIsProxyDir(sitProxyPath)

        # create a fake package directory within the proxy...
        packageName = 'UnittestABCDEF123'
        goodNameDir = os.path.join(sitProxyPath, 'Libraries', packageName)
        goodVersionDir = os.path.join(goodNameDir, '42.0')
        badVersionDir = os.path.join(goodNameDir, '21.0')
        FastScript.mkdir(goodVersionDir)

        resultList = ProxyDir.findProxyInstallations()
        self.assertTrue(
            len(resultList) >= 1
        )  # may be greater if developer has real software installed in proxy

        self.assertTrue(goodVersionDir in resultList)
        self.assertFalse(badVersionDir in resultList)

        # clean-up
        FastScript.remove(goodNameDir)
Esempio n. 2
0
def getFlatDependencies(canonicalPaths, cache=None, sitPath=None):
    """
        Resolves all dependencies recursively and converts them to a flat
        set of overall dependencies.

        This function might be handy to determine all SIT packages that
        need to transferred to another site.
    """
    cache = {} if cache is None else cache
    sitPath = SIT.getPath() if sitPath is None else sitPath

    Any.requireIsIterable(canonicalPaths)
    Any.requireIsDict(cache)
    Any.requireIsTextNonEmpty(sitPath)

    result = set()

    for canonicalPath in canonicalPaths:
        requireIsCanonicalPath(canonicalPath)

        result.add('sit://' + canonicalPath)

        deps = getDependencies(canonicalPath,
                               recursive=True,
                               cache=cache,
                               systemPackages=False,
                               sitPath=sitPath)

        flatDeps = FastScript.flattenList(deps)

        for item in flatDeps:
            result.add(item)

    return result
Esempio n. 3
0
def isInstalled(url, sitPath=None):
    """
        Checks if the given package is installed. Depending on the URL type
        different checks will be performed, e.g.:

        'sit://Libraries/Serialize/3.0'    # check in current SIT
        'deb://binutils'                   # check for O.S. packages (*.deb)

        You may speed-up this function by providing 'sitPath' so that it
        does not need to be queried internally every time.
    """
    from ToolBOSCore.Platforms import Debian

    Any.requireIsTextNonEmpty(url)

    if ':' not in url:
        # default to SIT packages
        url = 'sit://' + url

    protocol, remainder = splitURL(url)

    if protocol == 'sit':
        if not sitPath:
            sitPath = SIT.getPath()

        status = isInstalled_sitPackage(remainder, sitPath)
    elif protocol == 'deb':
        try:
            status = Debian.isInstalled(remainder)
        except OSError as details:
            raise OSError(details)
    else:
        raise RuntimeError('invalid URL protocol or format')

    return status
Esempio n. 4
0
    def makeDocumentation( self ):
        from ToolBOSCore.BuildSystem.DocumentationCreator import DocumentationCreator

        if self._outOfTree:
            logging.warning( 'documentation creation in out-of-tree build not implemented' )
            return False


        if Any.getDebugLevel() <= 3:
            from six import StringIO

            # capture output so that it's not printed
            output = StringIO()
        else:
            output = None


        try:
            dstSIT = SIT.getPath()

            dc = DocumentationCreator( self._sourceTree, dstSIT, output, output )
            dc.generate()

        except AssertionError as e:

            logging.error( 'failed to create documentation: %s', e )
            return False

        except subprocess.CalledProcessError:

            if output:
                print( output.getvalue() )

            logging.error( 'failed to create documentation' )
            return False
    def test_proxyInstallation(self):
        oldcwd = os.getcwd()
        packageName = 'ExamplePackage'
        packageVersion = '1.0'
        category = 'Applications'
        projectRoot = os.path.join('.', packageName, packageVersion)
        output = StringIO() if Any.getDebugLevel() <= 3 else None
        platform = Platforms.getHostPlatform()
        sitPath = SIT.getPath()

        # build + install package
        FastScript.changeDirectory(projectRoot)

        bst = BuildSystemTools()
        bst.setStdOut(output)
        bst.setStdErr(output)
        bst.compile()

        Any.requireIsDirNonEmpty('build')
        Any.requireIsDirNonEmpty(os.path.join('build', platform))
        Any.requireIsDirNonEmpty('examples')
        Any.requireIsDirNonEmpty(os.path.join('examples', platform))

        for fileName in ('ThreadingExampleAtomicOperation',
                         'ThreadingExampleJoin', 'ThreadingExampleTraps'):
            Any.requireIsFileNonEmpty(os.path.join('bin', platform, fileName))

        if not ProxyDir.isProxyDir(sitPath):
            self.skip("%s: Is not a proxy directory" % sitPath)

        bst.makeDocumentation()
        bst.proxyInstall()
        installRoot = os.path.join(sitPath, category, packageName,
                                   packageVersion)

        # check result
        Any.requireIsDir(installRoot)
        Any.requireIsDirNonEmpty(os.path.join(installRoot, 'bin', platform))
        Any.requireIsDirNonEmpty(os.path.join(installRoot, 'doc/html'))
        Any.requireIsFileNonEmpty(
            os.path.join(installRoot, 'doc/html/index.html'))
        Any.requireIsFileNonEmpty(os.path.join(installRoot, 'pkgInfo.py'))
        Any.requireIsFileNonEmpty(os.path.join(installRoot,
                                               'packageVar.cmake'))

        for fileName in ('ThreadingExampleAtomicOperation',
                         'ThreadingExampleJoin', 'ThreadingExampleTraps'):
            Any.requireIsFileNonEmpty(
                os.path.join(installRoot, 'bin', platform, fileName))

        # clean-up
        bst.uninstall(cleanGlobalInstallation=False)
        bst.distclean()

        self.assertFalse(os.path.exists(installRoot))

        FastScript.changeDirectory(oldcwd)
    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.getPath(), package )

        super( BSTProxyInstalledPackage, self ).open( topLevelDir )
Esempio n. 7
0
def getMaintainerFromFilesystem(project):
    """
        Returns the username of the maintainer by reading the fileowner of
        the project from the current SIT.
    """
    requireIsCanonicalPath(project)

    path = SIT.getPath() + os.sep + project
    owner = FastScript.getFileOwner(path)

    return owner
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)')
Esempio n. 9
0
def findProxyInstallations(checkLinks=False):
    """
        Returns a list of packages installed within the proxy SIT.

        A ValueError will be raised if the current SIT is not a proxy.

        If 'checkLinks' == True, each version symlink will also be tested
        if it really points into the root SIT. For example, it might be
        difficult to localize a manually changed link that points e.g. in
        another group proxy or so.
    """
    resultList = []
    sit = SIT.getPath()
    sitParent = SIT.getParentPath()  # support cascaded proxies
    excludePattern = re.compile('^(parentTree|\d+\.\d+.*)$')
    criteria = re.compile("^(\d+)\.(\d+)(.*)")

    Any.requireIsDir(sit)
    Any.requireIsDir(sitParent)
    requireIsProxyDir(sit)

    # find all entries within the proxy that seem to be a version number
    dirList = FastScript.getDirsInDirRecursive(
        sit,
        excludePattern=excludePattern,
        onError=FastScript.printPermissionDenied)

    # check each found entry if it is a version directory, if so we
    # can expect that this is a local project installation
    for project in dirList:
        for entry in os.listdir(project):
            joinedPath = os.path.join(project, entry)

            # only perform test on version numbers
            if criteria.search(entry):

                # don't use os.path.isdir() as it follows symlinks!
                fileType = os.lstat(joinedPath).st_mode

                if checkLinks == True and stat.S_ISLNK(fileType) == True:
                    # test if symlink points into root SIT
                    target = os.readlink(joinedPath)

                    if target[0] == '/' and not target.startswith(sitParent):
                        logging.warning(joinedPath + ': points to ' + target)

                elif stat.S_ISDIR(fileType):
                    # we found a proxy installation
                    resultList.append(joinedPath)

    return resultList
Esempio n. 10
0
    def __init__(self,
                 projectRoot,
                 sitPath=None,
                 stdout=None,
                 stderr=None,
                 details=None):

        Any.requireIsDir(projectRoot)

        self.projectRoot = projectRoot
        logging.debug('topLevelDir=%s' % projectRoot)

        if details is None:
            details = PackageDetector(projectRoot)

            try:
                details.retrieveMakefileInfo()
            except EnvironmentError as e:
                logging.warning(e)  # e.g. $SIT not defined in environment

        else:
            Any.requireIsInstance(details, PackageDetector)

        if sitPath is None:
            sitPath = SIT.getPath()

        if FastScript.getEnv('MAKEFILE_DOC') == 'FALSE':
            handler = NullBackend
        elif details.docTool == 'doxygen':
            handler = DoxygenBackend
        elif details.docTool == 'matdoc':
            handler = MatlabBackend
        elif details.docTool == '':
            handler = NullBackend
        elif details.isMatlabPackage():

            # [CIA-1131] matdoc no longer works on xenial64
            #
            # On Ubuntu 16.04 disable documentation creation
            # (do not use doxygen either to not overwrite the
            # correct matdoc-output from Ubuntu 14.04 machines)

            if getHostPlatform().startswith('xenial'):
                handler = NullBackend
            else:
                handler = MatlabBackend

        else:
            handler = DoxygenBackend

        self.backend = handler(details, sitPath, stdout, stderr)
Esempio n. 11
0
def getIndexBaseDir(sitProxyPath=None):
    """
        Returns the path to the user's index base directory.

        If 'sitProxyPath' is omitted then the current Proxy-SIT is used.
    """
    if sitProxyPath is None:
        sitProxyPath = SIT.getPath()

    ProxyDir.requireIsProxyDir(sitProxyPath)

    indexBaseDir = os.path.join(sitProxyPath, 'Modules', 'Index')

    return indexBaseDir
Esempio n. 12
0
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)
Esempio n. 13
0
class BSTProxyInstalledPackage( BSTInstalledPackage ):
    """
        Represents a software package which is installed in the
        Proxy-SIT of the developer.
    """
    _sitPath = SIT.getPath()


    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.getPath(), package )

        super( BSTProxyInstalledPackage, self ).open( topLevelDir )
    def populate(self):
        """
            Scans all package in SIT and stores the ground-truth pkgInfo.py
            information into one giant hashtable for later fast access.

            The assignment is "packageURL": { pkgInfo data }
        """
        sitPath = SIT.getPath()
        canonicalPaths = SIT.getCanonicalPaths(sitPath)
        Any.requireIsListNonEmpty(canonicalPaths)

        for canonicalPath in canonicalPaths:
            ProjectProperties.requireIsCanonicalPath(canonicalPath)

            packageURL = 'sit://' + canonicalPath
            installRoot = os.path.join(sitPath, canonicalPath)
            detector = PackageDetector(installRoot)
            detector.retrieveMakefileInfo()

            self._cache[packageURL] = detector
Esempio n. 15
0
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
Esempio n. 16
0
def updateProxyDir(removeBrokenSymlinks=True,
                   removeEmptyCategories=True,
                   linkNewPackagesIntoProxy=True,
                   checkProxyLinkTarget=True,
                   checkProxyLinkedVersion=True,
                   removeProxyInstallations=False,
                   cleanHomeDirectory=True,
                   updateRTMapsIndex=True,
                   dryRun=False):
    """
        Updates the SIT proxy directory of the current user.

        The user may influence which worker functions shall be called
        (default: all)

          removeBrokenSymlinks:     remove broken symlinks to uninstalled
                                    packages

          removeEmptyCategories:    remove SIT categories that became empty,
                                    or packages without any version

          linkNewPackagesIntoProxy: if there are new packages in the global
                                    SIT, add a link to them into the proxy

          checkProxyLinkTarget:     verify that links are valid

          checkProxyLinkedVersion:  if there is a higher revision globally
                                    installed (e.g. 1.0.100) and the user
                                    has a link 1.0 pointing to 1.0.99 in the
                                    proxy, the 1.0 link will get updated to
                                    1.0.100 in order not to use an outdated
                                    revision

          removeProxyInstallations: DELETE ALL PACKAGES installed in the
                                    proxy (if any)

          cleanHomeDirectory:       clean-up unused files under ~/.HRI

          updateRTMapsIndex:        update *.pck symlinks in ~/.HRI/RTMaps

        If dryRun=True, nothing will actually be done.
    """
    from ToolBOSCore.Tools import RTMaps

    sitRoot = SIT.getParentPath()
    sitProxy = SIT.getPath()
    proxyChanged = False
    sitRootPkgList = []
    sitProxyPkgList = []
    pluginsEnabled = []

    Any.requireIsBool(removeBrokenSymlinks)
    Any.requireIsBool(removeEmptyCategories)
    Any.requireIsBool(linkNewPackagesIntoProxy)
    Any.requireIsBool(checkProxyLinkTarget)
    Any.requireIsBool(checkProxyLinkedVersion)
    Any.requireIsBool(removeProxyInstallations)
    Any.requireIsBool(cleanHomeDirectory)
    Any.requireIsBool(updateRTMapsIndex)
    Any.requireIsBool(dryRun)

    Any.requireMsg(sitRoot != sitProxy,
                   '%s: Is not a proxy directory' % sitProxy)

    # TBCORE-466: user should be able to disable particular plugins

    #if removeProxyInstallations:               # added later, see below
    #pluginsEnabled.append( _removeProxyInstallations )

    if removeBrokenSymlinks:
        pluginsEnabled.append(_removeBrokenSymlinks)

    if removeEmptyCategories:
        pluginsEnabled.append(_removeEmptyCategories)

    if linkNewPackagesIntoProxy:
        pluginsEnabled.append(_linkNewPackagesIntoProxy)

    if checkProxyLinkTarget:
        pluginsEnabled.append(_checkProxyLinkTarget)

    if checkProxyLinkedVersion:
        pluginsEnabled.append(_checkProxyLinkedVersion)

    if cleanHomeDirectory:
        pluginsEnabled.append(_cleanHomeDirectory)

    if not pluginsEnabled:
        raise ValueError('Nothing to do. Please check your parameters.')

    # in any case, after updating the proxy verify that there are no legacy
    # *.def files laying around
    pluginsEnabled.append(_checkDefFiles)

    tp = ThreadPool.ThreadPool()

    tp.add(SIT.getProjectsWithErrorHandling, sitRoot, sitRootPkgList)
    tp.add(SIT.getProjectsWithErrorHandling, sitProxy, sitProxyPkgList)

    tp.run()

    if removeProxyInstallations:
        changed = _removeProxyInstallations(sitRootPkgList, sitProxyPkgList,
                                            sitRoot, sitProxy, dryRun)

        if changed > 0:
            sitProxyPkgList = []
            SIT.getProjectsWithErrorHandling(sitProxy, sitProxyPkgList)

    for func in pluginsEnabled:
        proxyChanged |= func(sitRootPkgList, sitProxyPkgList, sitRoot,
                             sitProxy, dryRun)

    if updateRTMapsIndex:
        if RTMaps.isInstalled(sitRoot):
            RTMaps.updateComponentIndex(sitRoot, sitProxy, dryRun)
        else:
            logging.debug('RTMaps not installed')

    msg = 'Your proxy is up-to-date%s.' % (' now'
                                           if proxyChanged == True else '')
    logging.info('')
    logging.info(msg)
Esempio n. 17
0
def main(package):

    # When using shell tab-completion on SIT paths for the canonical path,
    # a trailing slash might be added. Remove this before proceeding.

    if package.endswith('/'):
        package = package[:-1]
        logging.debug('package truncated to: %s', package)

    try:
        ProjectProperties.requireIsCanonicalPath(package)
    except AssertionError as details:
        logging.error(details)
        raise SystemExit

    # stop if package is maintained via SVN

    svnUrl = ProjectProperties.getSVNLocationFromFilesystem(package)

    if svnUrl:
        logging.debug('found SVN URL: %s', svnUrl)
        logging.error('')
        logging.error('Package is maintained via SVN and cannot be cloned.')
        logging.error(
            'Use GitCheckout.py to access it in Git-style using the git-svn bridge :-)'
        )
        logging.error('')
        sys.exit(-2)

    # try to look-up repository URL from SIT, if not found do at least
    # a good guess

    installRoot = os.path.join(SIT.getPath(), package)

    try:
        detector = PackageDetector.PackageDetector(installRoot)
        detector.retrieveMetaInfoFromSIT()

        url = detector.gitOrigin

    except AssertionError as e:
        logging.error(e)
        raise SystemExit()

    # logging.debug( 'guessing Git location...' )
    # url = ProjectProperties.guessGitLocation( package )     # TODO: implement guessing

    if not url:
        logging.error('unable to determine Git repository location')
        sys.exit(-1)

    Any.requireIsTextNonEmpty(url)

    repo = Git.RemoteGitRepository(url)

    # warn if cloning from unofficial host (see CIA-1062)
    repo.checkIsOnMasterServer()

    if userName:
        repo.setUserName(userName)

    Any.setDebugLevel(logging.DEBUG)  # print executed command
    repo.clone()
Esempio n. 18
0
def source(package):
    """
        Python equivalent of "source BashSrc" from SIT, in order to setup
        PATH, LD_LIBRARY_PATH,... within the Python process.

        @anchor ProcessEnv_source
    """
    ProjectProperties.requireIsCanonicalPath(package)

    sourced = FastScript.getEnv('TOOLBOSCORE_SOURCED')
    Any.requireMsg(sourced, '$TOOLBOSCORE_SOURCED must not be empty')

    # avoid double-sourcing
    if package in sourced:
        return True

    ProjectProperties.requireIsInstalled(package)

    logging.debug('source %s/pkgInfo.py', package)
    sourced = '%s %s' % (package, sourced)
    FastScript.setEnv('TOOLBOSCORE_SOURCED', sourced)

    # load pkgInfo.py (if exists)
    try:
        content = getPkgInfoContent(project=package)
    except AssertionError:
        return True  # no such file, this is OK
    except (IOError, OSError) as details:
        logging.error(details)
        return False

    # setup environment of this package
    try:
        envVars = content['envVars']
    except KeyError:
        envVars = []  # no such setting, this is OK

    sitPath = SIT.getPath()

    for name, value in envVars:

        # replace known placeholdes
        value = value.replace('${INSTALL_ROOT}',
                              os.path.join(sitPath, package))

        FastScript.setEnv_withExpansion(name, value)

    # source dependent packages
    try:
        # TODO: eventually extend to sourcing recommended/suggested packages
        depList = content['depends']
    except (AssertionError, KeyError):
        depList = []  # no such setting, this is OK

    for dep in depList:
        if not dep.startswith('deb://'):
            source(SIT.strip(dep))

    # special treatment of PYTHONPATH:
    # After sourcing add new entries in PYTHONPATH to sys.path
    _expandSysPath()

    return True
Esempio n. 19
0
class BSTInstalledPackage( BSTPackage ):
    """
        Represents a software package which is installed in the
        Software Installation Tree (SIT).
    """
    _sitPath       = SIT.getPath()
    _metaInfoCache = None


    def __init__( self, url=None ):
        super( BSTInstalledPackage, self ).__init__( url )

        self.revDepSet  = None
        self.revDepTree = None


    def open( self, topLevelDir ):
        super( BSTInstalledPackage, self ).open( topLevelDir )


    def isInstalled( self ):
        # if package could not be opened then self.detector is None,
        # hence accessing self.detector.topLevelDir won't work
        if self.detector is None:
            return False

        Any.requireIsTextNonEmpty( self.detector.topLevelDir )
        Any.requireIsTextNonEmpty( self._sitPath )

        return os.path.exists( os.path.join( self._sitPath,
                                             self.detector.topLevelDir ) )


    def retrieveReverseDependencies( self, recursive ):
        self._ensureMetaInfoCache()

        self.revDepSet  = set()
        self.revDepTree = list()

        for depURL in self._metaInfoCache.getReverseDependencies( self.url ):
            ProjectProperties.requireIsURL( depURL )

            # no Debian packages can appear in reverse dependencies of SIT packages
            depPackage = BSTInstalledPackage( depURL )
            depPackage.detector = self._metaInfoCache.getDetector( depURL )

            if recursive:
                depPackage.retrieveReverseDependencies( recursive )
                self.revDepSet.update( depPackage.revDepSet )

            self.revDepSet.add( depURL )
            self.revDepTree.append( depPackage )


    def _ensureMetaInfoCache( self ):
        """
            Creates and populates the internal MetaInfoCache,
            if not already existing.
        """
        if not BSTInstalledPackage._metaInfoCache:
            BSTInstalledPackage._metaInfoCache = MetaInfoCache()
            BSTInstalledPackage._metaInfoCache.populate()


    def setMetaInfoCache( self, metaInfoCache ):
        Any.requireIsInstance( metaInfoCache, MetaInfoCache )

        BSTInstalledPackage._metaInfoCache = metaInfoCache
from ToolBOSCore.Settings import ToolBOSSettings
from ToolBOSCore.Storage import SIT
from ToolBOSCore.Storage.BashSrc import BashSrcWriter
from ToolBOSCore.Storage.CmdSrc import CmdSrcWriter
from ToolBOSCore.Storage.PackageVar import PackageVarCmakeWriter
from ToolBOSCore.Storage.PkgInfoWriter import PkgInfoWriter
from ToolBOSCore.Util import Any
from ToolBOSCore.Util import FastScript

# location of core templates such as Master, C_Library etc.
templateDir_core = os.path.join(FastScript.getEnv('TOOLBOSCORE_ROOT'),
                                'etc/mako-templates')

# location of higher-level templates such as BBCMs etc.
templateDir = os.path.join(
    SIT.getPath(), ToolBOSSettings.getConfigOption('package_pkgCreator'),
    'etc/mako-templates')


class PackageCreator(object):

    # some templates should not be directly visible to the users,
    # e.g. the Software Quality Guideline, if False they will be hidden
    # in the Package Creator GUI (TBCORE-1201)

    show = True

    def __init__(self, packageName, packageVersion, values=None, outputDir=''):
        Any.requireIsTextNonEmpty(packageName)
        Any.requireIsTextNonEmpty(packageVersion)
        Any.requireIsText(outputDir)
Esempio n. 21
0
def registerNormalPackage(package,
                          sitProxyPath=None,
                          indexBaseDir=None,
                          dryRun=False):
    """
        Creates a symlink to the *.pck file of 'package' within the RTMaps
        index.

        RTMAPS_VERSION is taken from the dependency list of the package.
    """
    if sitProxyPath is None:
        sitProxyPath = SIT.getPath()

    if indexBaseDir is None:
        indexBaseDir = getIndexBaseDir(sitProxyPath)

    ProjectProperties.requireIsCanonicalPath(package)
    Any.requireIsDir(sitProxyPath)
    Any.requireIsDir(indexBaseDir)
    Any.requireIsBool(dryRun)

    platformList = getPlatformNames()
    packageName = ProjectProperties.getPackageName(package)
    packageVersion = ProjectProperties.getPackageVersion(package)
    versionTokens = ProjectProperties.splitVersion(packageVersion)
    majorVersion = int(versionTokens[0])
    minorVersion = int(versionTokens[1])
    installRoot = os.path.join(sitProxyPath, package)

    Any.requireIsListNonEmpty(platformList)
    Any.requireIsTextNonEmpty(packageName)
    Any.requireIsTextNonEmpty(packageVersion)
    Any.requireIsDir(installRoot)

    deps = ProjectProperties.getDependencies(package)
    try:
        Any.requireIsListNonEmpty(deps)
    except AssertionError:
        logging.debug(
            'empty list of dependencies in RTMaps package is unplausible')
        msg = "%s: unable to retrieve dependencies, please check SIT installation" % package
        raise ValueError(msg)

    expr = re.compile('^sit://External/RTMaps/(\d+\.\d+)')

    # detect RTMaps version used by package
    rtmapsVersion = ''

    for dep in deps:
        tmp = expr.match(dep)

        if tmp:
            rtmapsVersion = tmp.group(1)
            break

    Any.requireIsTextNonEmpty(rtmapsVersion)
    logging.debug('%s depends on RTMaps %s', package, rtmapsVersion)

    libDir = os.path.join(installRoot, 'lib')
    pckFiles = FastScript.findFiles(libDir, ext='.pck')

    Any.requireMsg(
        len(pckFiles) > 0,
        package + ": No *.pck file found, forgot to compile?")

    for relPath in pckFiles:
        pckFileName = os.path.basename(relPath)
        pckPackage = os.path.splitext(pckFileName)[0]
        pckFileExt = os.path.splitext(pckFileName)[1]

        logging.debug('registering %s', pckPackage)

        for platform in platformList:
            pckPath = os.path.join(libDir, platform, pckFileName)
            dstDir = os.path.join(indexBaseDir, rtmapsVersion, platform)

            if os.path.exists(pckPath):
                symlinkFile = '%s_%d.%d%s' % (pckPackage, majorVersion,
                                              minorVersion, pckFileExt)
                symlinkPath = os.path.join(dstDir, symlinkFile)
                target = pckPath

                FastScript.link(target, symlinkPath, dryRun)
Esempio n. 22
0
class TaskButtonsWidget(QGroupBox, object):
    """
        Provides a group box with the main control buttons (build, clean,
        install, run unittest,...)
    """

    build = pyqtSignal()
    clean = pyqtSignal()
    globalInstall = pyqtSignal()
    proxyInstall = pyqtSignal()
    quit = pyqtSignal()
    test = pyqtSignal()

    hasProxy = ProxyDir.isProxyDir(SIT.getPath())

    def __init__(self):
        super(QGroupBox, self).__init__('commands')

        self._buildButton = QPushButton("&build")
        self._cleanButton = QPushButton("&distclean")
        self._testButton = QPushButton("run &testsuite")
        self._proxyInstButton = QPushButton("pro&xy inst.")
        self._globalInstButton = QPushButton("global &inst.")
        self._quitButton = QPushButton("&quit")

        self._cleanButton.setToolTip('delete build artefacts')
        self._buildButton.setToolTip('compile for selected platforms')
        self._proxyInstButton.setToolTip('install into Proxy-SIT')
        self._globalInstButton.setToolTip('globally install into SIT')
        self._testButton.setToolTip('start unittest (if present)')

        if not self.hasProxy:
            self._proxyInstButton.setToolTip('No Proxy-SIT available')
            self._proxyInstButton.setEnabled(False)

        self._cleanButton.pressed.connect(self.clean.emit)
        self._buildButton.pressed.connect(self.build.emit)
        self._proxyInstButton.pressed.connect(self.proxyInstall.emit)
        self._globalInstButton.pressed.connect(self.globalInstall.emit)
        self._testButton.pressed.connect(self.test.emit)
        self._quitButton.pressed.connect(self.quit.emit)

        # set start-up focus and run
        self._buildButton.setFocus()

        self._layout = QGridLayout()
        self._layout.addWidget(self._cleanButton, 1, 1)
        self._layout.addWidget(self._buildButton, 1, 2)
        self._layout.addWidget(self._proxyInstButton, 2, 1)
        self._layout.addWidget(self._globalInstButton, 2, 2)
        self._layout.addWidget(self._testButton, 3, 1)
        self._layout.addWidget(self._quitButton, 3, 2)


        if not os.path.exists( 'unittest.sh' ) and \
           not os.path.exists( 'unittest.bat' ):

            self._testButton.setEnabled(False)
            self._testButton.setToolTip(
                'unittest.sh or unittest.bat not found')

        self.setLayout(self._layout)

    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 __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()
Esempio n. 24
0
# When using shell tab-completion on SIT paths for the canonical path,
# a trailing slash might be added. Remove this before proceeding.

if package.endswith('/'):
    package = package[:-1]
    logging.debug('package truncated to: %s', package)

try:
    ProjectProperties.requireIsCanonicalPath(package)
except AssertionError as details:
    logging.error(details)
    raise SystemExit

# look for repository URL

sitPath = SIT.getPath()
installRoot = os.path.join(sitPath, package)
url = None
detector = None

try:
    detector = PackageDetector.PackageDetector(installRoot)
except AssertionError:
    pass  # package not found in SIT

if detector is not None:

    detector.retrieveMetaInfoFromSIT()

    if detector.gitOrigin:
Esempio n. 25
0
def getDependencies(project,
                    recursive=False,
                    cache=None,
                    ignoreErrors=False,
                    highlightMissing=True,
                    systemPackages=True,
                    sitPath=None):
    """
        Returns a list containing the direct dependencies of this package.
        If "recursive=True", they will be followed and the list actually
        becomes a nested list / tree. If the package does not have any
        dependencies the list will be empty.

        'project' must be specified in canonical form, e.g.:
           - 'Libraries/Serialize/3.0'
           - 'sit://Libraries/Serialize/3.0'
           - 'deb://gcc'

        If 'recursive=False', the list will contain the pure untreated
        strings stored in the pkgInfo.py file. There is no preprocessing
        done on its semantics. In recursive mode, we need to follow those
        paths and need to resolve 'sit://' etc.

        The 'cache' map is internally used to avoid processing already
        treated packages again. You should not specify this parameter when
        calling this function unless you need to query the dependencies of
        multiple projects in a list. In such case providing a cache-map
        will improve performance a lot.

        If 'systemPackages=False', Non-SIT packages such as *.deb or *.rpm
        packages will be excluded from the result list.

        You may speed-up this function by providing 'sitPath' so that it
        does not need to be queried internally every time.
    """
    from ToolBOSCore.Storage.PkgInfo import getPkgInfoContent

    if project.find('://') > 0:
        projectURL = project
        project = SIT.strip(project)
    else:
        projectURL = 'sit://' + project  # default protocol

    resultList = []

    if cache is None:
        cache = {}

    if not sitPath:
        sitPath = SIT.getPath()

    try:  # first look-up the cache
        depList = cache[projectURL]
    except KeyError:  # if not found read from filesystem
        if projectURL.startswith('sit://'):
            try:
                depList = getPkgInfoContent(project)['depends']
            except (AssertionError, KeyError):
                depList = []
        else:
            depList = []  # retrieving *.deb dependencies not implemented

    # ensure to only use URL-style dependencies
    for i, dep in enumerate(depList):
        if isinstance(dep, str):
            depList[i] = dep.replace('${HRI_GLOBAL_ROOT}/', 'sit://')

    # store the direct dependencies into the cache map
    cache[projectURL] = depList

    for dep in depList:
        if isinstance(dep, str):

            if systemPackages == False and not dep.startswith('sit://'):
                continue

            resultList.append(dep)

            if recursive:
                # 2012-10-09 reactivated this check for isInstalled() == False,
                # needed by ListDependencies.py + ExportWizard.py

                try:
                    if not isInstalled(dep, sitPath):
                        if highlightMissing:
                            resultList.append([missingPkgMsg])

                        if not ignoreErrors:
                            msg = '%s depends on %s which is not installed' \
                                  % ( project, dep )
                            raise RuntimeError(msg)
                except ValueError:
                    raise ValueError('invalid dependency "%s" in package %s' %
                                     (dep, project))

                subDepList = getDependencies(dep, recursive, cache,
                                             ignoreErrors, highlightMissing,
                                             systemPackages, sitPath)

                if len(subDepList) > 0:
                    resultList.append(subDepList)
        else:
            raise TypeError('dependency entry is not of type "str"')

    return resultList
bstpkg_global = BSTPackage.BSTGloballyInstalledPackage()

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