Add Gentoo support to bindep
Equery is used to query Gentoo's package database. An exit code of 3 means the package is not installed or it is an invalid package atom (doesn't exist for example). We are able to rely on the exit code for package install status and just output the package version, if it's installed. We do not output revision information as it is not needed here. We also add support for gentoo categories in the package name by allowing a '/' in the package name. This is needed for package names that exist in multiple categories. For instance, curl could map to 'dev-haskell/curl' or 'net-misc/curl'. Without this change we would not be able to specify which to install. I've also included testing for '/' in the package name. Change-Id: Id87038a5599824befae627d67a03f59b70e19257
This commit is contained in:
parent
a0f517c435
commit
03288d3263
|
@ -45,7 +45,7 @@ rule = <name>:name selector?:selector version?:version ('\n'|comment) -> (
|
|||
name, selector or [], version or [])
|
||||
lowercase = ('a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'
|
||||
|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z')
|
||||
name = letterOrDigit:start (letterOrDigit|'.'|'+'|'-')+:rest
|
||||
name = letterOrDigit:start (letterOrDigit|'.'|'+'|'-'|'/')+:rest
|
||||
ws = ' '+
|
||||
profile = ('!'?:neg <(lowercase|digit|':'|'-')+>:name) -> (neg!='!', name)
|
||||
selector = ws '[' profile:p1 (ws profile)*:p2 ']' -> [p1] + p2
|
||||
|
@ -143,6 +143,9 @@ class Depends(object):
|
|||
elif distro in ["centos", "fedora"]:
|
||||
atoms.add("rpm")
|
||||
self.platform = Rpm()
|
||||
elif distro in ["gentoo"]:
|
||||
atoms.add("emerge")
|
||||
self.platform = Emerge()
|
||||
return ["platform:%s" % (atom,) for atom in sorted(atoms)]
|
||||
|
||||
|
||||
|
@ -208,6 +211,30 @@ class Rpm(Platform):
|
|||
return elements[1]
|
||||
|
||||
|
||||
class Emerge(Platform):
|
||||
"""emerge specific implementation.
|
||||
|
||||
This currently shells out to equery, it could be changed to eix to be
|
||||
faster but that would add another dependency and eix's cache would need to
|
||||
be updated before this is run.
|
||||
"""
|
||||
|
||||
def get_pkg_version(self, pkg_name):
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
['equery', 'l', '--format=\'$version\'', pkg_name],
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
if e.returncode == 3:
|
||||
return None
|
||||
raise
|
||||
# output looks like
|
||||
# version
|
||||
output = output.strip()
|
||||
elements = output.split(' ')
|
||||
return elements[0]
|
||||
|
||||
|
||||
def _eval_diff(operator, diff):
|
||||
"""Return the boolean result for operator given diff.
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ from testtools import TestCase
|
|||
from bindep.depends import _eval
|
||||
from bindep.depends import Depends
|
||||
from bindep.depends import Dpkg
|
||||
from bindep.depends import Emerge
|
||||
from bindep.depends import Platform
|
||||
from bindep.depends import Rpm
|
||||
|
||||
|
@ -189,6 +190,7 @@ class TestDepends(TestCase):
|
|||
depends = Depends(dedent("""\
|
||||
foo
|
||||
bar [something]
|
||||
category/packagename # for gentoo
|
||||
baz [platform:this platform:that-those]
|
||||
quux [anotherthing !nothing] <=12
|
||||
womp # and a comment
|
||||
|
@ -196,7 +198,7 @@ class TestDepends(TestCase):
|
|||
|
||||
# all's ok? good then
|
||||
"""))
|
||||
self.assertEqual(len(depends.active_rules(['default'])), 2)
|
||||
self.assertEqual(len(depends.active_rules(['default'])), 3)
|
||||
|
||||
def test_parser_invalid(self):
|
||||
self.assertRaises(ometa.runtime.ParseError,
|
||||
|
@ -249,6 +251,48 @@ class TestDpkg(TestCase):
|
|||
self.assertEqual("4.0.0-0ubuntu1", platform.get_pkg_version("foo"))
|
||||
|
||||
|
||||
class TestEmerge(TestCase):
|
||||
|
||||
def test_not_installed(self):
|
||||
platform = Emerge()
|
||||
mocker = mox.Mox()
|
||||
mocker.StubOutWithMock(subprocess, "check_output")
|
||||
subprocess.check_output(
|
||||
['equery', 'l', '--format=\'$version\'', 'foo'],
|
||||
stderr=subprocess.STDOUT).AndRaise(
|
||||
subprocess.CalledProcessError(3, [], ''))
|
||||
mocker.ReplayAll()
|
||||
self.addCleanup(mocker.VerifyAll)
|
||||
self.addCleanup(mocker.UnsetStubs)
|
||||
self.assertEqual(None, platform.get_pkg_version("foo"))
|
||||
|
||||
def test_unknown_package(self):
|
||||
platform = Emerge()
|
||||
mocker = mox.Mox()
|
||||
mocker.StubOutWithMock(subprocess, "check_output")
|
||||
subprocess.check_output(
|
||||
['equery', 'l', '--format=\'$version\'', 'foo'],
|
||||
stderr=subprocess.STDOUT).AndRaise(
|
||||
subprocess.CalledProcessError(3, [], ''))
|
||||
mocker.ReplayAll()
|
||||
self.addCleanup(mocker.VerifyAll)
|
||||
self.addCleanup(mocker.UnsetStubs)
|
||||
self.assertEqual(None, platform.get_pkg_version("foo"))
|
||||
|
||||
def test_installed_version(self):
|
||||
platform = Emerge()
|
||||
mocker = mox.Mox()
|
||||
mocker.StubOutWithMock(subprocess, "check_output")
|
||||
subprocess.check_output(
|
||||
['equery', 'l', '--format=\'$version\'', 'foo'],
|
||||
stderr=subprocess.STDOUT).AndReturn(
|
||||
"4.0.0\n")
|
||||
mocker.ReplayAll()
|
||||
self.addCleanup(mocker.VerifyAll)
|
||||
self.addCleanup(mocker.UnsetStubs)
|
||||
self.assertEqual("4.0.0", platform.get_pkg_version("foo"))
|
||||
|
||||
|
||||
class TestRpm(TestCase):
|
||||
|
||||
# NOTE: test_not_installed is not implemented as rpm seems to only be aware
|
||||
|
|
Loading…
Reference in New Issue