14870 pkgdep should strip dependency debugging information
authorRichard Lowe <richlowe@richlowe.net>
Fri, 02 Apr 2010 19:53:57 -0400
changeset 1845 d9a33bd442b5
parent 1844 12e6aaf59b95
child 1846 37cc4d517320
14870 pkgdep should strip dependency debugging information
src/man/pkgdepend.1.txt
src/modules/publish/dependencies.py
src/pkgdep.py
src/tests/cli/t_pkgdep.py
--- a/src/man/pkgdepend.1.txt	Fri Apr 02 16:42:17 2010 -0700
+++ b/src/man/pkgdepend.1.txt	Fri Apr 02 19:53:57 2010 -0400
@@ -10,7 +10,7 @@
      /usr/bin/pkgdepend generate [-IMm] [-D name=value] [-k path] manifest_path
          proto_dir
 
-     /usr/bin/pkgdepend resolve [-dmos] manifest_path ...
+     /usr/bin/pkgdepend resolve [-dmosv] manifest_path ...
 
 DESCRIPTION
      pkgdepend(1) is used to generate and resolve dependencies for
@@ -60,7 +60,7 @@
           to look for kernel modules.  Using the -k argument removes the
           default paths which are /kernel and /usr/kernel.
 
-     resolve [-mo] [-d output_dir] [-s suffix] manifest_path ...
+     resolve [-mov] [-d output_dir] [-s suffix] manifest_path ...
           Transform dependencies on files into dependencies on the
           packages which deliver those files.  Dependencies are first
           resolved against the manifests given on the command line and
@@ -84,6 +84,9 @@
           will be added to the argument if not provided) to the basename
           of the file that was the source of the resolved dependencies.
 
+          With -v, include additional package dependency debugging
+          metadata.
+
 EXAMPLES
      Example 1: Generate the dependencies for the manifest written in
      foo, whose content directory is in ./bar/baz and store the results
--- a/src/modules/publish/dependencies.py	Fri Apr 02 16:42:17 2010 -0700
+++ b/src/modules/publish/dependencies.py	Fri Apr 02 19:53:57 2010 -0400
@@ -77,7 +77,7 @@
 class UnresolvedDependencyError(DependencyError):
         """This exception is used when no package delivers a file which is
         depended upon."""
-        
+
         def __init__(self, pth, file_dep, pvars):
                 self.path = pth
                 self.file_dep = file_dep
@@ -91,7 +91,7 @@
                         " ".join([("%s:%s" % (name, val)) for name, val in grp])
                         for grp in self.pvars.get_unsatisfied()
                     ]))
-                
+
 def list_implicit_deps(file_path, proto_dir, dyn_tok_conv, kernel_paths,
     remove_internal_deps=True):
         """Given the manifest provided in file_path, use the known dependency
@@ -150,7 +150,7 @@
                 delivered.setdefault(rp, variants.VariantSets()).merge(pvars)
                 bn = os.path.basename(p)
                 delivered_bn.setdefault(bn, variants.VariantSets()).merge(pvars)
-                
+
         for d in deps:
                 etype, pvars = d.resolve_internal(delivered_files=delivered,
                     delivered_base_names=delivered_bn)
@@ -302,7 +302,7 @@
 
         'orig_dep_vars' is the original set of variants under which the
         dependency must be satisfied.
-        
+
         'pkg_vars' is the list of variants against which the package delivering
         the action was published."""
 
@@ -369,7 +369,7 @@
 
         'orig_dep_vars' is the original set of variants under which the
         dependency must be satisfied.
-        
+
         'pkg_vars' is the list of variants against which the package delivering
         the action was published."""
 
@@ -648,14 +648,25 @@
         dep.strip_variants()
         return dep, dep_vars
 
-def resolve_deps(manifest_paths, api_inst):
+def prune_debug_attrs(action):
+        """Given a dependency action with pkg.debug.depend attributes
+        return a matching action with those attributes removed"""
+
+        attrs = dict((k, v) for k, v in action.attrs.iteritems()
+                     if not k.startswith(base.Dependency.DEPEND_DEBUG_PREFIX))
+        return actions.depend.DependencyAction(**attrs)
+
+def resolve_deps(manifest_paths, api_inst, prune_attrs=False):
         """For each manifest given, resolve the file dependencies to package
         dependencies. It returns a mapping from manifest_path to a list of
         dependencies and a list of unresolved dependencies.
 
         'manifest_paths' is a list of paths to the manifests being resolved.
 
-        'api_inst' is an ImageInterface which references the current image."""
+        'api_inst' is an ImageInterface which references the current image.
+
+        'prune_attrs' is a boolean indicating whether debugging
+        attributes should be stripped from returned actions."""
 
         # The variable 'manifests' is a list of 5-tuples. The first element
         # of the tuple is the path to the manifest. The second is the name of
