def _getInstallStatus(self, package, sitPath):

        try:
            installed = ProjectProperties.isInstalled(package, sitPath)
        except ValueError:
            installed = False

        if installed:

            if package.startswith('sit://'):
                msg = '%s: exists' % \
                      os.path.join( sitPath, SIT.strip( package) )
            else:
                msg = '%s: installed on this machine' % \
                      package.replace( 'deb://', '' )

        else:

            if package.startswith('sit://'):
                msg = '%s: no such file or directory' % \
                      os.path.join( sitPath, SIT.strip( package ) )
            else:
                msg = '%s: not installed on this machine' % \
                      package.replace( 'deb://', '' )

        return installed, msg
Example #2
0
def _removeBrokenSymlinks(sitRootPkgList, sitProxyPkgList, sitRoot, sitProxy,
                          dryRun):
    """
        If 'dryRun' is True, it won't actually do anything to your proxy.

        Returns the number of broken links that have been removed
        (or that would have been removed, in case of dry run).
    """
    requireIsProxyDir(sitProxy)

    logging.info('searching for broken symlinks...')
    brokenLinks = _findBrokenLinks(sitProxy)

    for path in brokenLinks:
        if dryRun:
            logging.info('-- DRY RUN --   found broken symlink %s', path)
        else:
            if path.endswith('.py'):
                logging.info('deleting %s', path)
            else:
                logging.info('package was uninstalled: %s', SIT.strip(path))

            os.remove(path)

    return len(brokenLinks)
    def _createCellWidget(self, package):
        Any.requireMsg( Any.isInstance( package, BSTPackage.BSTPackage ) or \
                        Any.isInstance( package, DebianPackage ),
                        'unexpected datatype: %s' % type(package) )

        Any.requireIsTextNonEmpty(package.url)

        cell = QTreeWidgetItem([package.url])
        inSystem = self._model.isInstalled_locally
        inProxy = self._model.isInstalled_proxySIT
        inGlobal = self._model.isInstalled_globalSIT

        ProjectProperties.requireIsCanonicalPath(SIT.strip(package.url))

        if package.url.startswith('sit://'):
            if self._hasProxy:
                self._setCellColorCode(cell, 1, inProxy(package.url))
            else:
                self._setCellColorCode(cell, 1, None)

            self._setCellColorCode(cell, 2, inGlobal(package.url))
            self._setCellColorCode(cell, 3, None)
        else:
            self._setCellColorCode(cell, 1, None)
            self._setCellColorCode(cell, 2, None)
            self._setCellColorCode(cell, 3, inSystem(package.url))

        return cell
Example #4
0
def getBuildDependencies(project, recursive=False):
    """
        For now this simply calls getBuildDependenciesFromPkgInfo(),
        ignoring the case that the pkgInfo.py might not be present.

        Note: Unlike getDependencies(), the result of this function
              is a flat (non-nested) list.
    """
    from ToolBOSCore.Storage.PkgInfo import getPkgInfoContent

    Any.requireIsTextNonEmpty(project)

    try:
        resultList = getPkgInfoContent(project)['buildDepends']
    except (AssertionError, IOError, KeyError):
        resultList = []

    if recursive:
        depList = getDependencies(project, recursive=True)
        depList = FastScript.flattenList(depList)

        for dep in depList:
            if dep.startswith('sit://'):
                try:
                    buildDepList = getPkgInfoContent(
                        SIT.strip(dep))['buildDepends']
                except (AssertionError, IOError, KeyError):
                    buildDepList = []

                if buildDepList:
                    resultList.append(buildDepList)

        resultList = FastScript.reduceList(resultList)

    return resultList
