---
 cli.py          |  275 ++++++++++++++++++++++++++++++++---------------
 output.py       |   61 ++++++++++-
 yum/__init__.py |  321 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 547 insertions(+), 110 deletions(-)

diff --git a/cli.py b/cli.py
index 91c2553..8f8fdf9 100755
--- a/cli.py
+++ b/cli.py
@@ -1596,56 +1596,125 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
             1 = we've errored, exit with error string
             2 = we've got work yet to do, onto the next stage        
         """
-        uservisible=1
+        return self._returnGroupLists(userlist)
+
+    def _returnGroupLists(self, userlist, summary=False):
+        # What data are we showing...
+        wts_map = {'hidden' : 'hidden',
+                   'language' : 'lang',
+                   'languages' : 'lang',
+                   'lang' : 'lang',
+                   'langs' : 'lang',
+                   'environment' : 'env',
+                   'environments' : 'env',
+                   'env' : 'env',
+                   'envs' : 'env',
+                   'package' : 'pkg',
+                   'packages' : 'pkg',
+                   'pkg' : 'pkg',
+                   'pkgs' : 'pkg',
+                   'available' : 'avail',
+                   'avail' : 'avail',
+                   'installed' : 'inst',
+                   'inst' : 'inst',
+                   'id' : 'id',
+                   'ids' : 'id',
+                   }
+        verb = self.verbose_logger.isEnabledFor(yum.logginglevels.DEBUG_3)
+        wts = {'hidden' : False,
+               'lang'   : False,
+               'env'    : True,
+               'pkg'    : True,
+               'inst'   : True,
+               'avail'  : True,
+               'id'     : verb}
             
-        if len(userlist) > 0:
-            if userlist[0] == 'hidden':
-                uservisible=0
-                userlist.pop(0)
+        while userlist:
+            arg = userlist[0]
+            val = True
+            if arg.startswith('no'):
+                arg = arg[2:]
+                val = False
+            if arg not in wts_map:
+                break
+            wts[wts_map[arg]] = val
+            userlist.pop(0)
         if not userlist:
             userlist = None # Match everything...
 
-        installed, available = self.doGroupLists(uservisible=uservisible,
-                                                 patterns=userlist)
+        uv  = not wts['hidden']
+        dGL = self.doGroupLists(patterns=userlist,
+                                uservisible=uv, return_evgrps=True)
+
+        installed, available, ievgrps, evgrps = dGL
+
+        if not wts['env']:
+            ievgrps = []
+            evgrps  = []
+
+        if not wts['inst']:
+            installed = []
+            ievgrps   = []
+        if not wts['avail']:
+            available = []
+            evgrps    = []
         
-        if not installed and not available:
-            self.logger.error(_('Warning: No groups match: %s'),
-                              ", ".join(userlist))
-            return 0, []
+        done = []
+        def _out_grp(sect, groups):
+            if not groups:
+                return
+
+            done.append(sect)
+            if summary:
+                self.verbose_logger.log(yum.logginglevels.INFO_2,
+                                        "%s %u", sect, len(groups))
+                return
 
-        def _out_grp(sect, group):
-            if not done:
-                self.verbose_logger.log(yum.logginglevels.INFO_2, sect)
-            msg = '   %s' % group.ui_name
-            if self.verbose_logger.isEnabledFor(yum.logginglevels.DEBUG_3):
-                msg += ' (%s)' % group.groupid
-            if group.langonly:
-                msg += ' [%s]' % group.langonly
-            self.verbose_logger.info('%s', msg)
+            self.verbose_logger.log(yum.logginglevels.INFO_2, sect)
 
-        done = False
+            for group in groups:
+                msg = '   %s' % group.ui_name
+                if wts['id']:
+                    msg += ' (%s)' % group.compsid
+                if group.langonly:
+                    msg += ' [%s]' % group.langonly
+                self.verbose_logger.info('%s', msg)
+
+        _out_grp(_('Installed Environment Groups:'), ievgrps)
+        _out_grp(_('Available Environment Groups:'), evgrps)
+
+        groups = []
         for group in installed:
             if group.langonly: continue
-            _out_grp(_('Installed Groups:'), group)
-            done = True
+            if not wts['pkg']: continue
+            groups.append(group)
+        _out_grp(_('Installed Groups:'), groups)
 
-        done = False
+        groups = []
         for group in installed:
             if not group.langonly: continue
-            _out_grp(_('Installed Language Groups:'), group)
-            done = True
+            if not wts['lang']: continue
+            groups.append(group)
+        _out_grp(_('Installed Language Groups:'), groups)
 
-        done = False
+        groups = []
         for group in available:
             if group.langonly: continue
-            _out_grp(_('Available Groups:'), group)
-            done = True
+            if not wts['pkg']: continue
+            groups.append(group)
+        _out_grp(_('Available Groups:'), groups)
 
-        done = False
+        groups = []
         for group in available:
             if not group.langonly: continue
-            _out_grp(_('Available Language Groups:'), group)
-            done = True
+            if not wts['lang']: continue
+            groups.append(group)
+        _out_grp(_('Available Language Groups:'), groups)
+
+        if not done:
+            self.logger.error(_('Warning: No Environments/Groups match: %s'),
+                              ", ".join(userlist))
+            return 0, []
 
         return 0, [_('Done')]
 
@@ -1664,47 +1733,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
             1 = we've errored, exit with error string
             2 = we've got work yet to do, onto the next stage
         """
