Exemple #1
0
    def testFromTuple(self):
        def check(t):
            self.assertEquals(t.name, 'a')
            self.assertEquals(t.version, 'b')
            self.assertEquals(str(t.flavor), 'c')

        t = trovetup.TroveSpec(('a', 'b', 'c'))
        check(t)

        c = deps.parseFlavor('c').freeze()
        t = trovetup.TroveSpec('a', 'b', c, withFrozenFlavor=True)
        check(t)
Exemple #2
0
 def compare(self, spec, asStr, name, version, flavor, **kwargs):
     t = trovetup.TroveSpec(spec, **kwargs)
     r = "TroveSpec('%s')" % asStr
     self.assertEquals(str(t), asStr)
     self.assertEquals(repr(t), r)
     self.assertEquals(t.name, name)
     self.assertEquals(t.version, version)
     self.assertEquals(str(t.flavor), str(flavor))
Exemple #3
0
    def testEmptyName(self):
        t = trovetup.TroveSpec('', version='1.2')
        self.assertEquals(str(t), '=1.2')
        self.assertEquals(t.name, '')
        self.assertEquals(t.version, '1.2')
        self.assertEquals(t.flavor, None)

        self.assertRaises(TroveSpecError,
            trovetup.TroveSpec, '', allowEmptyName=False)
Exemple #4
0
def parseTroveSpec(specStr, allowEmptyName = True, withFrozenFlavor = False):
    """
    Parse a TroveSpec string

    @param specStr: the input string
    @type specStr: string

    @param allowEmptyName: if set, will accept an empty string and some other
    variations.
    @type allowEmptyName: bool

    @param withFrozenFlavor: if set, will accept a frozen flavor
    @type withFrozenFlavor: bool

    @rtype: list
    @return: (name, version, flavor)

    @raise TroveSpecError: Raised if the input string is not a valid TroveSpec
    """
    return trovetup.TroveSpec(specStr,
        allowEmptyName=allowEmptyName, withFrozenFlavor=withFrozenFlavor)
Exemple #5
0
    def __new__(cls, name, version=None, flavor=None, **kwargs):
        if isinstance(name, (tuple, list)):
            name = list(name)
            name[0] = name[0].replace('==', '=')
        else:
            name = name.replace('==', '=')
        name, version, flavor = trovetup.TroveSpec(name, version, flavor,
                                                   **kwargs)

        newTuple = tuple.__new__(cls, (name, version, flavor))
        if newTuple.version:
            newTuple.pinned = '==' in newTuple.version
            newTuple.local = '@local' in newTuple.version
            newTuple._has_branch = '/' in newTuple.version[1:]
        else:
            newTuple.pinned = False
            newTuple._has_branch = False
            newTuple.local = False

        newTuple.snapshot = (not newTuple.pinned and not newTuple.local
                             and newTuple._has_branch)

        return newTuple