@@ -736,6 +747,9 @@
                 # Add variant information to the dependency actions and combine
                 # what would otherwise be duplicate dependencies.
                 deps = combine(deps, pkg_vars)
+
+                if prune_attrs:
+                        deps = [prune_debug_attrs(d) for d in deps]
                 pkg_deps[mp] = deps
-                        
+
         return pkg_deps, errs
--- a/src/pkgdep.py	Fri Apr 02 16:42:17 2010 -0700
+++ b/src/pkgdep.py	Fri Apr 02 19:53:57 2010 -0400
@@ -79,7 +79,7 @@
 
 Subcommands:
         pkgdepend generate [-DIkMm] manifest proto_dir
-        pkgdepend [options] resolve [-dMos] manifest ...
+        pkgdepend [options] resolve [-dmosv] manifest ...
 
 Options:
         -R dir
@@ -141,7 +141,7 @@
                     "inferred from the\ninstall paths of the files."))
 
         retcode = 0
-                
+
         manf = pargs[0]
         proto_dir = pargs[1]
 
@@ -167,14 +167,14 @@
                 for l in fh:
                         msg(l.rstrip())
                 fh.close()
-        
+
         for d in sorted(ds):
                 msg(d)
 
         if show_missing:
                 for m in ms:
                         emsg(m)
-                
+
         for e in es:
                 emsg(e)
                 retcode = 1
@@ -188,8 +188,9 @@
         echo_manifest = False
         output_to_screen = False
         suffix = None
+        verbose = False
         try:
-            opts, pargs = getopt.getopt(args, "d:mos:")
+            opts, pargs = getopt.getopt(args, "d:mos:v")
         except getopt.GetoptError, e:
             usage(_("illegal global option -- %s") % e.opt)
         for opt, arg in opts:
@@ -201,6 +202,8 @@
                         output_to_screen = True
                 elif opt == "-s":
                         suffix = arg
+                elif opt == "-v":
+                        verbose = True
 
         if (out_dir or suffix) and output_to_screen:
                 usage(_("-o cannot be used with -d or -s"))
@@ -216,7 +219,7 @@
                 out_dir = os.path.abspath(out_dir)
                 if not os.path.isdir(out_dir):
                         usage(_("The output directory %s is not a directory." %
-                            manf), retcode=2)
+                            out_dir), retcode=2)
 
         if img_dir is None:
                 try:
@@ -249,14 +252,15 @@
                 return 1
 
         try:
-            pkg_deps, errs = dependencies.resolve_deps(manifest_paths, api_inst)
+            pkg_deps, errs = dependencies.resolve_deps(manifest_paths, api_inst,
+                prune_attrs=not verbose)
         except (actions.MalformedActionError, actions.UnknownActionError), e:
             error(_("Could not parse one or more manifests because of the " +
                 "following line:\n%s") % e.actionstr)
             return 1
 
         ret_code = 0
-        
+
         if output_to_screen:
                 ret_code = pkgdeps_to_screen(pkg_deps, manifest_paths,
                     echo_manifest)
@@ -297,7 +301,7 @@
                 attrs.update(dict(tup))
                 res.append(str(actions.depend.DependencyAction(**attrs)))
         return "\n".join(res).rstrip()
-        
+
 def pkgdeps_to_screen(pkg_deps, manifest_paths, echo_manifest):
         """Write the resolved package dependencies to stdout.
 
--- a/src/tests/cli/t_pkgdep.py	Fri Apr 02 16:42:17 2010 -0700
+++ b/src/tests/cli/t_pkgdep.py	Fri Apr 02 19:53:57 2010 -0400
@@ -108,7 +108,7 @@
                                 fp, self.py_path)
                             ])))
                         return res
-                        
+
                 sp = subprocess.Popen(
                     "python%s -c 'import sys; print sys.path'" % ver,
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -157,7 +157,7 @@
                     "dummy_fmri": base.Dependency.DUMMY_FMRI,
                     "reason": "%(reason)s"
                 }
-                
+
         def make_full_res_manf_1(self, proto_area):
                 return self.make_res_manf_1(proto_area) + self.test_manf_1
 
@@ -187,7 +187,7 @@
     "pfx":base.Dependency.DEPEND_DEBUG_PREFIX,
     "dummy_fmri":base.Dependency.DUMMY_FMRI
 }
-        
+
         def make_res_payload_1(self, proto_area):
                 return ("depend fmri=%(dummy_fmri)s "
                     "%(pfx)s.file=python "
@@ -230,7 +230,7 @@
 file NOHASH group=sys mode=0600 owner=root path=var/log/authlog variant.foo=baz variant.num=two
 """
 