-        uservisible=1
-            
-        if len(userlist) > 0:
-            if userlist[0] == 'hidden':
-                uservisible=0
-                userlist.pop(0)
-        if not userlist:
-            userlist = None # Match everything...
-
-        installed, available = self.doGroupLists(uservisible=uservisible,
-                                                 patterns=userlist)
-        
-        def _out_grp(sect, num):
-            if not num:
-                return
-            self.verbose_logger.log(yum.logginglevels.INFO_2, '%s %u', 
sect,num)
-        done = 0
-        for group in installed:
-            if group.langonly: continue
-            done += 1
-        _out_grp(_('Installed Groups:'), done)
-
-        done = 0
-        for group in installed:
-            if not group.langonly: continue
-            done += 1
-        _out_grp(_('Installed Language Groups:'), done)
-
-        done = False
-        for group in available:
-            if group.langonly: continue
-            done += 1
-        _out_grp(_('Available Groups:'), done)
-
-        done = False
-        for group in available:
-            if not group.langonly: continue
-            done += 1
-        _out_grp(_('Available Language Groups:'), done)
-
-        return 0, [_('Done')]
+        return self._returnGroupLists(userlist, summary=True)
     
     def returnGroupInfo(self, userlist):
         """Print complete information about the groups that match the
@@ -1722,12 +1751,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         """
         for strng in userlist:
             group_matched = False
-            for group in self.comps.return_groups(strng):
-                self.displayPkgsInGroups(group)
-                group_matched = True
+
+            pkg_grp = True
+            grp_grp = True
+            if strng.startswith('@^'):
+                strng = strng[2:]
+                pkg_grp = False
+            elif strng.startswith('@'):
+                strng = strng[1:]
+                grp_grp = False
+
+            if grp_grp:
+                for evgroup in self.comps.return_environments(strng):
+                    self.displayGrpsInEnvironments(evgroup)
+                    group_matched = True
+            if pkg_grp:
+                for group in self.comps.return_groups(strng):
+                    self.displayPkgsInGroups(group)
+                    group_matched = True
 
             if not group_matched:
-                self.logger.error(_('Warning: Group %s does not exist.'), 
strng)
+                self.logger.error(_('Warning: Group/Environment %s does not 
exist.'), strng)
         
         return 0, []
         
@@ -1747,10 +1791,37 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         pkgs_used = []
         
         for group_string in grouplist:
+
+            grp_grp = True
+            pkg_grp = True
+            if group_string.startswith('@^'):
+                pkg_grp = False
+                group_string = group_string[2:]
+            elif group_string.startswith('@'):
+                grp_grp = False
+                group_string = group_string[1:]
+
             group_matched = False
-            for group in self.comps.return_groups(group_string):
+            groups = []
+            if grp_grp:
+                groups = self.comps.return_environments(group_string)
+            for group in groups:
                 group_matched = True
 
+                try:
+                    txmbrs = self.selectEnvironment(group.environmentid,
+                                                    upgrade=upgrade)
+                except yum.Errors.GroupsError:
+                    self.logger.critical(_('Warning: Environment %s does not 
exist.'), group_string)
+                    continue
+                else:
+                    pkgs_used.extend(txmbrs)
+
+            groups = []
+            if pkg_grp:
+                groups = self.comps.return_groups(group_string)
+            for group in groups:
+                group_matched = True
             
                 try:
                     txmbrs = self.selectGroup(group.groupid, upgrade=upgrade)
@@ -1784,13 +1855,47 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         """
         pkgs_used = []
         for group_string in grouplist:
-            try:
-                txmbrs = self.groupRemove(group_string)
-            except yum.Errors.GroupsError:
-                self.logger.critical(_('No group named %s exists'), 
group_string)
-                continue
-            else:
-                pkgs_used.extend(txmbrs)
+
+            grp_grp = True
+            pkg_grp = True
+            if group_string.startswith('@^'):
+                pkg_grp = False
+                group_string = group_string[2:]
+            elif group_string.startswith('@'):
+                grp_grp = False
+                group_string = group_string[1:]
+
+            groups = []
+            if grp_grp:
+                if self.conf.group_command == 'objects':
+                    groups = self.igroups.return_environments(group_string)
+                else:
+                    groups = self.comps.return_environments(group_string)
+                if not groups:
+                    self.logger.critical(_('No Environment named %s exists'), 
group_string)
+            for group in groups:
+                try:
+                    txmbrs = self.environmentRemove(group.environmentid)
+                except yum.Errors.GroupsError:
+                    continue
+                else:
+                    pkgs_used.extend(txmbrs)
+
+            groups = []
+            if pkg_grp:
+                if self.conf.group_command == 'objects':
+                    groups = self.igroups.return_groups(group_string)
+                else:
+                    groups = self.comps.return_groups(group_string)
+                if not groups:
+                    self.logger.critical(_('No group named %s exists'), 
group_string)
+            for group in groups:
+                try:
+                    txmbrs = self.groupRemove(group.groupid)
+                except yum.Errors.GroupsError:
+                    continue
+                else:
+                    pkgs_used.extend(txmbrs)
                 
         if not pkgs_used:
             return 0, [_('No packages to remove from groups')]
diff --git a/output.py b/output.py
index b3f2c75..d29eba8 100755
--- a/output.py
+++ b/output.py
@@ -1092,8 +1092,8 @@ class YumOutput:
         print _('\nGroup: %s') % group.ui_name
 
         verb = self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
-        if verb:
-            print _(' Group-Id: %s') % to_unicode(group.groupid)
+        if True:
+            print _(' Group-Id: %s') % to_unicode(group.compsid)
 
         igroup_data = self._groupInstalledData(group)
         igrp_only   = set()
@@ -1144,6 +1144,63 @@ class YumOutput:
                                        columns=columns,
                                        igroup_data=igroup_data)
 
+    def displayGrpsInEnvironments(self, evgroup):
+        """Output information about the groups in a given evgroup
+
+        :param group: an Environment object to output information about
+        """
+        print _('\nEnvironment Group: %s') % evgroup.ui_name
+        print _(' Environment-Id: %s') % to_unicode(evgroup.compsid)
+
+        igroup_data = self._groupInstalledEnvData(evgroup)
+        igrp_only   = set()
+        for grp_name in igroup_data:
+            if igroup_data[grp_name] == 'installed':
+                igrp_only.add(grp_name)
+        igrp_only.difference_update(evgroup.allgroups)
+        all_grps = evgroup.allgroups + list(igrp_only)
+
+        if evgroup.ui_description:
+            print _(' Description: %s') % to_unicode(evgroup.ui_description)
+
+        def _get_igrp_data(item, indent):
+            if not igroup_data:
+                return indent
+
+            assert item in igroup_data
+            if item not in igroup_data or igroup_data[item] == 'available':
+                indent += '+' # Group up/in will install i
+            elif igroup_data[item] == 'installed':
+                indent += '=' # Installed via. group
+            elif igroup_data[item] == 'blacklisted-installed':
+                if False: # Not sure it's worth listing these...
+                    return None # On the other hand, there's mark-packages
+                indent += ' ' # Installed, not via. group
+            else:
+                assert igroup_data[item] == 'blacklisted-available'
+                if False: # Not sure it's worth listing these...
+                    return None
+                indent += '-' # Not installed, and won't be
+            return indent
+
+        sections = ((_(' Mandatory Groups:'), evgroup.groups),
+                    (_(' Optional Groups:'),  evgroup.options))
+
+        for (section_name, grp_names) in sections:
+            if len(grp_names) > 0:
+                print section_name
+                for grp_name in sorted(grp_names):
+                    pindent = _get_igrp_data(grp_name, "   ")
+                    if pindent is None:
+                        continue
+
+                    print "%s%s" % (pindent, grp_name)
+
+        if igrp_only:
+            print _(' Installed Groups:')
+            for grp_name in sorted(igrp_only):
+                print "%s%s", "  ", grp_name
+
     def depListOutput(self, results):
         """Format and output a list of findDeps results
 
diff --git a/yum/__init__.py b/yum/__init__.py
index 6ec5b15..c713cff 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3228,25 +3228,81 @@ much more problems).
 
         return ret
 
+    def _groupInstalledEnvData(self, evgroup):
+        """ Return a dict of
+             grp_name =>
+             (installed, available,
+             backlisted-installed, blacklisted-available). """
+        ret = {}
+        if not evgroup or self.conf.group_command != 'objects':
+            return ret
+
+        grp_names = {}
+        if evgroup.environmentid in self.igroups.groups:
+            grp_names = self.igroups.environments[evgroup.environmentid]
+            grp_names = grp_names.grp_names
+
+        for grp_name in set(evgroup.allgroups + list(grp_names)):
+            igrp = self.igroups.groups.get(grp_name)
+            if grp_name not in grp_names and not igrp:
+                ret[grp_name] = 'available'
+                continue
+
+            if not igrp:
+                ret[grp_name] = 'blacklisted-available'
+                continue
+
+            if igrp.environment == evgroup.environmentid:
+                ret[grp_name] = 'installed'
+                break
+            else:
+                ret[grp_name] = 'blacklisted-installed'
+
+        return ret
+
     def _groupReturnGroups(self, patterns=None, ignore_case=True):
         igrps = None
+        ievgrps = None
         if patterns is None:
             grps = self.comps.groups
             if self.conf.group_command == 'objects':
                 igrps = self.igroups.groups.values()
-            return igrps, grps
+            evgrps = self.comps.environments
+            if False and self.conf.group_command == 'objects':
+                # FIXME: Environment groups.
+                ievgrps = self.igroups.environments.values()
+            return igrps, grps, ievgrps, evgrps
+
+        gpats = []
+        epats = []
+        for pat in patterns:
+            if pat.startswith('@^'):
+                epats.append(pat[2:])
+            elif pat.startswith('@'):
+                gpats.append(pat[1:])
+            else:
+                epats.append(pat)
+                gpats.append(pat)
+
+        epats = ",".join(epats)
+        gpats = ",".join(gpats)
 
-        pats = ",".join(patterns)
         cs   = not ignore_case
-        grps = self.comps.return_groups(pats, case_sensitive=cs)
+        grps = self.comps.return_groups(gpats, case_sensitive=cs)
         #  Because we want name matches too, and we don't store group names
         # we need to add the groupid's we've found:
         if self.conf.group_command == 'objects':
-            pats += "," + ",".join([grp.groupid for grp in grps])
-            igrps = self.igroups.return_groups(pats, case_sensitive=cs)
-        return igrps, grps
+            gpats = gpats + "," + ",".join([grp.groupid for grp in grps])
+            igrps = self.igroups.return_groups(gpats, case_sensitive=cs)
 
-    def doGroupLists(self, uservisible=0, patterns=None, ignore_case=True):
+        evgrps = self.comps.return_environments(epats, case_sensitive=cs)
+        if self.conf.group_command == 'objects':
+            epats = epats+ "," + ",".join([grp.environmentid for grp in 
evgrps])
+            ievgrps = self.igroups.return_environments(epats, 
case_sensitive=cs)
+        return igrps, grps, ievgrps, evgrps
+
+    def doGroupLists(self, uservisible=0, patterns=None, ignore_case=True,
+                     return_evgrps=False):
         """Return two lists of groups: installed groups and available
         groups.
 
@@ -3257,14 +3313,19 @@ much more problems).
            lists.  If not given, all groups will be included
         :param ignore_case: whether to ignore case when determining
            whether group names match the strings in *patterns*
+        :param return_evgrps: whether to return environment groups as well as
+           package groups
         """
         installed = []
         available = []
+        einstalled = []
+        eavailable = []
 
         if self.comps.compscount == 0:
             raise Errors.GroupsError, _('No group data available for 
configured repositories')
         
-        igrps, grps = self._groupReturnGroups(patterns, ignore_case)
+        igrps, grps, ievgrps, evgrps = self._groupReturnGroups(patterns,
+                                                               ignore_case)
 
         if igrps is not None:
             digrps = {}
@@ -3272,6 +3333,12 @@ much more problems).
                 digrps[igrp.gid] = igrp
             igrps = digrps
 
+        if ievgrps is not None:
+            digrps = {}
+            for ievgrp in ievgrps:
+                digrps[ievgrp.evgid] = ievgrp
+            ievgrps = digrps
+
         for grp in grps:
             if igrps is None:
                 grp_installed = grp.installed
@@ -3292,20 +3359,49 @@ much more problems).
                         available.append(grp)
                 else:
                     available.append(grp)
+
+        for evgrp in evgrps:
+            if ievgrps is None:
+                evgrp_installed = evgrp.installed
+            else:
+                evgrp_installed = evgrp.environmentid in ievgrps
+                if evgrp_installed:
+                    del ievgrps[evgrp.environmentid]
+
+            if evgrp_installed:
+                einstalled.append(evgrp)
+            else:
+                eavailable.append(evgrp)
             
         if igrps is None:
-            return sorted(installed), sorted(available)
+            igrps = {}
+        if ievgrps is None:
+            ievgrps = {}
 
         for igrp in igrps.values():
             #  These are installed groups that aren't in comps anymore. so we
             # create fake comps groups for them.
             grp = comps.Group()
+            grp.groupid = igrp.gid
             grp.installed = True
             grp.name = grp.groupid
             for pkg_name in igrp.pkg_names:
                 grp.mandatory_packages[pkg_name] = 1
             installed.append(grp)
 
+        for ievgrp in ievgrps.values():
+            #  These are installed evgroups that aren't in comps anymore. so we
+            # create fake comps evgroups for them.
+            evgrp = comps.Environment()
+            grp.environmentid = ievgrp.evgid
+            evgrp.installed = True
+            evgrp.name = evgrp.environmentid
+            evgrp._groups = list(ievgrp.groups)
+            einstalled.append(evgrp)
+
+        if return_evgrps:
+            return (sorted(installed), sorted(available),
+                    sorted(einstalled), sorted(eavailable))
         return sorted(installed), sorted(available)
     
     def groupRemove(self, grpid):
@@ -3317,8 +3413,11 @@ much more problems).
            transaction set by this function
         """
         txmbrs_used = []
-        
-        thesegroups = self.comps.return_groups(grpid)
+
+        if self.conf.group_command == 'objects':
+            thesegroups = self.igroups.return_groups(grpid)
+        else:
+            thesegroups = self.comps.return_groups(grpid)
         if not thesegroups:
             raise Errors.GroupsError, _("No Group named %s exists") % 
to_unicode(grpid)
 
@@ -3326,17 +3425,24 @@ much more problems).
             igroup_data = self._groupInstalledData(thisgroup)
 
             thisgroup.toremove = True
-            pkgs = thisgroup.packages
-            for pkg in thisgroup.packages:
+
+            if self.conf.group_command == 'objects':
+                pkgs = thisgroup.pkg_names
+                gid  = thisgroup.gid
+            else:
+                pkgs = thisgroup.packages
+                gid  = thisgroup.groupid
+
+            for pkg in pkgs:
                 if pkg in igroup_data and igroup_data[pkg] != 'installed':
                     continue
 
                 txmbrs = self.remove(name=pkg, silence_warnings=True)
                 txmbrs_used.extend(txmbrs)
                 for txmbr in txmbrs:
-                    txmbr.groups.append(thisgroup.groupid)
+                    txmbr.groups.append(gid)
             if igroup_data:
-                self.igroups.del_group(thisgroup.groupid)
+                self.igroups.del_group(gid)
             
         return txmbrs_used
 
@@ -3368,8 +3474,48 @@ much more problems).
                             self.tsInfo.remove(txmbr.po.pkgtup)
         
         
+    def environmentRemove(self, evgrpid):
+        """Mark all the packages in the given group to be removed.
+
+        :param evgrpid: the name of the environment containing the groups to
+           mark for removal
+        :return: a list of transaction members added to the
+           transaction set by this function
+        """
+        txmbrs_used = []
+
+        if self.conf.group_command == 'objects':
+            thesegroups = self.igroups.return_environments(evgrpid)
+        else:
+            thesegroups = self.comps.return_environments(evgrpid)
+        if not thesegroups:
+            raise Errors.GroupsError, _("No Environment named %s exists") % 
to_unicode(evgrpid)
+
+        for thisgroup in thesegroups:
+            igroup_data = self._groupInstalledEnvData(thisgroup)
+
+            if self.conf.group_command == 'objects':
+                grps  = thisgroup.grp_names
+                evgid = thisgroup.evgid
+            else:
+                grps  = thisgroup.allgroups
+                evgid = thisgroup.environmentid
+
+            for grp in grps:
+                if grp in igroup_data and igroup_data[grp] != 'installed':
+                    continue
+
+                txmbrs = self.groupRemove(grp)
+                txmbrs_used.extend(txmbrs)
+                for txmbr in txmbrs:
+                    txmbr.environments.append(evgid)
+            if igroup_data:
+                self.igroups.del_environment(evgid)
+
+        return txmbrs_used
+
     def selectGroup(self, grpid, group_package_types=[],
-                    enable_group_conditionals=None, upgrade=False):
+                    enable_group_conditionals=None, upgrade=False, 
ievgrp=None):
         """Mark all the packages in the given group to be installed.
 
         :param grpid: the name of the group containing the packages to
@@ -3395,6 +3541,9 @@ much more problems).
         if group_package_types:
             package_types = group_package_types
 