Example #5
0
def getBuildRequirements(projectURL,
                         recursive=False,
                         cache=None,
                         ignoreErrors=False):
    """
        Returns a list of packages that are necessary to build the
        specified package.

        'projectURL' must be a canonical path starting with the "sit://" prefix.

        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.
    """
    Any.requireIsTextNonEmpty(projectURL)
    Any.requireMsg( projectURL.startswith( 'sit://' ) == True,
                       "'project' parameter needs to start with sit:// " + \
                       "'(you passed: %s)" % projectURL )

    # query dependencies of package, don't forget to add package itself
    resultList = []  # projectURL ]
    project = SIT.strip(projectURL)

    if not isinstance(cache, dict):
        cache = {}

    try:  # first look-up the cache
        depList = cache[projectURL]
        #logging.debug( 'CACHE HIT: %s' % projectURL )
    except KeyError:  # if not found read from filesystem
        #logging.debug( 'CACHE MISS: %s' % projectURL )
        tmpList = getDependencies( project, systemPackages=False ) + \
                  getBuildDependencies( project )
        depList = FastScript.reduceList(tmpList)

    # store the direct dependencies into the cache map
    cache.update({projectURL: depList})

    for dep in depList:
        resultList.append(dep)

        if recursive == True and not dep.startswith('deb://'):
            subDepList = getBuildRequirements(dep, recursive, cache,
                                              ignoreErrors)

            for subDep in subDepList:
                if subDep not in resultList:
                    resultList.append(subDep)

    return resultList
Example #6
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)
Example #7
0
def toCanonicalPath(string):
    """
        Takes a string and attempts to shrink it to a canonical path,
        removing any leading SIT prefix or trailing slash.

           '/hri/sit/latest/DevelopmentTools/ToolBOSCore/3.0/'
           --> 'DevelopmentTools/ToolBOSCore/3.0'
    """
    Any.requireIsTextNonEmpty(string)

    canonicalPath = SIT.strip(string)

    # remove trailing slashes (occurs if user provides a string with trailing slashes)
    while canonicalPath.endswith('/'):
        canonicalPath = canonicalPath[0:-1]

    return canonicalPath
Example #8
0
def _removeEmptyCategories(sitRootPkgList, sitProxyPkgList, sitRoot, sitProxy,
                           dryRun):
    """
        If 'dryRun' is True, it won't actually do anything to your proxy.

        Returns the number of empty directories (unused SIT categories,
        packages without any version) that have been removed (or that would
        have been removed, in case of dry run).

        All parameters except 'sitProxy' path will be ignored and only
        kept for compatibility.
    """
    requireIsProxyDir(sitProxy)

    candidates = set()
    whitelist = (os.path.join(sitProxy, 'Modules', 'Index'), )

    for root, dirs, files in os.walk(sitProxy, followlinks=False):
        for entry in dirs:
            candidate = os.path.join(root, entry)

            if candidate not in whitelist:
                candidates.add(candidate)

    # path must not contain anything like a version string
    expr = re.compile('/\d+\.\d+')
    noMatch = lambda p: not (expr.search(p))
    candidates = filter(noMatch, candidates)

    # only keep really empty directories
    isEmptyDir = lambda p: os.listdir(p) == []
    emptyDirs = list(filter(isEmptyDir, candidates))
    emptyDirs.sort()

    for path in emptyDirs:
        if dryRun:
            logging.info('-- DRY RUN --   found empty dir. %s' % path)
        else:
            logging.info('rmdir %s' % SIT.strip(path))
            os.rmdir(path)

    return len(emptyDirs)
       'servers may require additional steps before connecting, such ' + \
       'as setting up "authorized keys" or SSH agents.'

argman = ArgsManagerV2.ArgsManager(desc)

argman.addArgument('-u', '--user', help='account name to use for SVN server')

argman.addArgument('package', help='absolute or canonical package path')

argman.addExample('%(prog)s Libraries/MasterClock/1.6')
argman.addExample('%(prog)s -v -u monthy Libraries/MasterClock/1.6')
argman.addExample('%(prog)s ${SIT}/Libraries/MasterClock/1.6')

args = vars(argman.run())

package = SIT.strip(args['package'])  # strip-off the SIT part if provided
userName = args['user']

#----------------------------------------------------------------------------
# Main program
#----------------------------------------------------------------------------

# 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)
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
Example #11
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