@api.publicApi
    def updateChangeSet(self, itemList, keepExisting = False, recurse = True,
                        resolveDeps = True, test = False,
                        updateByDefault = True, callback=None,
                        split = True, sync = False, fromChangesets = [],
                        checkPathConflicts = True, checkPrimaryPins = True,
                        resolveRepos = True, syncChildren = False,
                        updateOnly = False, resolveGroupList=None,
                        installMissing = False, removeNotByDefault = False,
                        keepRequired = None, migrate = False,
                        criticalUpdateInfo=None, resolveSource = None,
                        updateJob = None, exactFlavors = False):
        """
        DEPRECATED, use L{newUpdateJob} and L{prepareUpdateJob} instead.

        Create an update job.
        """
        # FIXME: this API has gotten far out of hand.  Refactor when
        # non backwards compatible API changes are acceptable.
        # In particular. installMissing and updateOnly have similar meanings,
        # (but expanding updateOnly meaning would require making incompatible
        # changes), keepExisting is also practically meaningless at this level.
        # CNY-492
        if keepRequired is None:
            keepRequired = self.cfg.keepRequired

        # To go away eventually
        if callback:
            import warnings
            warnings.warn("The callback argument to updateChangeSet has been "
                          "deprecated, use setUpdateCallback() instead")
            self.setUpdateCallback(callback)

        if self.updateCallback is None:
            self.setUpdateCallback(UpdateCallback())
        self.updateCallback.preparingChangeSet()

        if criticalUpdateInfo is None:
            criticalUpdateInfo = CriticalUpdateInfo()

        if updateJob:
            uJob = updateJob
        else:
            uJob = database.UpdateJob(self.db)

        hasCriticalUpdateInfo = False
        troveSource = uJob.getTroveSource()
        first = True
        for changeSet, incFConts in criticalUpdateInfo.iterChangeSets():
            if first:
                # Replace the trove source with one that can store
                # dependencies
                troveSource = trovesource.ChangesetFilesTroveSource(self.db,
                                                             storeDeps=True)
                uJob.troveSource = troveSource
                first = False
            troveSource.addChangeSet(changeSet, includesFileContents = incFConts)
            hasCriticalUpdateInfo = True

        forceJobClosure = False

        useAffinity = False
        if fromChangesets:
            # when --from-file is used we need to explicitly compute the
            # transitive closure for our job. we normally trust the
            # repository to give us the right thing, but that won't
            # work when we're pulling jobs out of the change set
            forceJobClosure = True

            csSource = trovesource.ChangesetFilesTroveSource(self.db,
                                                             storeDeps=True)
            csSource.searchAsRepository()
            for cs in fromChangesets:
                self._replaceIncomplete(cs, self.db, self.db, self.repos)
                csSource.addChangeSet(cs, includesFileContents = True)
                # FIXME ChangeSetSource: We shouldn't have to add this to
                # uJob.troveSource() at this point, since the
                # changeset is not part of the job yet.  But given the
                # way changeSetSource.createChangeSet is written
                # (it can't handle recursive changeSet creation, e.g.)
                # we have no choice.  Search FIXME ChangeSetSource for
                # a matching comment
                uJob.getTroveSource().addChangeSet(cs,
                                                   includesFileContents = True)
        mainSearchSource = None
        troveSource = None
        searchSource = None
        if sync:
            troveSource = trovesource.ReferencedTrovesSource(self.db)
        elif syncChildren:
            troveSource = self.db
        elif fromChangesets:
            troveSource = trovesource.stack(csSource, self.repos)
            mainSearchSource = self.getSearchSource(troveSource=troveSource)
            searchSource = mainSearchSource
        elif hasCriticalUpdateInfo:
            # Use the trove source as a search source too
            searchSource = uJob.getTroveSource()
        else:
            mainSearchSource = self.getSearchSource()
            searchSource = mainSearchSource
            uJob.setSearchSource(mainSearchSource)
            useAffinity = True

        if not searchSource and troveSource:
            searchSource = searchsource.SearchSource(troveSource,
                                                     self.cfg.flavor)
        uJob.setSearchSource(searchSource)

        if resolveGroupList:
            if not mainSearchSource:
                mainSearchSource = self.getSearchSource()
            result = mainSearchSource.findTroves(resolveGroupList,
                                                 useAffinity=useAffinity,
                                                 exactFlavors=exactFlavors)
            groupTups = list(itertools.chain(*result.itervalues()))
            groupTroves = self.repos.getTroves(groupTups, withFiles=False)
            resolveSource = resolve.DepResolutionByTroveList(self.cfg, self.db,
                                                             groupTroves)
        if resolveSource:
            resolveRepos = False

        if migrate:
            jobSet = self._fullMigrate(itemList, uJob, recurse=recurse)
        else:
            jobSet = self._updateChangeSet(itemList, uJob,
                                       keepExisting = keepExisting,
                                       recurse = recurse,
                                       updateMode = updateByDefault,
                                       useAffinity = useAffinity,
                                       checkPrimaryPins = checkPrimaryPins,
                                       forceJobClosure = forceJobClosure,
                                       syncChildren = syncChildren,
                                       updateOnly = updateOnly,
                                       installMissing = installMissing,
                                       removeNotByDefault = removeNotByDefault,
                                       exactFlavors = exactFlavors)

        self._validateJob(jobSet)

        # When keep existing is provided none of the changesets should
        # be relative (since relative change sets, by definition, cause
        # something on the system to get replaced).
        if keepExisting:
            for job in jobSet:
                if job[1][0] is not None:
                    raise UpdateError, 'keepExisting specified for a ' \
                                       'relative change set'

        self.updateCallback.resolvingDependencies()

        # this updates jobSet w/ resolutions, and splitJob reflects the
        # jobs in the updated jobSet
        if resolveDeps or split:
            (depList, suggMap, cannotResolve, splitJob, keepList,
             criticalUpdates) = \
            self._resolveDependencies(uJob, jobSet, split = split,
                                      resolveDeps = resolveDeps,
                                      useRepos = resolveRepos,
                                      resolveSource = resolveSource,
                                      keepRequired = keepRequired,
                                      criticalUpdateInfo = criticalUpdateInfo)

            # if any of the things we're about to install or remove use
            # capsules we cannot split the job
            if not split:
                splitJob = [ list(jobSet) ]
                criticalUpdates = []
        else:
            (depList, suggMap, cannotResolve, splitJob, keepList,
             criticalUpdates) = ( [], {}, [], [ list(jobSet) ], [], [] )

        if keepList:
            self.updateCallback.done()
            for job, depSet, reqInfo in sorted(keepList):
                self.updateCallback.warning('keeping %s - required by at least %s',
                            job[0], reqInfo[0])

        if depList:
            raise DepResolutionFailure(self.cfg, depList, suggMap,
                                       cannotResolve, splitJob, criticalUpdates)
        elif suggMap and not self.cfg.autoResolve:
            raise NeededTrovesFailure(self.cfg, depList, suggMap,
                                      cannotResolve, splitJob, criticalUpdates)
        elif cannotResolve:
            raise EraseDepFailure(self.cfg, depList, suggMap,
                                  cannotResolve, splitJob, criticalUpdates)

        # look for troves which look like they'll conflict (same name/branch
        # and incompatible install paths)
        if not sync and checkPathConflicts:
            d = {}
            conflicts = {}
            for job in jobSet:
                if not job[2][0]: continue
                name, branch = job[0], job[2][0].branch()
                l = d.setdefault((name, branch), [])
                l.append(job)

            for jobList in d.values():
                if len(jobList) < 2: continue
                trvs = uJob.getTroveSource().getTroves(
                        [ (x[0], x[2][0], x[2][1]) for x in jobList ],
                        withFiles = False)
                paths = [ x.getPathHashes() for x in trvs ]

                for i, job in enumerate(jobList):
                    for j in range(i):
                        # RPM capsules can overlap; there is special handling
                        # for that
                        if (trvs[i].troveInfo.capsule.type() ==
                                trove._TROVECAPSULE_TYPE_RPM and
                            trvs[j].troveInfo.capsule.type() ==
                                trove._TROVECAPSULE_TYPE_RPM):
                            continue

                        if not paths[i].compatibleWith(paths[j]):
                            l = conflicts.setdefault(job[0], [])
                            l.append((job[2], jobList[j][2]))

            if conflicts:
                raise InstallPathConflicts(conflicts)

        if criticalUpdates:
            criticalJobs = [ splitJob[x] for x in criticalUpdates ]
        else:
            criticalJobs = []

        if split:
            self._combineJobs(uJob, splitJob, criticalJobs)
        else:
            # order must not matter since split was False
            uJob.addJob(list(jobSet))

        uJob.reorderPreScripts(criticalUpdateInfo)

        uJob.setTransactionCounter(self.db.getTransactionCounter())

        # Save some misc information that could be useful to recreate the
        # update job

        kwargs = dict(
            keepExisting = keepExisting,
            recurse = recurse,
            resolveDeps = resolveDeps,
            test = test,
            updateByDefault = updateByDefault,
            split = split,
            sync = sync,
            checkPathConflicts = checkPathConflicts,
            checkPrimaryPins = checkPrimaryPins,
            resolveRepos = resolveRepos,
            syncChildren = syncChildren,
            updateOnly = updateOnly,
            resolveGroupList = resolveGroupList,
            installMissing = installMissing,
            removeNotByDefault = removeNotByDefault,
            keepRequired = keepRequired,
            migrate = migrate,
            exactFlavors = False)
        # Make sure we store them as booleans
        kwargs = dict( (k, bool(v)) for k, v in kwargs.iteritems())
        if not uJob.getRestartedFlag():
            # If we were already a restart, don't bother to change the keyword
            # arguments, they should be the same as for the original set
            uJob.setKeywordArguments(kwargs)

        uJob.setItemList(itemList)
        uJob.setFromChangesets(fromChangesets)

        return (uJob, suggMap)
dataset/ETHPy150Open sassoftware/conary/conary/conaryclient/update.py/ClientUpdate.updateChangeSet/original