+        if self.conf.group_command == 'compat':
+            upgrade = False
+
         for thisgroup in thesegroups:
             if thisgroup.selected:
                 continue
@@ -3415,7 +3564,8 @@ much more problems).
                 if thisgroup.groupid in self.igroups.groups:
                     igrp = self.igroups.groups[thisgroup.groupid]
                 else:
-                    
self.igroups.add_group(thisgroup.groupid,thisgroup.packages)
+                    self.igroups.add_group(thisgroup.groupid,
+                                           thisgroup.packages, ievgrp)
             pkgs.extend(list(igroup_data.keys()))
 
             old_txmbrs = len(txmbrs_used)
@@ -3442,7 +3592,8 @@ much more problems).
                     if (upgrade and
                         (self.conf.group_command == 'simple' or
                          (igroup_data and igroup_data[pkg] == 'installed'))):
-                        txmbrs = self.update(name = pkg)
+                        txmbrs = self.update(name = pkg,
+                                             pkg_warning_level='debug2')
                     elif igroup_data and igroup_data[pkg] == 'installed':
                         pass # Don't upgrade on install.
                     else:
@@ -3464,7 +3615,8 @@ much more problems).
 
             count_cond_test = 0
             # FIXME: What do we do about group conditionals when group==objects
-            if group_conditionals:
+            #        or group upgrade for group_command=simple?
+            if not upgrade and group_conditionals:
                 for condreq, cond in 
