hi there,

I've a small code review here (134 line of change, nearly all test changes) for a pkglint RFE, that allows Checker subclasses to lookup any given manifest in the reference repository.

https://cr.opensolaris.org/action/browse/pkg/timf/pkglint-access-refmf/pkglint-access-refmf-webrev

This allows users to write plugins that compare lint manifests with manifests from the reference repo. I'm not adding any lint Checkers to the gate that use this RFE, but am adding unit tests for the functionality.

As an example, the attached pkglint plugin shows how we could check if packages being linted would bring in new 'type=parent' dependencies. This check can be useful in cases where:

   * a user has minimized a global zone, removing a package
   * a refactoring in a different non-global zone package
     causes a new parent dependency on that
     now-uninstalled package
   * the system fails to update as a result, because that package
     no longer exists in the global zone.


- having pkglint issue warnings about new parent dependencies can certainly be helpful, it's just a bit advanced to include as a bundled lint check (because in many cases, it's perfectly legal to bring in new parent dependencies, you just have to be careful about it)

        cheers,
                        tim
#!/usr/bin/python
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
#
import pkg.lint.base as base

class WosManifestChecker(base.ManifestChecker):
        """An example class iwh a single check for parent dependencies."""

        name = "wos.manifest"

        def __init__(self, config):
                self.description = _(
                    "checks packages for parent dependency issues")
                super(WosManifestChecker, self).__init__(config)

        def __expand_parent_deps(self, manifest, engine, reference=False):
                """Very crudely expand dependencies, returning the set of
                all parent dependencies that could be brought onto the system
                by this manifest. We ignore 'incorporate' dependencies, but
                otherwise consider all dependencies regardless of variant,
                facet or predicate values.

                Returns a set of packages which were parent dependencies
                encountered while expanding dependencies expressed by this
                manifest.
                """

                parent_deps = set()
                seen_mfs = set()
                def expand_deps(mf, parent_deps):
                        # iterate through the manfest looking for depend actions
                        for ac in mf.gen_actions_by_type("depend"):
                                fmri = ac.attrs["fmri"]
                                if fmri == "feature/package/dependency/self":
                                        fmri = mf.fmri.get_name()
                                if fmri in seen_mfs:
                                        # crude, since we could have multiple
                                        # ways of expressing the same dependency
                                        continue
                                seen_mfs.add(fmri)
                                if ac.attrs["type"] == "parent":
                                        parent_deps.add(fmri)
                                elif ac.attrs["type"] != "incorporate":
                                        # recurse
                                        dep_mf = engine.get_manifest(fmri,
                                            search_type=engine.LATEST_SUCCESSOR,
                                            reference=reference)
                                        # our reference may not have this dep.
                                        if dep_mf:
                                                expand_deps(dep_mf, parent_deps)
                expand_deps(manifest, parent_deps)
                return parent_deps

        def parent_deps(self, manifest, engine, pkglint_id="001"):
                """Warn when a package introduces a new parent dependency."""

                lint_id = "%s%s" % (self.name, pkglint_id)
                try:
                        ref_mf = engine.get_manifest(manifest.fmri.get_name(),
                            search_type=engine.LATEST_SUCCESSOR, reference=True)
                        if not ref_mf:
                                return
                except base.LintException:
                        engine.warning(_("parent deps check skipped for "
                            "%(pkg)s: no reference repository configured") %
                            {"pkg": manifest.fmri},
                            msgid="%s.2" % lint_id)
                        return

                # the lint package might be new, and no version appears in the
                # reference repository
                if not ref_mf:
                        return

                parent_deps = self.__expand_parent_deps(manifest, engine)
                ref_parent_deps = self.__expand_parent_deps(ref_mf, engine,
                    reference=True)
                new_deps = parent_deps - ref_parent_deps

                if new_deps:
                        engine.warning(_("The following new parent dependencies"
                            " are introduced as a result of %(pkg)s:\n\t"
                            "%(deps)s") %
                            {"pkg": manifest.fmri,
                            "deps": "\n\t".join(list(new_deps))},
                            msgid="%s.1" % lint_id)

        parent_deps.pkglint_desc = _(
            "Check that no new parent dependencies are introduced.")
_______________________________________________
pkg-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/pkg-discuss

Reply via email to