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)
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))
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)
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)
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
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)
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