17944 specifying multiple forms of the same pattern should not result in a matching error
authorShawn Walker <shawn.walker@oracle.com>
Fri, 18 Mar 2011 11:01:24 -0700
changeset 2260 ea8567aa3ef8
parent 2259 5702783558d1
child 2261 3c66f438398d
17944 specifying multiple forms of the same pattern should not result in a matching error 17952 pkg verify errors are prefixed with the wrong subcommand
src/client.py
src/modules/client/api.py
src/modules/client/imageplan.py
src/tests/cli/t_pkg_install.py
--- a/src/client.py	Fri Mar 18 10:51:01 2011 -0700
+++ b/src/client.py	Fri Mar 18 11:01:24 2011 -0700
@@ -848,7 +848,7 @@
                         logger.error(" ")
 
                 error(_("no packages matching '%s' installed") % \
-                    ", ".join(notfound), cmd="fix")
+                    ", ".join(notfound), cmd="verify")
 
                 if processed:
                         if any_errors:
--- a/src/modules/client/api.py	Fri Mar 18 10:51:01 2011 -0700
+++ b/src/modules/client/api.py	Fri Mar 18 11:01:24 2011 -0700
@@ -1956,12 +1956,27 @@
                 pat_tuples = {}
                 pat_versioned = False
                 latest_pats = set()
+                seen = set()
+                npatterns = set()
                 for pat, error, pfmri, matcher in self.parse_fmri_patterns(
                     patterns):
                         if error:
                                 illegals.append(error)
                                 continue
 
+                        # Duplicate patterns are ignored.
+                        sfmri = str(pfmri)
+                        if sfmri in seen:
+                                # A different form of the same pattern
+                                # was specified already; ignore this
+                                # one (e.g. pkg:/network/ping,
+                                # /network/ping).
+                                continue
+
+                        # Track used patterns.
+                        seen.add(sfmri)
+                        npatterns.add(pat)
+
                         if "@" in pat:
                                 # Mark that a pattern contained version
                                 # information.  This is used for a listing
@@ -1971,6 +1986,9 @@
                                 latest_pats.add(pat)
                         pat_tuples[pat] = (pfmri.tuple(), matcher)
 
+                patterns = npatterns
+                del npatterns, seen
+
                 if illegals:
                         raise apx.InventoryException(illegal=illegals)
 
--- a/src/modules/client/imageplan.py	Fri Mar 18 10:51:01 2011 -0700
+++ b/src/modules/client/imageplan.py	Fri Mar 18 11:01:24 2011 -0700
@@ -49,7 +49,6 @@
 import sys
 
 from pkg.client.debugvalues import DebugValues
-from collections import defaultdict
 
 UNEVALUATED       = 0 # nothing done yet
 EVALUATED_PKGS    = 1 # established fmri changes
@@ -2056,7 +2055,8 @@
                 # print patterns, match_type, pub_ranks
 
                 # figure out which kind of matching rules to employ
-
+                seen = set()
+                npatterns = []
                 for pat in patterns:
                         try:
                                 parts = pat.split("@", 1)
@@ -2078,11 +2078,24 @@
                                         fmri = pkg.fmri.PkgFmri(
                                             pat_stem, brelease)
 
+                                sfmri = str(fmri)
+                                if sfmri in seen:
+                                        # A different form of the same pattern
+                                        # was specified already; ignore this
+                                        # one (e.g. pkg:/network/ping,
+                                        # /network/ping).
+                                        wildcard_patterns.discard(pat)
+                                        continue
+
+                                seen.add(sfmri)
+                                npatterns.append(pat)
                                 matchers.append(matcher)
                                 pubs.append(fmri.publisher)
                                 fmris.append(fmri)
                         except pkg.fmri.FmriError, e:
                                 illegals.append(e)
+                patterns = npatterns
+                del npatterns, seen
 
                 # Create a dictionary of patterns, with each value being a
                 # set of pkg names that match that pattern.
@@ -2105,7 +2118,6 @@
                                         ret[pat].add(name)
 
                 matchdict = {}
-
                 for p in patterns:
                         l = len(ret[p])
                         if l == 0: # no matches at all
@@ -2219,6 +2231,8 @@
                 # figure out which kind of matching rules to employ
                 brelease = self.image.attrs["Build-Release"]
                 latest_pats = set()
+                seen = set()
+                npatterns = []
                 for pat in patterns:
                         try:
                                 parts = pat.split("@", 1)
@@ -2256,6 +2270,17 @@
                                             pkg.version.Version(pat_ver,
                                                 brelease)
 
+                                sfmri = str(fmri)
+                                if sfmri in seen:
+                                        # A different form of the same pattern
+                                        # was specified already; ignore this
+                                        # one (e.g. pkg:/network/ping,
+                                        # /network/ping).
+                                        wildcard_patterns.discard(pat)
+                                        continue
+
+                                seen.add(sfmri)
+                                npatterns.append(pat)
                                 if pat_ver and \
                                     getattr(fmri.version, "match_latest", None):
                                         latest_pats.add(pat)
@@ -2267,6 +2292,8 @@
                         except (pkg.fmri.FmriError,
                             pkg.version.VersionError), e:
                                 illegals.append(e)
+                patterns = npatterns
+                del npatterns, seen
 
                 # Create a dictionary of patterns, with each value being a
                 # dictionary of pkg names & fmris that match that pattern.
--- a/src/tests/cli/t_pkg_install.py	Fri Mar 18 10:51:01 2011 -0700
+++ b/src/tests/cli/t_pkg_install.py	Fri Mar 18 11:01:24 2011 -0700
@@ -581,6 +581,14 @@
                 self.pkg("list baz", exit=0)
                 self.pkg("uninstall 'b*' 'f*'")
 
+                # However, multiple forms of the same pattern should simply be
+                # coalesced and allowed.
+                self.pkg("install pkg:/foo /foo ///foo pkg:///foo")
+                self.pkg("list")
+                self.pkg("verify pkg:/foo /foo ///foo pkg:///foo")
+                self.pkg("uninstall pkg:/foo /foo ///foo "
+                    "pkg:///foo")
+
         def test_bad_package_actions(self):
                 """Test the install of packages that have actions that are
                 invalid."""