python-smartpm: 1.4.1 -> 1.5

* Remove the following patches since the are already in the source:
smart-config-ignore-all-recommends.patch
smart-conflict-provider.patch
smart-dflags.patch
smart-filename-NAME_MAX.patch
smart-flag-exclude-packages.patch
smart-flag-ignore-recommends.patch
smart-metadata-match.patch
smart-multilib-fixes.patch
smart-rpm-extra-macros.patch
smart-rpm-md-parse.patch
smart-rpm-root.patch
smart-tmpdir.patch
smart-yaml-error.patch

* Update the following patches, part of the code are already in the
  source:
smart-attempt.patch
smart-improve-error-reporting.patch
smart-recommends.patch
smartpm-rpm5-nodig.patch

* Use github and git repo as the SRC_URI.

(From OE-Core rev: 5fc580fc444e45d00de0e50d32b6e6e0b2e6b7ea)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Robert Yang
2015-07-08 00:23:48 -07:00
committed by Richard Purdie
parent f9ac3f3e20
commit 05b02d27d2
18 changed files with 132 additions and 2050 deletions

View File

@@ -18,38 +18,68 @@ Upstream-Status: Pending
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
smart.py | 5 +++-
smart/commands/install.py | 5 ++++
smart/transaction.py | 65 +++++++++++++++++++++++++++++++++++------------
3 files changed, 58 insertions(+), 17 deletions(-)
backends/rpm/pm.py | 35 ++++++++++++++++++++++++++++++++++-
transaction.py | 50 +++++++++++++++++++++++++++++++++++++-------------
2 files changed, 71 insertions(+), 14 deletions(-)
Index: smart-1.4.1/smart/commands/install.py
===================================================================
--- smart-1.4.1.orig/smart/commands/install.py
+++ smart-1.4.1/smart/commands/install.py
@@ -50,6 +50,8 @@ def option_parser():
parser = OptionParser(usage=USAGE,
description=DESCRIPTION,
examples=EXAMPLES)
+ parser.add_option("--attempt", action="store_true",
+ help=_("attempt to install packages, ignore failures"))
parser.add_option("--stepped", action="store_true",
help=_("split operation in steps"))
parser.add_option("--urls", action="store_true",
@@ -80,6 +82,9 @@ def main(ctrl, opts):
if not opts.args:
raise Error, _("no package(s) given")
+ if opts.attempt:
+ sysconf.set("attempt-install", True, soft=True)
diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py
index 9bbd952..ba6405a 100644
--- a/smart/backends/rpm/pm.py
+++ b/smart/backends/rpm/pm.py
@@ -241,15 +241,48 @@ class RPMPackageManager(PackageManager):
cb = RPMCallback(prog, upgradednames)
cb.grabOutput(True)
probs = None
+ retry = 0
try:
probs = ts.run(cb, None)
finally:
del getTS.ts
cb.grabOutput(False)
+ if probs and sysconf.has("attempt-install", soft=True):
+ def remove_conflict(pkgNEVR):
+ for key in changeset.keys():
+ if pkgNEVR == str(key):
+ del changeset[key]
+ del pkgpaths[key]
+ iface.warning("Removing %s due to file %s conflicting with %s" % (pkgNEVR, fname, altNEVR))
+ break
+
if opts.explain:
sysconf.set("explain-changesets", True, soft=True)
+ retry = 1
+ for prob in probs:
+ if prob[1][0] == rpm.RPMPROB_NEW_FILE_CONFLICT:
+ msg = prob[0].split()
+ fname = msg[1]
+ pkgNEVR = msg[7]
+ altNEVR = msg[9]
+ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1]
+ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1]
+ remove_conflict(pkgNEVR)
+ elif prob[1][0] == rpm.RPMPROB_FILE_CONFLICT:
+ msg = prob[0].split()
+ fname = msg[1]
+ pkgNEVR = msg[5]
+ altNEVR = msg[11]
+ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1]
+ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1]
+ remove_conflict(pkgNEVR)
+ else:
+ retry = 0
+
prog.setDone()
- if probs:
+ if probs and (not retry):
raise Error, "\n".join([x[0] for x in probs])
prog.stop()
+ if retry and len(changeset):
+ self.commit(changeset, pkgpaths)
Index: smart-1.4.1/smart/transaction.py
===================================================================
--- smart-1.4.1.orig/smart/transaction.py
+++ smart-1.4.1/smart/transaction.py
class RPMCallback:
def __init__(self, prog, upgradednames):
diff --git a/smart/transaction.py b/smart/transaction.py
index 4b90cb7..3e043e9 100644
--- a/smart/transaction.py
+++ b/smart/transaction.py
@@ -555,6 +555,8 @@ class Transaction(object):
changeset.set(pkg, INSTALL)
isinst = changeset.installed
@@ -145,79 +175,3 @@ Index: smart-1.4.1/smart/transaction.py
changeset.set(pkg, INSTALL)
locked[pkg] = (LOCKED_INSTALL, None)
elif op is REMOVE:
@@ -1216,9 +1240,18 @@ class Transaction(object):
else:
op = REMOVE
if op is INSTALL or op is REINSTALL:
- self._install(pkg, changeset, locked, pending)
- if pkg in changeset:
- changeset.setRequested(pkg, True)
+ try:
+ self._install(pkg, changeset, locked, pending)
+ if pkg in changeset:
+ changeset.setRequested(pkg, True)
+ except Failed, e:
+ if attempt:
+ iface.warning(_("Can't install %s: %s") % (pkg, e))
+ if pkg in changeset:
+ del changeset[pkg]
+ continue
+ else:
+ raise Failed, e
elif op is REMOVE:
self._remove(pkg, changeset, locked, pending)
elif op is UPGRADE:
Index: smart-1.4.1/smart/backends/rpm/pm.py
===================================================================
--- smart-1.4.1.orig/smart/backends/rpm/pm.py
+++ smart-1.4.1/smart/backends/rpm/pm.py
@@ -243,15 +253,48 @@ class RPMPackageManager(PackageManager):
cb = RPMCallback(prog, upgradednames)
cb.grabOutput(True)
probs = None
+ retry = 0
try:
probs = ts.run(cb, None)
finally:
del getTS.ts
cb.grabOutput(False)
+ if probs and sysconf.has("attempt-install", soft=True):
+ def remove_conflict(pkgNEVR):
+ for key in changeset.keys():
+ if pkgNEVR == str(key):
+ del changeset[key]
+ del pkgpaths[key]
+ iface.warning("Removing %s due to file %s conflicting with %s" % (pkgNEVR, fname, altNEVR))
+ break
+
+ retry = 1
+ for prob in probs:
+ if prob[1][0] == rpm.RPMPROB_NEW_FILE_CONFLICT:
+ msg = prob[0].split()
+ fname = msg[1]
+ pkgNEVR = msg[7]
+ altNEVR = msg[9]
+ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1]
+ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1]
+ remove_conflict(pkgNEVR)
+ elif prob[1][0] == rpm.RPMPROB_FILE_CONFLICT:
+ msg = prob[0].split()
+ fname = msg[1]
+ pkgNEVR = msg[5]
+ altNEVR = msg[11]
+ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1]
+ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1]
+ remove_conflict(pkgNEVR)
+ else:
+ retry = 0
+
prog.setDone()
- if probs:
+ if probs and (not retry):
raise Error, "\n".join([x[0] for x in probs])
prog.stop()
+ if retry and len(changeset):
+ self.commit(changeset, pkgpaths)
class RPMCallback:
def __init__(self, prog, upgradednames):

