Skip to content

Commit

Permalink
Merge pull request #616 from at-wat/alpine-installer
Browse files Browse the repository at this point in the history
Add alpine support
  • Loading branch information
tfoote authored May 6, 2019
2 parents 307b641 + 709d2ca commit 81e72cb
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/rosdep2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@


def create_default_installer_context(verbose=False):
from .platforms import alpine
from .platforms import arch
from .platforms import cygwin
from .platforms import debian
Expand All @@ -68,7 +69,7 @@ def create_default_installer_context(verbose=False):
from .platforms import slackware
from .platforms import source

platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat, slackware, freebsd]
platform_mods = [alpine, arch, cygwin, debian, gentoo, opensuse, osx, redhat, slackware, freebsd]
installer_mods = [source, pip, gem] + platform_mods

context = InstallerContext()
Expand Down
89 changes: 89 additions & 0 deletions src/rosdep2/platforms/alpine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright (c) 2018, SEQSENSE, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Author Atsushi Watanabe/atsushi.w@ieee.org

import os

from rospkg.os_detect import OS_ALPINE

from .pip import PIP_INSTALLER
from .source import SOURCE_INSTALLER
from ..installers import PackageManagerInstaller
from ..shell_utils import read_stdout

APK_INSTALLER = 'apk'


def register_installers(context):
context.set_installer(APK_INSTALLER, ApkInstaller())


def register_platforms(context):
context.add_os_installer_key(OS_ALPINE, APK_INSTALLER)
context.add_os_installer_key(OS_ALPINE, PIP_INSTALLER)
context.add_os_installer_key(OS_ALPINE, SOURCE_INSTALLER)
context.set_default_os_installer_key(OS_ALPINE, lambda self: APK_INSTALLER)


def apk_detect(pkgs, exec_fn=read_stdout):
"""
Given a list of packages, return a list of which are already installed.
:param exec_fn: function to execute Popen and read stdout (for testing)
"""

if not pkgs:
return []

cmd = ['apk', 'info', '--installed']
cmd.extend(pkgs)
std_out = exec_fn(cmd)

return std_out.splitlines()


class ApkInstaller(PackageManagerInstaller):

def __init__(self):
super(ApkInstaller, self).__init__(apk_detect)

def get_install_command(self, resolved, interactive=True, reinstall=False, quiet=False):
pkgs = self.get_packages_to_install(resolved, reinstall=reinstall)
if not pkgs:
return []

cmd = self.elevate_priv(['apk', 'add'])

if interactive:
cmd.append('--interactive')
if quiet:
cmd.append('--quiet')

cmd.extend(pkgs)

return [cmd]
91 changes: 91 additions & 0 deletions test/test_rosdep_alpine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright (c) 2018, SEQSENSE, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Author Atsushi Watanabe/atsushi.w@ieee.org

import os
import traceback
from mock import Mock, patch

import rospkg.os_detect


def get_test_dir():
# not used yet
return os.path.abspath(os.path.join(os.path.dirname(__file__), 'alpine'))


def test_apk_detect():
from rosdep2.platforms.alpine import apk_detect

m = Mock(return_value='')
expected = []
val = apk_detect([], exec_fn=m)
assert val == expected, 'Result was: %s' % val
m.assert_not_called()

m = Mock(return_value='')
expected = []
val = apk_detect(['a'], exec_fn=m)
assert val == expected, 'Result was: %s' % val
m.assert_called_with(['apk', 'info', '--installed', 'a'])

m = Mock(return_value='\n'.join(['a', 'b']))
expected = ['a', 'b']
val = apk_detect(['a', 'b'], exec_fn=m)
assert val == expected, 'Result was: %s' % val
m.assert_called_with(['apk', 'info', '--installed', 'a', 'b'])


def test_ApkInstaller():
from rosdep2.platforms.alpine import ApkInstaller

@patch.object(ApkInstaller, 'get_packages_to_install')
def test(mock_method):
installer = ApkInstaller()
mock_method.return_value = []
assert [] == installer.get_install_command(['nonexistingfakepackage'])

mock_method.return_value = ['a-dev', 'b-dev']

expected = [['sudo', '-H', 'apk', 'add', 'a-dev', 'b-dev']]
val = installer.get_install_command(['notused'], interactive=False, quiet=False)
assert val == expected, 'Result was: %s' % val

expected = [['sudo', '-H', 'apk', 'add', '--interactive', 'a-dev', 'b-dev']]
val = installer.get_install_command(['notused'], interactive=True, quiet=False)
assert val == expected, 'Result was: %s' % val

expected = [['sudo', '-H', 'apk', 'add', '--quiet', 'a-dev', 'b-dev']]
val = installer.get_install_command(['notused'], interactive=False, quiet=True)
assert val == expected, 'Result was: %s' % val

try:
test()
except AssertionError:
traceback.print_exc()
raise

0 comments on commit 81e72cb

Please sign in to comment.