def getTargetArch(flavor, currentArch = None): if currentArch is None: currentArch = Flavor() currentArch.addDep(deps.InstructionSetDependency, arch.currentArch[0][0]) setArch = False currentArchName = [ x.name for x in currentArch.iterDepsByClass(deps.InstructionSetDependency) ] assert(len(currentArchName) == 1) currentArchName = currentArchName[0] archNames = [ x.name for x in flavor.iterDepsByClass(deps.InstructionSetDependency) ] if len(archNames) > 1: raise RuntimeError, 'Cannot build trove with two architectures' if not archNames: return False, None targetArch = archNames[0] if targetArch != currentArchName: if targetArch in setArchOk.get(currentArchName, []): setArch = True return setArch, targetArch else: return False, None
def getTargetArch(flavor, currentArch=None): if currentArch is None: currentArch = Flavor() currentArch.addDep(deps.InstructionSetDependency, arch.currentArch[0][0]) setArch = False currentArchName = [ x.name for x in currentArch.iterDepsByClass(deps.InstructionSetDependency) ] assert (len(currentArchName) == 1) currentArchName = currentArchName[0] archNames = [ x.name for x in flavor.iterDepsByClass(deps.InstructionSetDependency) ] if len(archNames) > 1: raise RuntimeError, 'Cannot build trove with two architectures' if not archNames: return False, None targetArch = archNames[0] if targetArch != currentArchName: if targetArch in setArchOk.get(currentArchName, []): setArch = True return setArch, targetArch else: return False, None
def testUnknownFlavor(self): # Adding a flavor that is unknown to the current version of the # code intTag = 65535 stringTag = "yet-to-be-defined" class YetToBeDefinedFlavor(DependencyClass): tag = intTag tagName = stringTag justOne = False depClass = Dependency flv = Flavor() flvName = "was" flvFlag = "flag1" flv.addDep(YetToBeDefinedFlavor, Dependency(flvName, [ (flvFlag, FLAG_SENSE_REQUIRED) ])) frozen = flv.freeze() x = ThawFlavor(frozen) # The code that implements str is very specific to what's currently # implemented self.assertEqual(str(x), '') # However, it's not the empty flavor self.assertNotEqual(x, parseFlavor('')) self.assertEqual(x.freeze(), '65535#was:flag1')
def getCrossCompile(flavor): flavorTargetSet = flavor.getDepClasses().get(deps.DEP_CLASS_TARGET_IS, None) if flavorTargetSet is None: return None targetFlavor = Flavor() for insSet in flavorTargetSet.getDeps(): targetFlavor.addDep(deps.InstructionSetDependency, insSet) isCrossTool = flavor.stronglySatisfies(crossFlavor) return None, targetFlavor, isCrossTool
def getArchFlags(flavor, getTarget=True, withFlags=True): archFlavor = Flavor() flavorInsSet = flavor.getDepClasses().get(deps.DEP_CLASS_IS, None) if flavorInsSet is not None: for insSet in flavorInsSet.getDeps(): if not withFlags: insSet = deps.Dependency(insSet.name) archFlavor.addDep(deps.InstructionSetDependency, insSet) if not getTarget: return archFlavor flavorInsSet = flavor.getDepClasses().get(deps.DEP_CLASS_TARGET_IS, None) if flavorInsSet is not None: for insSet in flavorInsSet.getDeps(): if not withFlags: insSet = deps.Dependency(insSet.name) archFlavor.addDep(deps.TargetInstructionSetDependency, insSet) return archFlavor
def testFlavorDisplayed(self): repos = self.openRepository() db = self.openDatabase() foobar = Flavor('~foo,~bar') nofoobar = Flavor('~!foo,~!bar') v1 = VFS('/localhost@rpl:devel/1.0-1-1') dcfg = display.DisplayConfig(repos, db) dcfg.setTroveDisplay(baseFlavors=[Flavor('~foo')]) formatter = display.TroveTupFormatter(dcfg) formatter.prepareTuples([('foo', v1, foobar), ('foo', v1, nofoobar)]) vStr, flv = formatter.getTupleStrings('foo', v1, foobar) assert (str(flv) == '~bar,~foo') vStr, flv = formatter.getTupleStrings('foo', v1, nofoobar) assert (str(flv) == '~!bar,~!foo')
def getDownstreamNameVersionFlavor(self): ''' Return a tuple similar to C{x.getName(), x.getDownstreamVersion(), deps.Flavor()}. Note that the flavor is empty as this is referring only to the source trove, not to any built object. ''' if not self.downstreamVersion: raise ValueError('Downstream version not yet allocated') return self.name, self.downstreamVersion, Flavor()
def testFindTroves(self): _, facade = self.prep() repos = MockRepositoryClient() mock.mockMethod(facade._getRepositoryClient, repos) results = facade._findTroves([('foo', None, None)], ['localhost@rpl:1', 'localhost@rpl:2']) assert (results == { ('foo', None, None): [('foo', VFS('/localhost@rpl:1/1.0-1-1'), Flavor(''))] }) results = facade._findTrovesFlattened( [('foo', None, None)], ['localhost@rpl:1', 'localhost@rpl:2']) assert (results == [('foo', VFS('/localhost@rpl:1/1.0-1-1'), Flavor(''))]) results = facade._findTroves(['foo[ssl]'], 'localhost@rpl:1') assert (results == { ('foo[ssl]'): [('foo', VFS('/localhost@rpl:1/1.0-1-1'), Flavor('ssl'))] }) results = facade._findTrovesFlattened(['foo[ssl]'], 'localhost@rpl:1') assert (results == [('foo', VFS('/localhost@rpl:1/1.0-1-1'), Flavor('ssl'))])
def getRecipes(repos, troveTups): fileIds = [] troveSpecs = [(x[0], x[1], Flavor()) for x in troveTups] troves = repos.getTroves(troveSpecs) for i, trove in enumerate(troves): filename = trove.getName().split(':')[0] + '.recipe' found = False for (pathId, filePath, fileId, fileVersion) in trove.iterFileList(): if filePath == filename: fileIds.append((fileId, fileVersion)) found = True break repos.getFileContents(fileIds) #caches files return troves
def testJobTupFormatter(self): # CNY-1742 repos = self.openRepository() db = self.openDatabase() dcfg = display.JobDisplayConfig(repos, db) formatter = display.JobTupFormatter(dcfg) v1 = VFS('/localhost@rpl:devel/1.0-1-1') v2 = VFS('/localhost@rpl:devel/1.0-1-2') f = Flavor('') jobs = [('foo', (None, None), (v1, f), False), ('foo', (None, None), (v2, f), False)] formatter.prepareJobs(jobs) result = ''.join(x for x in formatter.formatJobTups(jobs)) self.assertEqual(result, 'Install foo=1.0-1-1Install foo=1.0-1-2') formatter = display.JobFormatter(dcfg) (rc, txt) = self.captureOutput(display.displayJobs, dcfg, formatter, jobs) self.assertEqual(txt, 'Install foo=1.0-1-1\nInstall foo=1.0-1-2\n')
def commitJobs(conaryclient, jobList, reposName, message=None, commitOutdatedSources=False, sourceOnly=False, excludeSpecs=None, writeToFile=None): jobsToCommit = {} alreadyCommitted = [] finalCs = changeset.ReadOnlyChangeSet() mapping = {} for job in jobList: if job.isCommitted(): alreadyCommitted.append(job) else: jobsToCommit[job.jobId] = job jobsToCommit = jobsToCommit.values() # dedup job list if not jobsToCommit: err = 'Job(s) already committed' return False, err allTroves = [] trovesByBranch = {} alreadyCommitted = False for job in jobsToCommit: mapping[job.jobId] = {} for trove in job.iterTroves(): allTroves.append(trove) troveVersion = trove.getVersion() if troveVersion.getHost() == reposName: if not troveVersion.branch().hasParentBranch(): message = ('Cannot commit filesystem cook %s - ' ' nowhere to commit to!' % trove.getName()) return False, message assert (allTroves) source = trovesource.SimpleTroveSource() if excludeSpecs: excludeSpecsWithContext = {} troveMap = {} for excludeSpec in excludeSpecs: if len(excludeSpec) == 4: context = excludeSpec[3] else: context = None excludeSpecsWithContext.setdefault(excludeSpec[:3], []).append(context) excludeSpecs = [x[:3] for x in excludeSpecs] for trove in allTroves: troveTup = (trove.getName().split(':')[0], trove.getVersion(), trove.getFlavor()) source.addTrove(*troveTup) troveMap.setdefault(troveTup, []).append(trove) source.searchAsDatabase() matches = source.findTroves(None, excludeSpecs, None, allowMissing=True) trvMatches = [] for excludeSpec, matchList in matches.iteritems(): contexts = excludeSpecsWithContext[excludeSpec] for match in matchList: for trv in troveMap[match]: if trv.context in contexts or None in contexts: trvMatches.append(trv) allTroves = [x for x in allTroves if x not in trvMatches] if not allTroves: message = ('All troves excluded - not committing') return False, message repos = conaryclient.getRepos() trovesByNBF = {} sourcesToCheck = [] branchMap = {} trovesToClone = [] for trove in allTroves: builtTroves = list(trove.iterBuiltTroves()) if not builtTroves: continue if builtTroves[0][1].getHost() != reposName: alreadyCommitted = True for n, v, f in builtTroves: trovesByNBF[n, v.branch(), f] = (trove, v) continue troveVersion = trove.getVersion() if troveVersion.getHost() == reposName: sourceTup = (trove.getName(), troveVersion, Flavor()) targetBranch = troveVersion.branch().parentBranch() branchMap[troveVersion.branch()] = targetBranch nbf = trove.getName(), targetBranch, Flavor() if nbf in trovesByNBF: if trovesByNBF[nbf][1] != troveVersion: badVersion = trovesByNBF[nbf][1] return False, ( "Cannot commit two different versions of source component %s:" " %s and %s" % (trove.getName(), troveVersion, badVersion)) trovesByNBF[nbf] = trove, troveVersion sourcesToCheck.append(sourceTup) if sourceOnly: continue for troveTup in builtTroves: branch = troveTup[1].branch() targetBranch = branch.parentBranch() # add mapping so that when the cloning is done # we can tell what commit resulted in what binaries. nbf = (troveTup[0], targetBranch, troveTup[2]) if nbf in trovesByNBF: otherBinary = trovesByNBF[nbf][0].getBinaryTroves()[0] if otherBinary[1].branch() == targetBranch: # this one's already committed. break # discard the later of the two commits. if trovesByNBF[nbf][0].getVersion() > trove.getVersion(): # we're the earlier one badTrove, badVersion = trovesByNBF[nbf] newTrove = trove newVersion = troveTup[1] else: badTrove = trove badVersion = troveTup[1] newTrove, newVersion = trovesByNBF[nbf] name = nbf[0] flavor = nbf[2] skipped = [] for badTroveTup in badTrove.iterBuiltTroves(): badNbf = (badTroveTup[0], targetBranch, badTroveTup[2]) if not ':' in badTroveTup[0]: skipped.append(badTroveTup[0]) if badNbf in trovesByNBF and badTrove is trovesByNBF[ badNbf][0]: del trovesByNBF[badNbf] skipped = '%s' % (', '.join(skipped)) log.warning("Not committing %s on %s[%s]%s - overridden by" " %s[%s]%s" % (skipped, badTroveTup[1], badTroveTup[2], badTrove.getContextStr(), newVersion, flavor, newTrove.getContextStr())) if trove is badTrove: break trovesByNBF[nbf] = trove, troveTup[1] branchMap[branch] = targetBranch for nbf, (trove, tupVersion) in trovesByNBF.items(): if tupVersion.branch() != nbf[1]: trovesToClone.append((nbf[0], tupVersion, nbf[2])) if not trovesToClone: if sourceOnly: err = 'Could not find sources to commit' elif alreadyCommitted: log.warning('All built troves have already been committed') return True, {} else: err = 'Can only commit built troves, none found' return False, err if sourcesToCheck and not commitOutdatedSources: outdated = _checkOutdatedSources(repos, sourcesToCheck) if outdated: outdated = ( '%s=%s (replaced by newer %s)' \ % (name, builtVer, newVer.trailingRevision()) for (name, builtVer, newVer) in outdated) err = ('The following source troves are out of date:\n%s\n\n' 'Use --commit-outdated-sources to commit anyway' % '\n'.join(outdated)) return False, err # only update build info if we'll be okay if some buildreqs are not # updated updateBuildInfo = compat.ConaryVersion().acceptsPartialBuildReqCloning() callback = callbacks.CloneCallback(conaryclient.cfg, message) passed, cs = conaryclient.createTargetedCloneChangeSet( branchMap, trovesToClone, updateBuildInfo=updateBuildInfo, cloneSources=False, trackClone=False, callback=callback, fullRecurse=False) if passed: oldTroves = [] for troveCs in cs.iterNewTroveList(): if troveCs.getOldVersion(): oldTroves.append(troveCs.getOldNameVersionFlavor()) if oldTroves: oldDict = {} for oldTrove in repos.getTroves(oldTroves): oldDict.setdefault(oldTrove.getNameVersionFlavor(), []).append(oldTrove) for troveCs in cs.iterNewTroveList(): if troveCs.getOldVersion(): trv = oldDict[troveCs.getOldNameVersionFlavor()].pop() trv.applyChangeSet(troveCs) else: trv = Trove(troveCs) for _, childVersion, _ in trv.iterTroveList(strongRefs=True, weakRefs=True): # make sure there are not any references to the internal # rmake repository - that would be a bad bug - easy to # do with the way we do cooking of groups. onRepos = childVersion.getHost() == reposName assert not onRepos, "Trove %s references repository" % trv n, v, f = troveCs.getNewNameVersionFlavor() trove, troveVersion = trovesByNBF[n, v.branch(), f] troveNVFC = trove.getNameVersionFlavor(withContext=True) # map jobId -> trove -> binaries mapping[trove.jobId].setdefault(troveNVFC, []).append((n, v, f)) else: return False, 'Creating clone failed' signatureKey = conaryclient.cfg.signatureKey if signatureKey and compat.ConaryVersion().signAfterPromote(): finalCs = signAbsoluteChangeset(cs, signatureKey) if writeToFile: cs.writeToFile(writeToFile) else: repos.commitChangeSet(cs, callback=callback) return True, mapping