Exemple #6
0
def doModelUpdate(cfg, sysmodel, modelFile, otherArgs, **kwargs):
    kwargs['systemModel'] = sysmodel
    kwargs['systemModelFile'] = modelFile
    kwargs['loadTroveCache'] = True
    kwargs.setdefault('updateByDefault', True) # erase is not default case
    kwargs.setdefault('model', False)
    kwargs.setdefault('keepExisting', True) # prefer "install" to "update"
    restartInfo = kwargs.get('restartInfo', None)
    patchArgs = kwargs.pop('patchSpec', None)
    fromChangesets = []
    applyList = []

    callback = kwargs.get('callback', None)
    if not callback:
        callback = callbacks.UpdateCallback(trustThreshold=cfg.trustThreshold)
        kwargs['callback'] = callback
    else:
        callback.setTrustThreshold(cfg.trustThreshold)

    if restartInfo is None:
        addArgs = [x[1:] for x in otherArgs if x.startswith('+')]
        rmArgs = [x[1:] for x in otherArgs if x.startswith('-')]
        defArgs = [x for x in otherArgs
                    if not (x.startswith('+') or x.startswith('-'))]

        # find any default arguments that represent changesets to
        # install/update
        for defArg in list(defArgs):
            if kwargs['updateByDefault'] and os.path.isfile(defArg):
                try:
                    cs = changeset.ChangeSetFromFile(defArg)
                    fromChangesets.append((cs, defArg))
                    defArgs.remove(defArg)
                except filecontainer.BadContainer:
                    # not a changeset, must be a trove name
                    pass

        if kwargs['updateByDefault']:
            addArgs += defArgs
        else:
            rmArgs += defArgs

        if rmArgs:
            sysmodel.appendOpByName('erase', text=rmArgs)

        updateName = { False: 'update',
                       True: 'install' }[kwargs['keepExisting']]

        branchArgs = {}
        for index, spec in enumerate(addArgs):
            try:
                troveSpec = trovetup.TroveSpec(spec)
                version = versions.Label(troveSpec.version)
                branchArgs[troveSpec] = index
            except:
                # Any exception is a parse failure in one of the
                # two steps, and so we do not convert that argument
                pass
       
        if branchArgs:
            client = conaryclient.ConaryClient(cfg)
            repos = client.getRepos()
            foundTroves = repos.findTroves(cfg.installLabelPath,
                                           branchArgs.keys(),
                                           defaultFlavor = cfg.flavor)
            for troveSpec in foundTroves:
                index = branchArgs[troveSpec]
                foundTrove = foundTroves[troveSpec][0]
                addArgs[index] = addArgs[index].replace(
                    troveSpec.version,
                    '%s/%s' %(foundTrove[1].trailingLabel(),
                              foundTrove[1].trailingRevision()))

        disallowedChangesets = []
        for cs, argName in fromChangesets:
            for troveTuple in cs.getPrimaryTroveList():
                # group and redirect changesets will break the model the
                # next time it is run, so prevent them from getting in
                # the model in the first place
                if troveTuple[1].isOnLocalHost():
                    if troveTuple[0].startswith('group-'):
                        disallowedChangesets.append((argName, 'group',
                            trovetup.TroveTuple(*troveTuple).asString()))
                        continue
                    trvCs = cs.getNewTroveVersion(*troveTuple)
                    if trvCs.getType() == trove.TROVE_TYPE_REDIRECT:
                        disallowedChangesets.append((argName, 'redirect',
                            trovetup.TroveTuple(*troveTuple).asString()))
                        continue

                addArgs.append(
                    trovetup.TroveTuple(*troveTuple).asString())

        if disallowedChangesets:
            raise errors.ConaryError(
                'group and redirect changesets on a local label'
                ' cannot be installed:\n    ' + '\n    '.join(
                    '%s contains local %s: %s' % x
                    for x in disallowedChangesets))

        if addArgs:
            sysmodel.appendOpByName(updateName, text=addArgs)

        if patchArgs:
            sysmodel.appendOpByName('patch', text=patchArgs)


        kwargs['fromChangesets'] = [x[0] for x in fromChangesets]

        if kwargs.pop('model'):
            sysmodel.write(sys.stdout)
            sys.stdout.flush()
            return None

        keepExisting = kwargs.get('keepExisting')
        updateByDefault = kwargs.get('updateByDefault', True)
        applyList = cmdline.parseChangeList([], keepExisting,
                                            updateByDefault,
                                            allowChangeSets=True)

    else:
        # In the restart case, applyList == [] which says "sync to model"
        pass
        
    _updateTroves(cfg, applyList, **kwargs)
    # Clean up after ourselves
    if restartInfo:
        util.rmtree(restartInfo, ignore_errors=True)
