Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect System package name by recipe settings (#5026) #5215

Merged
merged 8 commits into from Jul 1, 2019
Merged
68 changes: 65 additions & 3 deletions conans/client/tools/system_pm.py
Expand Up @@ -2,7 +2,7 @@
import sys

from conans.client.runner import ConanRunner
from conans.client.tools.oss import OSInfo
from conans.client.tools.oss import OSInfo, cross_building, get_cross_building_settings
from conans.client.tools.files import which
from conans.errors import ConanException
from conans.util.env_reader import get_env
Expand All @@ -11,7 +11,7 @@

class SystemPackageTool(object):

def __init__(self, runner=None, os_info=None, tool=None, recommends=False, output=None):
def __init__(self, runner=None, os_info=None, tool=None, recommends=False, output=None, settings=None):

uilianries marked this conversation as resolved.
Show resolved Hide resolved
self._output = default_output(output, 'conans.client.tools.system_pm.SystemPackageTool')
os_info = os_info or OSInfo()
Expand All @@ -20,6 +20,7 @@ def __init__(self, runner=None, os_info=None, tool=None, recommends=False, outpu
self._tool._sudo_str = self._get_sudo_str()
self._tool._runner = runner or ConanRunner(output=self._output)
self._tool._recommends = recommends
self._settings = settings

@staticmethod
def _get_sudo_str():
Expand Down Expand Up @@ -86,11 +87,12 @@ def update(self):
self._is_up_to_date = True
self._tool.update()

def install(self, packages, update=True, force=False):
def install(self, packages, update=True, force=False, platforms=None):
uilianries marked this conversation as resolved.
Show resolved Hide resolved
"""
Get the system package tool install command.
'"""
packages = [packages] if isinstance(packages, str) else list(packages)
packages = self._parse_packages_arch(packages, platforms)

mode = self._get_sysrequire_mode()

Expand All @@ -114,6 +116,18 @@ def install(self, packages, update=True, force=False):
self.update()
self._install_any(packages)

def _parse_packages_arch(self, packages, platforms):
uilianries marked this conversation as resolved.
Show resolved Hide resolved
if self._settings and cross_building(self._settings):
_, build_arch, _, host_arch = get_cross_building_settings(self._settings)
arch = host_arch or build_arch
parsed_packages = []
for package in packages:
if isinstance(package, str):
uilianries marked this conversation as resolved.
Show resolved Hide resolved
for package_name in package.split(" "):
parsed_packages.append(self._tool._parse_package(package_name, arch, platforms))
return parsed_packages
uilianries marked this conversation as resolved.
Show resolved Hide resolved
return packages

def _installed(self, packages):
if not packages:
return True
Expand All @@ -139,6 +153,9 @@ class BaseTool(object):
def __init__(self, output=None):
self._output = default_output(output, 'conans.client.tools.system_pm.BaseTool')

def _parse_package(self, package, arch, platforms):
return package


class NullTool(BaseTool):
def add_repository(self, repository, repo_key=None):
Expand Down Expand Up @@ -175,6 +192,23 @@ def installed(self, package_name):
exit_code = self._runner("dpkg-query -W -f='${Status}' %s | grep -q \"ok installed\"" % package_name, None)
return exit_code == 0

def _platforms(self):
uilianries marked this conversation as resolved.
Show resolved Hide resolved
return

def _parse_package(self, package, arch, platforms):
uilianries marked this conversation as resolved.
Show resolved Hide resolved
if platforms is None:
platforms = {"x86_64": "amd64",
"x86": "i386",
"ppc32": "powerpc",
"ppc64le": "ppc64el",
"armv7": "arm",
"armv7hf": "armhf",
"armv8": "arm64",
"s390x": "s390x"}
if arch in platforms:
return "%s:%s" % (package, platforms[arch])
return package


class YumTool(BaseTool):
def add_repository(self, repository, repo_key=None):
Expand All @@ -192,6 +226,20 @@ def installed(self, package_name):
exit_code = self._runner("rpm -q %s" % package_name, None)
return exit_code == 0

def _parse_package(self, package, arch, platforms):
if platforms is None:
platforms = {"x86_64": "x86_64",
"x86": "i?86",
"ppc32": "powerpc",
"ppc64le": "ppc64le",
"armv7": "armv7",
"armv7hf": "armv7hl",
"armv8": "aarch64",
"s390x": "s390x"}
if arch in platforms:
return "%s.%s" % (package, platforms[arch])
return package


class BrewTool(BaseTool):
def add_repository(self, repository, repo_key=None):
Expand Down Expand Up @@ -271,6 +319,13 @@ def installed(self, package_name):
exit_code = self._runner("pacman -Qi %s" % package_name, None)
return exit_code == 0

def _parse_package(self, package, arch, platforms):
if platforms is None:
platforms = {"x86": "lib32"}
if arch in platforms:
return "%s-%s" % (platforms[arch], package)
return package


class ZypperTool(BaseTool):
def add_repository(self, repository, repo_key=None):
Expand All @@ -287,6 +342,13 @@ def installed(self, package_name):
exit_code = self._runner("rpm -q %s" % package_name, None)
return exit_code == 0

def _parse_package(self, package, arch, platforms):
if platforms is None:
platforms = {"x86": "i586"}
if arch in platforms:
return "%s.%s" % (platforms[arch], package)
return package


def _run(runner, command, output, accepted_returns=None):
accepted_returns = accepted_returns or [0, ]
Expand Down
34 changes: 34 additions & 0 deletions conans/test/unittests/client/tools/system_pm_test.py
Expand Up @@ -14,6 +14,7 @@
from conans.errors import ConanException
from conans.test.unittests.util.tools_test import RunnerMock
from conans.test.utils.tools import TestBufferConanOutput
from conans.test.utils.conanfile import MockSettings


class SystemPackageToolTest(unittest.TestCase):
Expand Down Expand Up @@ -166,6 +167,15 @@ def system_package_tool_test(self):
spt.install("a_package", force=True)
self.assertEqual(runner.command_called, "sudo -A yum install -y a_package")

settings = MockSettings({"arch": "x86", "arch_build": "x86_64", "os": "Linux",
"os_build": "Linux"})
spt = SystemPackageTool(runner=runner, os_info=os_info, output=self.out,
settings=settings)
spt.install("a_package", force=False)
self.assertEqual(runner.command_called, "rpm -q a_package.i?86")
jgsogo marked this conversation as resolved.
Show resolved Hide resolved
spt.install("a_package", force=True)
self.assertEqual(runner.command_called, "sudo -A yum install -y a_package.i?86")

os_info.linux_distro = "debian"
spt = SystemPackageTool(runner=runner, os_info=os_info, output=self.out)
with self.assertRaises(ConanException):
Expand Down Expand Up @@ -235,6 +245,30 @@ def system_package_tool_test(self):
spt.update()
self.assertEqual(runner.command_called, "apt-get update")

for arch, distro_arch in {"x86_64": "", "x86": ":i386", "ppc32": ":powerpc",
"ppc64le": ":ppc64el", "armv7": ":arm", "armv7hf": ":armhf",
"armv8": ":arm64", "s390x": ":s390x"}.items():
settings = MockSettings({"arch": arch,
"arch_build": "x86_64",
"os": "Linux",
"os_build": "Linux"})
spt = SystemPackageTool(runner=runner, os_info=os_info, output=self.out,
settings=settings)
spt.install("a_package", force=True)
self.assertEqual(runner.command_called,
"apt-get install -y --no-install-recommends a_package%s" % distro_arch)

for arch, distro_arch in {"x86_64": "", "x86": ":all"}.items():
settings = MockSettings({"arch": arch,
"arch_build": "x86_64",
"os": "Linux",
"os_build": "Linux"})
spt = SystemPackageTool(runner=runner, os_info=os_info, output=self.out,
settings=settings)
spt.install("a_package", force=True, platforms={"x86": "all"})
self.assertEqual(runner.command_called,
"apt-get install -y --no-install-recommends a_package%s" % distro_arch)

os_info.is_macos = True
os_info.is_linux = False
os_info.is_windows = False
Expand Down