thisgroup.conditional_packages.iteritems():
                     if self.isPackageInstalled(cond):
                         try:
@@ -3501,8 +3653,9 @@ much more problems).
                         if cond not in self.tsInfo.conditionals:
                             self.tsInfo.conditionals[cond] = []
                         self.tsInfo.conditionals[cond].extend(pkgs)
-            if len(txmbrs_used) == old_txmbrs:
-                self.logger.critical(_('Warning: Group %s does not have any 
packages.'), thisgroup.groupid)
+
+            if not upgrade and len(txmbrs_used) == old_txmbrs:
+                self.logger.critical(_('Warning: Group %s does not have any 
packages to install.'), thisgroup.groupid)
                 if count_cond_test:
                     self.logger.critical(_('Group %s does have %u conditional 
packages, which may get installed.'), count_cond_test)
         return txmbrs_used
@@ -3523,7 +3676,8 @@ much more problems).
         thesegroups = self.comps.return_groups(grpid)
         if not thesegroups:
             raise Errors.GroupsError, _("No Group named %s exists") % 
to_unicode(grpid)
-        
+
+        # FIXME: Do something with groups as objects, and env. groups.
         for thisgroup in thesegroups:
             thisgroup.selected = False
             
@@ -3549,6 +3703,86 @@ much more problems).
                         for pkg in self.tsInfo.conditionals.get(txmbr.name, 
[]):
                             self.tsInfo.remove(pkg.pkgtup)
         
+    def selectEnvironment(self, evgrpid, group_package_types=[],
+                          enable_group_conditionals=None, upgrade=False):
+        """Mark all the groups in the given environment group to be installed.
+
+        :param evgrpid: the name of the env. group containing the groups to
+           mark for installation
+        :param group_package_types: a list of the types of groups to
+           work with.  This overrides self.conf.group_package_types
+        :param enable_group_conditionals: overrides
+           self.conf.enable_group_conditionals
+        :return: a list of transaction members added to the
+           transaction set by this function
+        """
+        evgrps = self.comps.return_environments(evgrpid)
+        if not evgrps:
+            raise Errors.GroupsError, _("No Environment named %s exists") % 
to_unicode(evgrpid)
+
+        ret = []
+        for evgrp in evgrps:
+
+            ievgrp = None
+            if self.conf.group_command == 'compat':
+                grps = ",".join(sorted(evgrp.groups))
+            elif self.conf.group_command == 'simple':
+                if not upgrade:
+                    grps = ",".join(sorted(evgrp.groups))
+                else: # Only upgrade the installed groups...
+                    grps = []
+                    for grpid in evgrp.groups:
+                        grp = self.comps.return_group(grpid)
+                        if grp is None:
+                            continue
+                        if not grp.installed:
+                            continue
+                        grps.append(grpid)
+                    grps = ",".join(sorted(grps))
+            elif self.conf.group_command == 'objects':
+                igroup_data = self._groupInstalledEnvData(evgrp)
+ 
+                grps = []
+                for grpid in evgrp.groups:
+                    if (grpid not in igroup_data or
+                        igroup_data[grpid].startswith('blacklisted')):
+                        msg = _('Skipping group %s from environment %s'),
+                        self.verbose_logger.log(logginglevels.DEBUG_2,
+                                                msg, grpid, 
evgrp.environmentid)
+                        continue
+                    grps.apped(grp)
+                if evgrp.environmentid in self.igroups.environments:
+                    ievgrp = self.igroups.environments[evgrp.environmentid]
+                else:
+                    self.igroups.add_environment(evgrp.environmentid,
+                                                 evgrp.allgroups)
+                grps = ",".join(sorted(grps))
+
+            txs = self.selectGroup(grps,
+                                   group_package_types,
+                                   enable_group_conditionals, upgrade,
+                                   ievgrp=ievgrp)
+            ret.extend(txs)
+        return ret
+
+    def deselectEnvironment(self, evgrpid, force=False):
+        """Unmark the groups in the given environment group from being
+        installed.
+
+        :param evgrpid: the name of the environment group containing the
+           groups to unmark from installation
+        :param force: if True, force remove all the packages in the
+           given groups from the transaction
+        """
+        evgrps = self.comps.return_environments(evgrpid)
+        if not thesegroups:
+            raise Errors.GroupsError, _("No Environment named %s exists") % 
to_unicode(evgrpid)
+
+        for evgrp in evgrps:
+            grps = ",".join(sorted(evgrp.groups))
+            self.deselectGroup(grps, force)
+            # FIXME: env. needs to be marked not-to-be-installed, etc.
+
     def getPackageObject(self, pkgtup, allow_missing=False):
         """Return a package object that corresponds to the given
         package tuple.
@@ -3953,6 +4187,20 @@ much more problems).
         assert pattern[0] == '@'
         group_string = pattern[1:]
         tx_return = []
+
+        if group_string and group_string[0] == '^':
+            group_string = group_string[1:]
+            # Actually dealing with "environment groups".
+            for env_grp in self.comps.return_environments(group_string):
+                try:
+                    txmbrs = self.selectEnvironment(env_grp.environmentid,
+                                                    upgrade=upgrade)
+                    tx_return.extend(txmbrs)
+                except yum.Errors.GroupsError:
+                    self.logger.critical(_('Warning: Environment Group %s does 
not exist.'), group_string)
+                    continue
+            return tx_return
+
         for group in self.comps.return_groups(group_string):
             try:
                 txmbrs = self.selectGroup(group.groupid, upgrade=upgrade)
@@ -3971,6 +4219,18 @@ much more problems).
         assert pattern[0] == '@'
         group_string = pattern[1:]
         tx_return = []
+
+        if group_string and group_string[0] == '^':
+            group_string = group_string[1:]
+            # Actually dealing with "environment groups".
+            try:
+                txmbrs = self.environmentRemove(group_string)
+            except yum.Errors.GroupsError:
+                self.logger.critical(_('Warning: Environment Group %s does not 
exist.'), group_string)
+            else:
+                tx_return.extend(txmbrs)
+            return tx_return
+
         try:
             txmbrs = self.groupRemove(group_string)
         except yum.Errors.GroupsError:
@@ -3986,6 +4246,8 @@ much more problems).
         assert pattern[0] == '@'
         grpid = pattern[1:]
 
+        # FIXME: **** environment groups and groups as objects... ****
+
         thesegroups = self.comps.return_groups(grpid)
         if not thesegroups:
             raise Errors.GroupsError, _("No Group named %s exists") % 
to_unicode(grpid)
@@ -3999,6 +4261,10 @@ much more problems).
         assert pattern[0] == '-'
         pat = pattern[1:].strip()
 
+        if pat and pat.startswith('@^'):
+            pat = pat[2:]
+            return self.deselectEnvironment(pat)
+
         if pat and pat[0] == '@':
             pat = pat[1:]
             return self.deselectGroup(pat)
@@ -4389,6 +4655,15 @@ much more problems).
         # if no po do kwargs
         # uninstalled pkgs called for update get returned with errors in a 
list, maybe?
 
+        pkg_warn = kwargs.get('pkg_warning_level', 'flibble')
+        def _dbg2(*args, **kwargs):
+            self.verbose_logger.log(logginglevels.DEBUG_2, *args, **kwargs)
+        level2func = {'debug2' : _dbg2,
+                      'warning' : self.verbose_logger.warning}
+        if pkg_warn not in level2func:
+            pkg_warn = 'warning'
+        pkg_warn = level2func[pkg_warn]
+
         tx_return = []
         if not po and not kwargs: # update everything (the easy case)
             self.verbose_logger.log(logginglevels.DEBUG_2, _('Updating 
Everything'))
@@ -4505,7 +4780,7 @@ much more problems).
                     availpkgs = self._compare_providers(availpkgs, requiringPo)
                     availpkgs = map(lambda x: x[0], availpkgs)
                 elif not availpkgs:
-                    self.logger.warning(_("No package matched to upgrade: 
%s"), self._ui_nevra_dict(nevra_dict))
+                    pkg_warn(_("No package matched to upgrade: %s"), 
self._ui_nevra_dict(nevra_dict))
        
         # for any thing specified
         # get the list of available pkgs matching it (or take the po)
-- 
1.7.6.5

_______________________________________________
Yum-devel mailing list
Yum-devel@lists.baseurl.org
http://lists.baseurl.org/mailman/listinfo/yum-devel

Reply via email to