-        two_v_deps_output = """\
+        two_v_deps_verbose_output = """\
 %(m1_path)s
 depend fmri=pkg:/s-v-bar pkg.debug.depend.file=var/log/authlog pkg.debug.depend.file=var/log/file2 pkg.debug.depend.reason=baz pkg.debug.depend.type=hardlink type=require
 depend fmri=pkg:/s-v-baz-one pkg.debug.depend.file=var/log/authlog pkg.debug.depend.reason=baz pkg.debug.depend.type=hardlink type=require variant.foo=baz variant.num=one
@@ -251,6 +251,26 @@
 
 """
 
+        two_v_deps_output = """\
+%(m1_path)s
+depend fmri=pkg:/s-v-bar type=require
+depend fmri=pkg:/s-v-baz-one type=require variant.foo=baz variant.num=one
+depend fmri=pkg:/s-v-baz-two type=require variant.foo=baz variant.num=two
+
+
+%(m2_path)s
+
+
+
+%(m3_path)s
+
+
+
+%(m4_path)s
+
+
+"""
+
         dup_variant_deps = """\
 set name=variant.foo value=bar value=baz
 set name=variant.num value=one value=two
@@ -390,7 +410,7 @@
 
 Subcommands:
         pkgdepend generate [-DIkMm] manifest proto_dir
-        pkgdepend [options] resolve [-dMos] manifest ...
+        pkgdepend [options] resolve [-dmosv] manifest ...
 
 Options:
         -R dir
@@ -490,7 +510,7 @@
                     pkg_path +
                     " %(pfx)s.reason=%(reason)s "
                     "%(pfx)s.type=python type=require\n"
-                        
+
                     "depend fmri=%(dummy_fmri)s "
                     "%(pfx)s.file=misc.py "
                     "%(pfx)s.file=misc.pyc "
@@ -499,13 +519,13 @@
                     pkg_path +
                     " %(pfx)s.reason=%(reason)s "
                     "%(pfx)s.type=python type=require\n"
-                        
+
                     "depend fmri=%(dummy_fmri)s "
                     "%(pfx)s.file=pkg/__init__.py " +
                     self.__make_paths("", vp) +
                     " %(pfx)s.reason=%(reason)s "
                     "%(pfx)s.type=python type=require\n"
-                        
+
                     "depend fmri=%(dummy_fmri)s "
                     "%(pfx)s.file=search_storage.py "
                     "%(pfx)s.file=search_storage.pyc "
@@ -645,13 +665,13 @@
                     proto=proto, exit=2)
                 self.pkgdepend_generate("-\?", proto="")
                 self.pkgdepend_generate("--help", proto="")
-                
+
         def test_output(self):
                 """Check that the output is in the format expected."""
 
                 tp = self.make_manifest(self.test_manf_1)
-                fp = "usr/lib/python2.6/vendor-packages/pkg/client/indexer.py" 
-                
+                fp = "usr/lib/python2.6/vendor-packages/pkg/client/indexer.py"
+
                 self.pkgdepend_generate("%s" % tp,
                     proto=pkg5unittest.g_proto_area, exit=1)
                 self.check_res(self.make_res_manf_1(
@@ -671,7 +691,7 @@
 
                 self.make_proto_text_file(fp, self.python_text)
                 self.make_elf([], "usr/xpg4/lib/libcurses.so.1")
-                
+
                 self.pkgdepend_generate("-m %s" % tp, proto=self.test_proto_dir)
                 self.check_res(
                     self.make_full_res_manf_1_mod_proto(
@@ -681,7 +701,7 @@
 
                 tp = self.make_manifest(self.test_manf_2)
                 self.make_proto_text_file("etc/pam.conf", "text")
-                
+
                 self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res(self.res_manf_2, self.output)
                 self.check_res("", self.errout)
@@ -696,7 +716,7 @@
                             base.Dependency.DEPEND_DEBUG_PREFIX,
                         "dummy_fmri":base.Dependency.DUMMY_FMRI
                     }, self.errout)
-                
+
                 self.pkgdepend_generate("-M %s" % tp, proto=self.test_proto_dir)
                 self.check_res(self.res_manf_2, self.output)
                 self.check_res(self.res_manf_2_missing, self.errout)
@@ -707,7 +727,7 @@
                 tp = self.make_manifest(self.int_hardlink_manf)
 
                 self.make_proto_text_file("var/log/syslog", "text")
-                
+
                 self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res("", self.output)
                 self.check_res("", self.errout)
@@ -734,7 +754,7 @@
                 3) Does the first line of the file include a specific version
                     of python.
                     (Represented by F)
-                
+
                 Conditions || Perform Analysis
                  X  D  F   || Y, if F and D disagree, display a warning in the
                            ||     output and use D to analyze the file.
@@ -850,7 +870,7 @@
                         tp = self.make_manifest(
                             self.pyver_test_manf_1 % {"py_ver":py_ver})
                         fp = "usr/lib/python%s/vendor-packages/pkg/" \
-                            "client/indexer.py" % py_ver 
+                            "client/indexer.py" % py_ver
                         self.make_proto_text_file(fp, self.python_text)
 
                         # Run generate and check the output.
@@ -870,7 +890,7 @@
 
                         # Run resolver and check the output.
                         self.pkgdepend_resolve(
-                            "%s %s" % (dependency_mp, provider_mp))
+                            "-v %s %s" % (dependency_mp, provider_mp))
                         self.check_res("", self.output)
                         self.check_res("", self.errout)
                         dependency_res_p = dependency_mp + ".res"