Exemple #7
0
    def createBuildJobForStage(self,
                               itemList,
                               recurse=True,
                               rebuild=True,
                               useLocal=False,
                               progress=True):
        """
        @param itemList: list of troveSpec style items to build or
            paths to recipes.  May include version (after =) flavor
            (in []) or context (in {}) for each item.
        @type  itemList: list of strings
        @param recurse: if C{True} (the default), build all child
            packages included in groups.
        @param rebuild: if C{True} (the default), rmake will reuse
            packages that do not need to be rebuilt.
        @param useLocal: if C{True}, built packages on the stage label
            will be inserted into resolveTroves
        @param progress: if C{True} (the default), print a progress
            indication at the start of the operation
        @return: The new build job object
        """
        rmakeClient = self._getRmakeHelperWithContexts()[0]
        handle = self._handle

        if progress:
            handle.ui.progress('Creating rMake build job for %d items' %
                               len(itemList))

        stageLabel = handle.productStore.getActiveStageLabel()
        if recurse:
            recurse = rmakeClient.BUILD_RECURSE_GROUPS_SOURCE

        # When building groups, use the same flavor and buildFlavor (RBLD-350).
        hasGroups = bool(
            [x for x in itemList if os.path.basename(x).startswith('group-')])
        cfg = self._getRmakeConfigWithContexts(hasGroups=hasGroups)[0]

        if useLocal:
            # Insert troves from the build label into resolveTroves
            # to emulate a recursive job's affinity for built troves.
            conary = handle.facade.conary
            initialTroves = conary.getLatestPackagesOnLabel(stageLabel)
            cfg.resolveTroves.insert(0, initialTroves)

        job = rmakeClient.createBuildJob(itemList,
                                         rebuild=rebuild,
                                         recurseGroups=recurse,
                                         limitToLabels=[stageLabel],
                                         buildConfig=cfg)

        # Populate the group's productDefinitionSearchPath macro by
        # finding them first in the lookups rMake did for
        # resolveTroveTups, then with findTroves.
        searchPathTups = [
            x.getTroveTup() for x in handle.product.getGroupSearchPaths()
        ]

        # Iterate over each config that belongs to at least one trove
        # (generally one per context)
        troveConfigs = dict((id(x.cfg), x.cfg) for x in job.iterTroves())
        for troveCfg in troveConfigs.itervalues():
            # Figure out which troves we need to look up by filtering
            # out the ones rMake already looked up for us.
            alreadyFoundMap = dict(
                (troveSpec, troveTup)
                for (troveSpec, troveTup) in itertools.izip(
                    itertools.chain(*troveCfg.resolveTroves),
                    itertools.chain(*troveCfg.resolveTroveTups)))
            toFind = [x for x in searchPathTups if x not in alreadyFoundMap]

            # Look up the remaining ones using the config's flavor.
            results = handle.facade.conary._findTroves(
                toFind,
                troveCfg.installLabelPath,
                troveCfg.flavor,
                allowMissing=True)

            groupSearchPath = []
            for troveSpec in searchPathTups:
                if troveSpec in alreadyFoundMap:
                    troveTup = alreadyFoundMap[troveSpec]
                elif troveSpec in results:
                    troveTup = max(results[troveSpec])
                else:
                    raise errors.MissingGroupSearchPathElementError(*troveSpec)
                groupSearchPath.append('%s=%s' % troveTup[:2])

            troveCfg.macros['productDefinitionSearchPath'] = '\n'.join(
                groupSearchPath)
            proddefVersion = handle.product.getLoadedTrove()
            if proddefVersion is not None:
                proddefVersion = trovetup.TroveSpec(proddefVersion).version
                troveCfg.macros['productDefinitionVersion'] = proddefVersion

            platformInformation = handle.product.getPlatformInformation()
            if (platformInformation
                    and hasattr(platformInformation, 'platformClassifier')
                    and platformInformation.platformClassifier and 'windows'
                    in platformInformation.platformClassifier.get_tags()):
                troveCfg.macros['targetos'] = 'windows'

        return job