View File

@@ -1,24 +0,0 @@
Add a simple method to disable the install of recommended packages
Upstream-Status: Pending
Usage:
smart config --set ignore-all-recommends=1
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Index: smart-1.4.1/smart/transaction.py
===================================================================
--- smart-1.4.1.orig/smart/transaction.py
+++ smart-1.4.1/smart/transaction.py
@@ -611,7 +611,9 @@ class Transaction(object):
for prv in req.providedby:
for prvpkg in prv.packages:
if not reqrequired:
- if pkgconf.testFlag("ignore-recommends", prvpkg):
+ if sysconf.get("ignore-all-recommends", 0) == 1:
+ continue
+ elif pkgconf.testFlag("ignore-recommends", prvpkg):
continue
if isinst(prvpkg):
found = True

View File

@@ -1,196 +0,0 @@
Report a reason when a dependency could not be installed because it is locked
If a requirement of a package is conflicted, depending on how the
solution is reached, the transaction code may eliminate all providers
of the requirement and then error out because nothing provides them. To
work around this, store a reason in the locked dict and report that back
if we need to, so for example instead of:
error: Can't install packagegroup-core-ssh-dropbear-1.0-r1@all: no package provides dropbear
we now get:
error: Can't install packagegroup-core-ssh-dropbear-1.0-r1@all: unable to install provider for dropbear:
error: dropbear-2013.58-r1.0@armv5te is conflicted by openssh-sshd-6.2p2-r0@armv5te
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
smart/const.py | 7 +++++++
smart/transaction.py | 58 +++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/smart/const.py b/smart/const.py
index 4d8e5cb..67c1ac5 100644
--- a/smart/const.py
+++ b/smart/const.py
@@ -70,4 +70,11 @@ DATADIR = "/var/lib/smart/"
USERDATADIR = "~/.smart/"
CONFFILE = "config"
+LOCKED_INSTALL = Enum('LOCKED_INSTALL')
+LOCKED_REMOVE = Enum('LOCKED_REMOVE')
+LOCKED_CONFLICT = Enum('LOCKED_CONFLICT')
+LOCKED_CONFLICT_BY = Enum('LOCKED_CONFLICT_BY')
+LOCKED_NO_COEXIST = Enum('LOCKED_NO_COEXIST')
+LOCKED_SYSCONF = Enum('LOCKED_SYSCONF')
+
# vim:ts=4:sw=4:et
diff --git a/smart/transaction.py b/smart/transaction.py
index 300b9cc..dd9aa38 100644
--- a/smart/transaction.py
+++ b/smart/transaction.py
@@ -19,10 +19,31 @@
# along with Smart Package Manager; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP
+from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP, LOCKED_INSTALL, LOCKED_CONFLICT, LOCKED_CONFLICT_BY, LOCKED_NO_COEXIST, LOCKED_SYSCONF, LOCKED_REMOVE
from smart.cache import PreRequires, Package
from smart import *
+def lock_reason(pkg, lockvalue):
+ try:
+ (reason, otherpkg) = lockvalue
+ except TypeError:
+ reason = None
+ lockvalue = None
+ if reason == LOCKED_INSTALL:
+ return _("%s is to be installed") % pkg
+ elif reason == LOCKED_CONFLICT:
+ return _("%s conflicts with %s") % (pkg, otherpkg)
+ elif reason == LOCKED_CONFLICT_BY:
+ return _("%s is conflicted by %s") % (pkg, otherpkg)
+ elif reason == LOCKED_NO_COEXIST:
+ return _("%s cannot coexist with %s") % (pkg, otherpkg)
+ elif reason == LOCKED_SYSCONF:
+ return _("%s is locked in system configuration") % pkg
+ elif reason == LOCKED_REMOVE:
+ return _("%s is to be removed") % pkg
+ else:
+ return _("%s is locked (unknown reason)") % pkg
+
class ChangeSet(dict):
def __init__(self, cache, state=None, requested=None):
@@ -187,7 +208,7 @@ class Policy(object):
for pkg in pkgconf.filterByFlag("lock", cache.getPackages()):
if pkg not in self._locked:
self._sysconflocked.append(pkg)
- self._locked[pkg] = True
+ self._locked[pkg] = (LOCKED_SYSCONF, None)
def runFinished(self):
self._priorities.clear()
@@ -524,7 +545,7 @@ class Transaction(object):
if ownpending:
pending = []
- locked[pkg] = True
+ locked[pkg] = (LOCKED_INSTALL, None)
changeset.set(pkg, INSTALL)
isinst = changeset.installed
@@ -535,7 +556,7 @@ class Transaction(object):
if prvpkg is pkg:
continue
if not isinst(prvpkg):
- locked[prvpkg] = True
+ locked[prvpkg] = (LOCKED_CONFLICT_BY, pkg)
continue
if prvpkg in locked:
raise Failed, _("Can't install %s: conflicted package "
@@ -550,7 +571,7 @@ class Transaction(object):
if cnfpkg is pkg:
continue
if not isinst(cnfpkg):
- locked[cnfpkg] = True
+ locked[cnfpkg] = (LOCKED_CONFLICT, pkg)
continue
if cnfpkg in locked:
raise Failed, _("Can't install %s: it's conflicted by "
@@ -565,7 +586,7 @@ class Transaction(object):
for namepkg in namepkgs:
if namepkg is not pkg and not pkg.coexists(namepkg):
if not isinst(namepkg):
- locked[namepkg] = True
+ locked[namepkg] = (LOCKED_NO_COEXIST, pkg)
continue
if namepkg in locked:
raise Failed, _("Can't install %s: it can't coexist "
@@ -577,6 +598,7 @@ class Transaction(object):
# Check if someone is already providing it.
prvpkgs = {}
+ lockedpkgs = {}
found = False
for prv in req.providedby:
for prvpkg in prv.packages:
@@ -585,6 +607,8 @@ class Transaction(object):
break
if prvpkg not in locked:
prvpkgs[prvpkg] = True
+ else:
+ lockedpkgs[prvpkg] = locked[prvpkg]
else:
continue
break
@@ -597,7 +621,17 @@ class Transaction(object):
if not prvpkgs:
# No packages provide it at all. Give up.
if req in pkg.requires:
- raise Failed, _("Can't install %s: no package provides %s") % \
+ reasons = []
+ for prv in req.providedby:
+ for prvpkg in prv.packages:
+ lockedres = lockedpkgs.get(prvpkg, None)
+ if lockedres:
+ reasons.append(lock_reason(prvpkg, lockedres))
+ if reasons:
+ raise Failed, _("Can't install %s: unable to install provider for %s:\n %s") % \
+ (pkg, req, '\n '.join(reasons))
+ else:
+ raise Failed, _("Can't install %s: no package provides %s") % \
(pkg, req)
else:
# It's only a recommend, skip
@@ -627,7 +661,7 @@ class Transaction(object):
if ownpending:
pending = []
- locked[pkg] = True
+ locked[pkg] = (LOCKED_REMOVE, None)
changeset.set(pkg, REMOVE)
isinst = changeset.installed
@@ -1140,22 +1174,22 @@ class Transaction(object):
if op is KEEP:
if pkg in changeset:
del changeset[pkg]
- locked[pkg] = True
+ locked[pkg] = (LOCKED_KEEP, None)
elif op is INSTALL:
if not isinst(pkg) and pkg in locked:
raise Failed, _("Can't install %s: it's locked") % pkg
changeset.set(pkg, INSTALL)
- locked[pkg] = True
+ locked[pkg] = (LOCKED_INSTALL, None)
elif op is REMOVE:
if isinst(pkg) and pkg in locked:
raise Failed, _("Can't remove %s: it's locked") % pkg
changeset.set(pkg, REMOVE)
- locked[pkg] = True
+ locked[pkg] = (LOCKED_REMOVE, None)
elif op is REINSTALL:
if pkg in locked:
raise Failed, _("Can't reinstall %s: it's locked")%pkg
changeset.set(pkg, INSTALL, force=True)
- locked[pkg] = True
+ locked[pkg] = (LOCKED_INSTALL, None)
elif op is UPGRADE:
pass
--
1.8.1.2

View File

@@ -1,45 +0,0 @@
backends/rpm: add support for setting dependency flags
This is useful for OpenEmbedded so that we can do the equivalent of
the --nolinktos and --noparentdirs rpm command line options.
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
[sgw - Added try/catch for rpm4 since it does not have setDFlags() API]
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Index: smart-1.4.1/smart/backends/rpm/pm.py
===================================================================
--- smart-1.4.1.orig/smart/backends/rpm/pm.py
+++ smart-1.4.1/smart/backends/rpm/pm.py
@@ -106,6 +106,26 @@ class RPMPackageManager(PackageManager):
flags |= rpm.RPMTRANS_FLAG_TEST
ts.setFlags(flags)
+ try:
+ dflags = ts.setDFlags(0)
+ if sysconf.get("rpm-noupgrade", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOUPGRADE
+ if sysconf.get("rpm-norequires", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOREQUIRES
+ if sysconf.get("rpm-noconflicts", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOCONFLICTS
+ if sysconf.get("rpm-noobsoletes", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOOBSOLETES
+ if sysconf.get("rpm-noparentdirs", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOPARENTDIRS
+ if sysconf.get("rpm-nolinktos", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOLINKTOS
+ if sysconf.get("rpm-nosuggest", False):
+ dflags |= rpm.RPMDEPS_FLAG_NOSUGGEST
+ ts.setDFlags(dflags)
+ except AttributeError, ae:
+ pass
+
# Set rpm verbosity level.
levelname = sysconf.get('rpm-log-level')
level = {

View File

@@ -1,35 +0,0 @@
From a17998b6be3319ae476a64f366737bc267a53a8a Mon Sep 17 00:00:00 2001
From: Robert Yang <liezhi.yang@windriver.com>
Date: Mon, 16 Sep 2013 05:54:13 -0400
Subject: [PATCH] fetcher.py: truncate the filename to meet NAME_MAX
The function getLocalPath() converts the filepath into the filename,
there would be a "File name too long" error when len(filename) >
NAME_MAX, truncate it to meet NAME_MAX will fix the problem.
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
smart/fetcher.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/smart/fetcher.py b/smart/fetcher.py
--- a/smart/fetcher.py
+++ b/smart/fetcher.py
@@ -139,6 +139,14 @@ class Fetcher(object):
filename = os.path.basename(path)
if self._localpathprefix:
filename = self._localpathprefix+filename
+ # pathconf requires the path existed
+ if not os.path.exists(self._localdir):
+ os.makedirs(self._localdir)
+ name_max = os.pathconf(self._localdir, 'PC_NAME_MAX')
+ # The length of the filename should be less than NAME_MAX
+ if len(filename) > name_max:
+ iface.debug(_("Truncate %s to %s") % (filename, filename[-name_max:]))
+ filename = filename[-name_max:]
return os.path.join(self._localdir, filename)
def setForceCopy(self, value):
--
1.7.10.4

View File

@@ -1,70 +0,0 @@
Add exclude-packages flag support
Allow configuring specific packages to be excluded. This will allow
users to specify things NOT to install, and if they are attempted an
error will be generated.
Upstream-Status: Pending
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Index: smart-1.4.1/smart/const.py
===================================================================
--- smart-1.4.1.orig/smart/const.py
+++ smart-1.4.1/smart/const.py
@@ -70,6 +70,7 @@ DATADIR = "/var/lib/smart/"
USERDATADIR = "~/.smart/"
CONFFILE = "config"
+LOCKED_EXCLUDE = Enum('LOCKED_EXCLUDE')
LOCKED_INSTALL = Enum('LOCKED_INSTALL')
LOCKED_REMOVE = Enum('LOCKED_REMOVE')
LOCKED_CONFLICT = Enum('LOCKED_CONFLICT')
Index: smart-1.4.1/smart/transaction.py
===================================================================
--- smart-1.4.1.orig/smart/transaction.py
+++ smart-1.4.1/smart/transaction.py
@@ -19,7 +19,7 @@
# along with Smart Package Manager; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP, LOCKED_INSTALL, LOCKED_CONFLICT, LOCKED_CONFLICT_BY, LOCKED_NO_COEXIST, LOCKED_SYSCONF, LOCKED_REMOVE
+from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP, LOCKED_EXCLUDE, LOCKED_INSTALL, LOCKED_CONFLICT, LOCKED_CONFLICT_BY, LOCKED_NO_COEXIST, LOCKED_SYSCONF, LOCKED_REMOVE
from smart.cache import PreRequires, Package
from smart import *
@@ -29,7 +29,9 @@ def lock_reason(pkg, lockvalue):
except TypeError:
reason = None
lockvalue = None
- if reason == LOCKED_INSTALL:
+ if reason == LOCKED_EXCLUDE:
+ return _("%s is to be excluded") % pkg
+ elif reason == LOCKED_INSTALL:
return _("%s is to be installed") % pkg
elif reason == LOCKED_CONFLICT:
return _("%s conflicts with %s") % (pkg, otherpkg)
@@ -210,6 +212,10 @@ class Policy(object):
self._sysconflocked.append(pkg)
self._locked[pkg] = (LOCKED_SYSCONF, None)
+ for pkg in pkgconf.filterByFlag("exclude-packages", cache.getPackages()):
+ if pkg not in self._locked:
+ self._locked[pkg] = (LOCKED_EXCLUDE, None)
+
def runFinished(self):
self._priorities.clear()
for pkg in self._sysconflocked:
Index: smart-1.4.1/smart/commands/flag.py
===================================================================
--- smart-1.4.1.orig/smart/commands/flag.py
+++ smart-1.4.1/smart/commands/flag.py
@@ -47,6 +47,8 @@ Currently known flags are:
multi-version - Flagged packages may have more than one version
installed in the system at the same time
(backend dependent).
+ exclude-packages - Flagged packages will be excluded, if they are
+ required, an error will be generated.
ignore-recommends - Flagged packages will not be installed, if
they are only recommended by a package to be
installed rather than required.

View File

@@ -1,60 +0,0 @@
Add ignore-recommends flag support
Allow configuring recommends on specific packages to be ignored.
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
smart/commands/flag.py | 3 +++
smart/transaction.py | 7 ++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/smart/commands/flag.py b/smart/commands/flag.py
index 8b90496..191bb11 100644
--- a/smart/commands/flag.py
+++ b/smart/commands/flag.py
@@ -47,6 +47,9 @@ Currently known flags are:
multi-version - Flagged packages may have more than one version
installed in the system at the same time
(backend dependent).
+ ignore-recommends - Flagged packages will not be installed, if
+ they are only recommended by a package to be
+ installed rather than required.
security - Flagged packages are updates for security errata.
bugfix - Flagged packages are updates for bugfix errata.
diff --git a/smart/transaction.py b/smart/transaction.py
index dd9aa38..38eabae 100644
--- a/smart/transaction.py
+++ b/smart/transaction.py
@@ -596,12 +596,17 @@ class Transaction(object):
# Install packages required by this one.
for req in pkg.requires + pkg.recommends:
+ reqrequired = req in pkg.requires
+
# Check if someone is already providing it.
prvpkgs = {}
lockedpkgs = {}
found = False
for prv in req.providedby:
for prvpkg in prv.packages:
+ if not reqrequired:
+ if pkgconf.testFlag("ignore-recommends", prvpkg):
+ continue
if isinst(prvpkg):
found = True
break
@@ -620,7 +625,7 @@ class Transaction(object):
if not prvpkgs:
# No packages provide it at all. Give up.
- if req in pkg.requires:
+ if reqrequired:
reasons = []
for prv in req.providedby:
for prvpkg in prv.packages:
--
1.8.1.2

View File

@@ -8,170 +8,8 @@ Upstream-Status: Pending
Signed-off-by: Bogdan Marinescu <bogdan.a.marinescu@intel.com>
diff --git a/smart/commands/channel.py b/smart/commands/channel.py
index aa76f91..63fbb35 100644
--- a/smart/commands/channel.py
+++ b/smart/commands/channel.py
@@ -157,7 +157,17 @@ def main(ctrl, opts):
opts.show is None and opts.yaml is None):
iface.warning(_("Can't edit channels information."))
raise Error, _("Configuration is in readonly mode.")
-
+
+ # Argument check
+ opts.check_args_of_option("set", -1)
+ opts.check_args_of_option("remove", -1)
+ opts.check_args_of_option("edit", 0)
+ opts.check_args_of_option("enable", -1)
+ opts.check_args_of_option("disable", -1)
+ opts.ensure_action("channel", ["add", "set", "remove", "remove_all",
+ "list", "show", "yaml", "enable", "disable"])
+ opts.check_remaining_args()
+
if opts.add is not None:
if not opts.add and opts.args == ["-"]:
newchannels = []
diff --git a/smart/commands/check.py b/smart/commands/check.py
index b08608a..506e852 100644
--- a/smart/commands/check.py
+++ b/smart/commands/check.py
@@ -72,6 +72,9 @@ def parse_options(argv):
def main(ctrl, opts, reloadchannels=True):
+ # Argument check
+ opts.check_args_of_option("channels", 1)
+
if sysconf.get("auto-update"):
from smart.commands import update
updateopts = update.parse_options([])
diff --git a/smart/commands/config.py b/smart/commands/config.py
index dd50dee..4fe4366 100644
--- a/smart/commands/config.py
+++ b/smart/commands/config.py
@@ -80,6 +80,12 @@ def main(ctrl, opts):
globals["false"] = False
globals["no"] = False
+ # Check arguments
+ opts.check_args_of_option("set", -1)
+ opts.check_args_of_option("remove", -1)
+ opts.ensure_action("config", ["set", "show", "yaml", "remove"])
+ opts.check_remaining_args()
+
if opts.set:
for opt in opts.set:
m = SETRE.match(opt)
diff --git a/smart/commands/download.py b/smart/commands/download.py
index 6837993..b853c61 100644
--- a/smart/commands/download.py
+++ b/smart/commands/download.py
@@ -81,6 +81,14 @@ def parse_options(argv):
def main(ctrl, opts):
+ # Argument check
+ opts.check_args_of_option("target", 1)
+ opts.check_args_of_option("output", 1)
+ opts.check_args_of_option("from_urls", -1)
+ opts.check_args_of_option("from_metalink", -1)
+ if not opts.args and not opts.from_metalink and not opts.from_urls:
+ raise Error, _("no package(s) given")
+
packages = []
if opts.args:
if sysconf.get("auto-update"):
diff --git a/smart/commands/info.py b/smart/commands/info.py
index 12f74f0..59fbe98 100644
--- a/smart/commands/info.py
+++ b/smart/commands/info.py
@@ -58,6 +58,10 @@ def parse_options(argv):
def main(ctrl, opts, reloadchannels=True):
+ # Argument check
+ if not opts.args:
+ raise Error, _("No package(s) given")
+
if sysconf.get("auto-update"):
from smart.commands import update
updateopts = update.parse_options([])
diff --git a/smart/commands/install.py b/smart/commands/install.py
index 8a45954..590222c 100644
--- a/smart/commands/install.py
+++ b/smart/commands/install.py
@@ -76,6 +76,10 @@ def parse_options(argv):
def main(ctrl, opts):
+ # Argument check
+ if not opts.args:
+ raise Error, _("no package(s) given")
+
if opts.explain:
sysconf.set("explain-changesets", True, soft=True)
diff --git a/smart/commands/reinstall.py b/smart/commands/reinstall.py
index e59d896..32da3e6 100644
--- a/smart/commands/reinstall.py
+++ b/smart/commands/reinstall.py
@@ -68,7 +68,11 @@ def parse_options(argv):
return opts
def main(ctrl, opts):
-
+
+ # Argument check
+ if not opts.args:
+ raise Error, _("no package(s) given")
+
if opts.explain:
sysconf.set("explain-changesets", True, soft=True)
diff --git a/smart/commands/remove.py b/smart/commands/remove.py
index b4823a6..acd3bbd 100644
--- a/smart/commands/remove.py
+++ b/smart/commands/remove.py
@@ -74,6 +74,10 @@ def parse_options(argv):
def main(ctrl, opts):
+ # Argument check
+ if not opts.args:
+ raise Error, _("no package(s) given")
+
if opts.explain:
sysconf.set("explain-changesets", True, soft=True)
diff --git a/smart/commands/search.py b/smart/commands/search.py
index 0d0b573..44806b8 100644
--- a/smart/commands/search.py
+++ b/smart/commands/search.py
@@ -44,6 +44,8 @@ def option_parser():
def parse_options(argv):
opts = query.parse_options(argv, usage=USAGE, \
description=DESCRIPTION, examples=EXAMPLES)
+ if not argv:
+ raise Error, _("Search expression not specified")
opts.name = opts.args
opts.summary = opts.args
opts.description = opts.args
diff --git a/smart/commands/upgrade.py b/smart/commands/upgrade.py
index ec86290..7e290d8 100644
--- a/smart/commands/upgrade.py
+++ b/smart/commands/upgrade.py
@@ -91,6 +91,9 @@ def parse_options(argv):
def main(ctrl, opts):
+ # Argument check
+ opts.check_args_of_option("flag", 1)
+
if opts.explain:
sysconf.set("explain-changesets", True, soft=True)
diff --git a/smart/util/optparse.py b/smart/util/optparse.py
index 4a3d3a8..279b0bf 100644
index 6fff1bc..f445a3b 100644
--- a/smart/util/optparse.py
+++ b/smart/util/optparse.py
@@ -70,6 +70,8 @@ import sys, os
@@ -183,7 +21,7 @@ index 4a3d3a8..279b0bf 100644
def _repr(self):
return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
@@ -708,6 +710,12 @@ class Option:
@@ -710,6 +712,12 @@ class Option:
self.action, self.dest, opt, value, values, parser)
def take_action(self, action, dest, opt, value, values, parser):
@@ -196,7 +34,7 @@ index 4a3d3a8..279b0bf 100644
if action == "store":
setattr(values, dest, value)
elif action == "store_const":
@@ -819,6 +827,54 @@ class Values:
@@ -821,6 +829,54 @@ class Values:
setattr(self, attr, value)
return getattr(self, attr)

View File

@@ -1,28 +0,0 @@
smart - backends/rmp/metadata.py: Fix incorrect call to the match function
The match function should take three parameters, name, comparison, version...
The original code was passing it a reference to the object holding the data
instead, which caused the comparison in match to always fail.
Upstream-Status: Pending
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
--- a/smart/backends/rpm/metadata.py
+++ b/smart/backends/rpm/metadata.py
@@ -332,13 +332,13 @@
reqargs = [x for x in reqdict
if not ((x[2] is None or "=" in x[2]) and
(RPMProvides, x[1], x[3]) in prvdict or
- system_provides.match(*x[:3]))]
+ system_provides.match(x[1], x[2], x[3]))]
reqargs = collapse_libc_requires(reqargs)
recargs = [x for x in recdict
if not ((x[2] is None or "=" in x[2]) and
(RPMProvides, x[1], x[3]) in prvdict or
- system_provides.match(*x[:3]))]
+ system_provides.match(x[1], x[2], x[3]))]
prvargs = prvdict.keys()
cnfargs = cnfdict.keys()

View File

@@ -1,22 +0,0 @@
To fix some multilib issues, change the way the RPM backend decides
if two packages can coexist: if they have a different architecture,
automatically assume that they can coexist (which is fundamental for
multilib).
Upstream-Status: Pending
Signed-off-by: Bogdan Marinescu <bogdan.a.marinescu@intel.com>
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
index 6e83d40..7140c1b 100644
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -228,6 +228,8 @@ class RPMPackage(Package):
return False
selfver, selfarch = splitarch(self.version)
otherver, otherarch = splitarch(other.version)
+ if selfarch != otherarch:
+ return True
selfcolor = getArchColor(selfarch)
othercolor = getArchColor(otherarch)
if (selfcolor and othercolor and selfcolor != othercolor and

View File

@@ -1,27 +0,0 @@
backends/rpm: implement rpm-extra-macros option
Allow defining extra macros in the smart configuration to be passed
to rpm before opening the database.
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
index b9e9cb2..234c844 100644
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -53,6 +53,10 @@ def rpm_join_dbpath(root, dbpath):
return os.path.join(root, dbpath)
def getTS(new=False):
+ if sysconf.get("rpm-extra-macros"):
+ for key, value in sysconf.get("rpm-extra-macros").items():
+ rpm.addMacro(key, str(value))
+
rpm_root = os.path.abspath(sysconf.get("rpm-root", "/"))
if not hasattr(getTS, "ts") or getTS.root != rpm_root:
getTS.root = rpm_root
--
1.7.9.5

View File

@@ -1,26 +0,0 @@
backends/rpm: fix parsing of rpm-md metadata
If assertions are disabled then the queue.pop() wasn't being executed,
leading to requires, recommends etc. not being read properly.
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
diff --git a/smart/backends/rpm/metadata.py b/smart/backends/rpm/metadata.py
index 2c54f39..dc9df22 100644
--- a/smart/backends/rpm/metadata.py
+++ b/smart/backends/rpm/metadata.py
@@ -188,7 +188,8 @@ class RPMMetaDataLoader(Loader):
elif event == "end":
- assert queue.pop() is elem
+ popped = queue.pop()
+ assert popped is elem
if skip:
if tag == skip:
--
1.7.9.5

View File

@@ -1,80 +0,0 @@
Fix smart RPM backend to handle rpm-dbpath/rpm-root properly
Don't assume that if the dbpath starts with / that it is an absolute
path. This matches the behaviour of rpm itself. (If the root path is
specified and does not start with /, rpm will prepend the root path
twice and fail).
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
index 7092332..0489e11 100644
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -46,6 +46,12 @@ __all__ = ["RPMPackage", "RPMProvides", "RPMNameProvides", "RPMPreRequires",
"rpm", "getTS", "getArchScore", "getArchColor", "system_provides",
"collapse_libc_requires"]
+def rpm_join_dbpath(root, dbpath):
+ if dbpath.startswith('/') and root:
+ return os.path.join(root, dbpath[1:])
+ else:
+ return os.path.join(root, dbpath)
+
def getTS(new=False):
rpm_root = os.path.abspath(sysconf.get("rpm-root", "/"))
if not hasattr(getTS, "ts") or getTS.root != rpm_root:
@@ -56,7 +62,7 @@ def getTS(new=False):
#if not sysconf.get("rpm-check-signatures", False):
# getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm")
- dbdir = os.path.join(getTS.root, rpm_dbpath)
+ dbdir = rpm_join_dbpath(getTS.root, rpm_dbpath)
if not os.path.isdir(dbdir):
try:
os.makedirs(dbdir)
diff --git a/smart/channels/rpm_sys.py b/smart/channels/rpm_sys.py
index efcb10e..b9fda27 100644
--- a/smart/channels/rpm_sys.py
+++ b/smart/channels/rpm_sys.py
@@ -20,7 +20,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
from smart.backends.rpm.header import RPMDBLoader
-from smart.backends.rpm.base import getTS
+from smart.backends.rpm.base import getTS, rpm_join_dbpath
from smart.channel import PackageChannel
from smart import *
import os
@@ -32,9 +32,9 @@ class RPMSysChannel(PackageChannel):
def fetch(self, fetcher, progress):
getTS() # Make sure the db exists.
- path = os.path.join(sysconf.get("rpm-root", "/"),
- sysconf.get("rpm-dbpath", "var/lib/rpm"),
- "Packages")
+ dbdir = rpm_join_dbpath(sysconf.get("rpm-root", "/"),
+ sysconf.get("rpm-dbpath", "var/lib/rpm"))
+ path = os.path.join(dbdir, "Packages")
digest = os.path.getmtime(path)
if digest == self._digest:
return True
diff --git a/smart/plugins/detectsys.py b/smart/plugins/detectsys.py
index 2cd49ad..3959d07 100644
--- a/smart/plugins/detectsys.py
+++ b/smart/plugins/detectsys.py
@@ -20,10 +20,11 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
from smart import *
+from smart.backends.rpm.base import rpm_join_dbpath
import os
def detectRPMSystem():
- dir = os.path.join(sysconf.get("rpm-root", "/"),
+ dir = rpm_join_dbpath(sysconf.get("rpm-root", "/"),
sysconf.get("rpm-dbpath", "var/lib/rpm"))
file = os.path.join(dir, "Packages")
if os.path.exists(file):

View File

@@ -1,30 +0,0 @@
backends/rpm: remove creation of /var/tmp
This doesn't appear to be needed, and breaks installation of base-files
in OpenEmbedded (since that is a symlink installed as part of the
package).
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
index 234c844..127354d 100644
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -82,12 +82,6 @@ def getTS(new=False):
else:
iface.warning(_("Initialized new rpm database at %s")
% getTS.root)
- tmpdir = os.path.join(getTS.root, "var/tmp")
- if not os.path.isdir(tmpdir):
- try:
- os.makedirs(tmpdir)
- except OSError:
- pass
if new:
if sysconf.get("rpm-dbpath"):
rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))
--
1.7.9.5

View File

@@ -1,86 +0,0 @@
Print a more friendly error if YAML output is requested without PyYAML
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
diff --git a/smart/commands/channel.py b/smart/commands/channel.py
index 63fbb35..108f3f1 100644
--- a/smart/commands/channel.py
+++ b/smart/commands/channel.py
@@ -339,7 +339,10 @@ def main(ctrl, opts):
print
if opts.yaml is not None:
- import yaml
+ try:
+ import yaml
+ except ImportError:
+ raise Error, _("Please install PyYAML in order to use this function")
yamlchannels = {}
for alias in (opts.yaml or sysconf.get("channels", ())):
channel = sysconf.get(("channels", alias))
diff --git a/smart/commands/config.py b/smart/commands/config.py
index 4fe4366..aa1db78 100644
--- a/smart/commands/config.py
+++ b/smart/commands/config.py
@@ -137,7 +137,10 @@ def main(ctrl, opts):
pprint.pprint(sysconf.get((), hard=True))
if opts.yaml is not None:
- import yaml
+ try:
+ import yaml
+ except ImportError:
+ raise Error, _("Please install PyYAML in order to use this function")
if opts.yaml:
marker = object()
for opt in opts.yaml:
diff --git a/smart/commands/flag.py b/smart/commands/flag.py
index ed18999..8b90496 100644
--- a/smart/commands/flag.py
+++ b/smart/commands/flag.py
@@ -138,7 +138,10 @@ def main(ctrl, opts):
print
if opts.yaml is not None:
- import yaml
+ try:
+ import yaml
+ except ImportError:
+ raise Error, _("Please install PyYAML in order to use this function")
yamlflags = {}
for flag in opts.yaml or pkgconf.getFlagNames():
flag = flag.strip()
diff --git a/smart/commands/mirror.py b/smart/commands/mirror.py
index ca50a95..f7b019d 100644
--- a/smart/commands/mirror.py
+++ b/smart/commands/mirror.py
@@ -218,7 +218,10 @@ def main(ctrl, opts):
print
if opts.yaml:
- import yaml
+ try:
+ import yaml
+ except ImportError:
+ raise Error, _("Please install PyYAML in order to use this function")
yamlmirrors = {}
mirrors = sysconf.get("mirrors", ())
for origin in mirrors:
diff --git a/smart/commands/priority.py b/smart/commands/priority.py
index d850d29..441ea32 100644
--- a/smart/commands/priority.py
+++ b/smart/commands/priority.py
@@ -117,7 +117,10 @@ def main(ctrl, opts):
print
elif opts.yaml:
- import yaml
+ try:
+ import yaml
+ except ImportError:
+ raise Error, _("Please install PyYAML in order to use this function")
yamlpriorities = {}
priorities = sysconf.get("package-priorities", {})
for name in opts.args or priorities:

View File

@@ -6,41 +6,54 @@ Upstream-Status: Pending
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
diff -ur smart-1.4.1.orig/smart/backends/rpm/base.py smart-1.4.1/smart/backends/rpm/base.py
--- smart-1.4.1.orig/smart/backends/rpm/base.py 2012-10-04 11:22:11.229351164 -0500
+++ smart-1.4.1/smart/backends/rpm/base.py 2012-10-04 11:22:44.820170786 -0500
@@ -53,8 +53,8 @@
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -63,11 +63,11 @@ def getTS(new=False):
if sysconf.get("rpm-dbpath"):
rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))
getTS.ts = rpm.ts(getTS.root)
- if not sysconf.get("rpm-check-signatures", False):
- getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
- if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
- getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
- else:
- raise Error, _("rpm requires checking signatures")
+ #if not sysconf.get("rpm-check-signatures", False):
+ # getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+ # if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
+ # getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+ # else:
+ # raise Error, _("rpm requires checking signatures")
rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm")
dbdir = os.path.join(getTS.root, rpm_dbpath)
dbdir = rpm_join_dbpath(getTS.root, rpm_dbpath)
if not os.path.isdir(dbdir):
@@ -82,8 +82,8 @@
@@ -89,11 +89,11 @@ def getTS(new=False):
if sysconf.get("rpm-dbpath"):
rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))
ts = rpm.ts(getTS.root)
- if not sysconf.get("rpm-check-signatures", False):
- ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
- if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
- ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
- else:
- raise Error, _("rpm requires checking signatures")
+ #if not sysconf.get("rpm-check-signatures", False):
+ # ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+ # if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
+ # ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+ # else:
+ # raise Error, _("rpm requires checking signatures")
return ts
else:
return getTS.ts
diff -ur smart-1.4.1.orig/smart/plugins/yumchannelsync.py smart-1.4.1/smart/plugins/yumchannelsync.py
--- smart-1.4.1.orig/smart/plugins/yumchannelsync.py 2010-12-06 03:11:05.000000000 -0600
+++ smart-1.4.1/smart/plugins/yumchannelsync.py 2012-10-04 11:23:09.799350924 -0500
@@ -56,7 +56,8 @@
diff --git a/smart/plugins/yumchannelsync.py b/smart/plugins/yumchannelsync.py
--- a/smart/plugins/yumchannelsync.py
+++ b/smart/plugins/yumchannelsync.py
@@ -56,8 +56,8 @@ def _getreleasever():
rpmroot = sysconf.get("rpm-root", "/")
ts = rpmUtils.transaction.initReadOnlyTransaction(root=rpmroot)
- ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
+ #ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
+ ts.pushVSFlags(~(rpm._RPMVSF_NODIGESTS))
- if hasattr(rpm, '_RPMVSF_NOSIGNATURES') and hasattr(rpm, '_RPMVSF_NODIGESTS'):
- ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
+ #if hasattr(rpm, '_RPMVSF_NOSIGNATURES') and hasattr(rpm, '_RPMVSF_NODIGESTS'):
+ # ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
releasever = None
# HACK: we're hard-coding the most used distros, will add more if needed
idx = ts.dbMatch('provides', 'fedora-release')