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