summaryrefslogtreecommitdiff
path: root/meta
diff options
context:
space:
mode:
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-devtools/python/python-smartpm/smart-conflict-provider.patch196
-rw-r--r--meta/recipes-devtools/python/python-smartpm_1.4.1.bb1
2 files changed, 197 insertions, 0 deletions
diff --git a/meta/recipes-devtools/python/python-smartpm/smart-conflict-provider.patch b/meta/recipes-devtools/python/python-smartpm/smart-conflict-provider.patch
new file mode 100644
index 0000000000..10a7447cb4
--- /dev/null
+++ b/meta/recipes-devtools/python/python-smartpm/smart-conflict-provider.patch
@@ -0,0 +1,196 @@
+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
+
diff --git a/meta/recipes-devtools/python/python-smartpm_1.4.1.bb b/meta/recipes-devtools/python/python-smartpm_1.4.1.bb
index 0cf3847c77..3e392311f3 100644
--- a/meta/recipes-devtools/python/python-smartpm_1.4.1.bb
+++ b/meta/recipes-devtools/python/python-smartpm_1.4.1.bb
@@ -26,6 +26,7 @@ SRC_URI = "\
file://smart-multilib-fixes.patch \
file://smart-yaml-error.patch \
file://smart-channelsdir.patch \
+ file://smart-conflict-provider.patch \
"
SRC_URI[md5sum] = "573ef32ba177a6b3c4bf7ef04873fcb6"