@@ -893,14 +913,11 @@
         def test_resolve_screen_out(self):
                 """Check that the results printed to screen are what is
                 expected."""
-                
+
                 m1_path = self.make_manifest(self.two_variant_deps)
                 m2_path = self.make_manifest(self.two_v_deps_bar)
                 m3_path = self.make_manifest(self.two_v_deps_baz_one)
                 m4_path = self.make_manifest(self.two_v_deps_baz_two)
-                p2_name = "s-v-bar"
-                p3_name = "s-v-baz-one"
-                p4_name = "s-v-baz-two"
                 self.pkgdepend_resolve("-o %s" %
                     " ".join([m1_path, m2_path, m3_path, m4_path]), exit=1)
 
@@ -910,6 +927,7 @@
                         "m3_path": m3_path,
                         "m4_path": m4_path
                     }, self.output)
+
                 self.check_res(self.two_v_deps_resolve_error % {
                         "manf_path": m1_path,
                         "pfx":
@@ -917,6 +935,16 @@
                         "dummy_fmri":base.Dependency.DUMMY_FMRI
                     }, self.errout)
 
+                self.pkgdepend_resolve("-vo %s" %
+                    " ".join([m1_path, m2_path, m3_path, m4_path]), exit=1)
+
+                self.check_res(self.two_v_deps_verbose_output % {
+                        "m1_path": m1_path,
+                        "m2_path": m2_path,
+                        "m3_path": m3_path,
+                        "m4_path": m4_path
+                    }, self.output)
+
         def test_bug_10518(self):
                 """ pkgdepend should exit 2 on input args of the wrong type """
                 m_path = self.make_manifest(self.test_manf_1)
@@ -970,10 +998,10 @@
                 m_path = None
                 nonsense = "This is a nonsense manifest"
                 m_path = self.make_manifest(nonsense)
-                
+
                 self.pkgdepend_generate("%s" % m_path,
                     proto=self.test_proto_dir, exit=1)
-                self.check_res('pkgdepend: Could not parse manifest ' + 
+                self.check_res('pkgdepend: Could not parse manifest ' +
                     '%s because of the following line:\n' % m_path +
                     nonsense, self.errout)
 
@@ -986,7 +1014,7 @@
                 """Using the provided run paths, produces a elf binary with
                 those paths set and checks to make sure that pkgdep run with
                 the provided arguments performs the substitution correctly."""
-                
+
                 elf_path = self.make_elf(run_paths)
                 m_path = self.make_manifest(self.elf_sub_manf %
                     {"file_loc": elf_path})
@@ -1026,7 +1054,7 @@
                     m_path, proto=self.test_proto_dir)
                 self.check_res("", self.errout)
                 self.check_res(self.kernel_manf_stdout_platform, self.output)
-                
+
                 self.debug("Test unexpanded token")
 
                 rp = ["/platform/$PLATFORM/foo"]
@@ -1089,7 +1117,7 @@
                     proto=self.test_proto_dir)
                 self.check_res("", self.errout)
                 self.check_res(self.double_double_stdout, self.output)
-                
+
         def test_bug_12816(self):
                 """Test that the error produced by a missing payload action
                 uses the right path."""
@@ -1141,7 +1169,7 @@
 
                 # In the comments below, v.f stands for variant.foo and v.n
                 # stands for variant.num.
-                
+
                 # dup_variant_deps contains all the dependencies to be resolved.
                 # It is published as dup-v-deps.
                 m1_path = self.make_manifest(self.dup_variant_deps)
@@ -1192,10 +1220,7 @@
                 # that manually added dependencies are propogated correctly.
                 m8_path = self.make_manifest("\n\n")
 
-                p2_name = "s-v-bar"
-                p3_name = "s-v-baz-one"
-                p4_name = "s-v-baz-two"
-                self.pkgdepend_resolve(" -m %s" % " ".join([m1_path, m2_path,
+                self.pkgdepend_resolve(" -vm %s" % " ".join([m1_path, m2_path,
                         m3_path, m4_path, m5_path, m6_path, m7_path, m8_path]))
                 fh = open(m1_path + ".res")
                 res = fh.read()