Source code for core.cli.dependencies

"""
VIKI: more than a GUI for ROS, https://github.com/UT-RAM/viki 
version: 0.2 - Alice
copyright: Robin Hoogervorst, Alex Kamphuis, Cees Trouwborst, 2016 
licensed under the MIT License
"""

__author__ = 'robin'

"""
    Python file with a set of functions that handles basically all dependency management concerning ROS for viki

    A couple of kinds of dependencies:
    - First level dependencies are the dependencies of ROS packages that are needed directly for modules
    - Second level dependencies are dependencies of ROS packages, these can be
        - System level, to be installed with rosdep
        - ROS package leven, to be installed (parsed, pulled, etc.) with rospack
"""

from core.backend import scan
from viki_config import VikiConfig
import os
import subprocess


[docs]def check_installed_packages(): """ Checks for every module that is available, if the ROS packages needed for it are installed on the system :return: Boolean """ viki_config = VikiConfig() missing_packages = get_missing_packages(viki_config) if len(missing_packages) > 0: print "[WARNING] - There are missing packages for full VIKI support:" print "\n".join(map((lambda x: x['name']), missing_packages)) return False else: print "[OK] - All ROS package dependencies are met!" print "Note: only second level dependencies of already installed packages have been checked" return True
[docs]def get_installed_packages(): """ Gets the currently installed ROS packages and returns the names as an array :return: """ p = subprocess.Popen(['rospack', 'list-names'], stdout=subprocess.PIPE) packages = p.stdout.read().split() return packages
[docs]def get_missing_packages(viki_config): """ Looks for missing ROS packages that are defined as dependency in a module :return: List with names of the missing ROS packages """ installed_packages = get_installed_packages() modules_on_system = get_modules(viki_config) missing_packages = [] # if multiple modules use that package for module in modules_on_system: for package in module.package_dependencies: if not package['name'] in installed_packages: # Only add the package if it is not yet in the list if not package in missing_packages: missing_packages.append(package) module.missing_packages.append(package) return missing_packages
[docs]def get_second_level_dependencies(): p = subprocess.Popen(['rosdep', 'check', '--from-paths', '../'], stdout=subprocess.PIPE) output_string = p.stdout.read() print output_string if "All system dependencies" in output_string: return True return False
[docs]def install_second_level_dependencies(): p = subprocess.Popen(['rosdep', 'install', '--from-paths', '../'], stdout=subprocess.PIPE) print p.stdout.read() p.communicate()
[docs]def get_package_locations(): """ Uses 'rosdep db' and parsing to get the packages that we can install and the apt-get packages to install it :return: """ p = subprocess.Popen(['rosdep', 'db'], stdout=subprocess.PIPE) package_lines = p.stdout.read().splitlines() package_map = map((lambda x: x.split(' -> ')), package_lines) return package_map
[docs]def get_aptget_packages(ros_package_names): """ Returns installation candidates in a list [[ros_package_name, aptget_package], ...] This is based on the package names provided as the parameter :param ros_package_names: :return: """ apt_packages = get_package_locations() return filter((lambda x: x[0] in ros_package_names), apt_packages)
[docs]def start_aptget_installation(installation_candidates): """ Installs the packages that are provided in aa package list :param installation_candidates: :return: """ if (len(installation_candidates) == 0): return print "VIKI is going to install the following missing packages using apt-get: \n" print ",".join(map((lambda x: x[0]+" ("+x[1]+")"), installation_candidates)) print "It may ask for your sudo password, to be able to execute apt-get" input = None # Ask for confirmation, pressing enter yields Y as default while input not in ["y", "n", "Y", "N", ""]: print "Are you OK with that?" input = raw_input("[Y/n]: ") if input == "n" or input == "N": print "Aborting installation..." return command = ["sudo", "apt-get", "install"] + map((lambda x: x[1]), installation_candidates) subprocess.call(command)
[docs]def start_vcs_installation(missing_vcs_packages): if (len(missing_vcs_packages) == 0): return print "VIKI is going to install the following missing packages using version control: \n" print "\n".join(map((lambda x: x['name']+" ("+x['src']+")"), missing_vcs_packages)) input = None # Ask for confirmation, pressing enter yields Y as default while input not in ["y", "n", "Y", "N", ""]: print "Are you OK with that?" input = raw_input("[Y/n]: ") if input == "n" or input == "N": print "Aborting installation..." return if not os.path.exists("../viki_dependencies"): os.makedirs("../viki_dependencies") for package in missing_vcs_packages: command = [] if package['type'] == 'git': # TODO: This should install in the right VIKI directory, not 'viki_dependencies' command = ['git', 'clone', package['src'], '../viki_dependencies/'+package['name']] if command != []: subprocess.call(command) return None
[docs]def get_modules(viki_config): # TODO: Cache the module list in here, so that we don't scan all files again and again, and again... # if module_list == None: module_list = scan.getAvailableModules(viki_config) return module_list
[docs]def get_distinct_packages(modules): packages_per_module = filter((lambda x: len(x) > 0), map((lambda x: x.package_dependencies), modules)) packages_list = reduce((lambda x,y: x+y), packages_per_module) return list(set(packages_list)) # filter out duplicates..