From ae5ebc063f8e1ed2d9f121f9cbbe0f588a594448 Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 26 Feb 2019 13:49:13 +0100 Subject: [PATCH 1/2] check for dependencies --- dependencies.txt | 9 +++++ src/giskardpy/utils.py | 77 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 dependencies.txt diff --git a/dependencies.txt b/dependencies.txt new file mode 100644 index 0000000000..3044e58c9c --- /dev/null +++ b/dependencies.txt @@ -0,0 +1,9 @@ +symengine>=0.3.1.dev1 +numpy==1.15.4 +urdfdom-py==0.4.0 +rosunit==1.14.4 +cython==0.26.1 +qpoases==3.1.0 +giskard_msgs==0.1.0 +py_trees_ros==0.5.14 +py_trees==0.6.1 \ No newline at end of file diff --git a/src/giskardpy/utils.py b/src/giskardpy/utils.py index dffbd31a57..dbb843e39e 100644 --- a/src/giskardpy/utils.py +++ b/src/giskardpy/utils.py @@ -24,6 +24,7 @@ from contextlib import contextmanager import sys, os import pylab as plt +import pkg_resources from giskardpy.plugin import PluginBehavior, NewPluginBase @@ -514,4 +515,78 @@ def add_edges(root, root_dot_name, visibility_level): add_edges(c, proposed_dot_name, visibility_level) add_edges(root, root.name, visibility_level) - return graph \ No newline at end of file + return graph + + + +def rospkg_exits(name): + """ + checks whether a ros package with the given name and version exits + :param name: the name and version of the ros package in requirements format e.g. giskard_msgs<=0.1.0 + :return: True if it exits else False + """ + r = rospkg.RosPack() + try: + l = name.split('=') + if l[0].endswith('<'): + m = r.get_manifest(l[0][:-1]) + version_m = m.version.split('.') + version_d = l[len(l) - 1].split('.') + k = max(len(version_m), len(version_d)) + for i in range(k): + if version_m[i] < version_d[i]: + return True + elif version_m[i] > version_d[i]: + print("found ROS package " + l[0][:-1] + "==" + str( + m.version) + " but " + name + " is required") + return False + return True + elif l[0].endswith('>'): + m = r.get_manifest(l[0][:-1]) + version_m = m.version.split('.') + version_d = l[len(l) - 1].split('.') + k = max(len(version_m), len(version_d)) + for i in range(k): + if version_m[i] > version_d[i]: + return True + elif version_m[i] < version_d[i]: + print("found ROS package " + l[0][:-1] + "==" + str( + m.version) + " but " + name + " is required") + return False + return True + else: + m = r.get_manifest(l[0]) + version_m = m.version.split('.') + version_d = l[len(l)-1].split('.') + if(len(version_m) != len(version_d)): + print("found ROS package " + l[0] + "==" + str(m.version) + " but " + name + " is required") + return False + for i in range(len(version_m)): + if version_m[i] != version_d[i]: + print("found ROS package " + l[0] + "==" + str(m.version) + " but " + name + " is required") + return False + return True + + except Exception as e: + print(name + " not found") + return False + +def check_dependencies(): + """ + Checks whether the dependencies specified in the dependency.txt in the root folder of giskardpy are installed. If a + dependecy is not installed a message is printed. + """ + r = rospkg.RosPack() + + with open(r.get_path('giskardpy') + '/dependencies.txt') as f: + dependencies = f.readlines() + + dependencies = [x.strip() for x in dependencies] + + for d in dependencies: + try: + pkg_resources.require(d) + except pkg_resources.DistributionNotFound as e: + rospkg_exits(d) + except pkg_resources.VersionConflict as e: + print('require ' + str(e.req) + ' but found ' + str(e.dist)) \ No newline at end of file From be3cde826db47eb7347b7170550412a99e69abb3 Mon Sep 17 00:00:00 2001 From: kevin Date: Mon, 4 Mar 2019 21:29:46 +0100 Subject: [PATCH 2/2] now the dependeny check fully supports the requirements.txt syntax --- dependencies.txt | 18 +++--- src/giskardpy/utils.py | 136 ++++++++++++++++++++++++++++------------- 2 files changed, 103 insertions(+), 51 deletions(-) diff --git a/dependencies.txt b/dependencies.txt index 3044e58c9c..c9cdac0a74 100644 --- a/dependencies.txt +++ b/dependencies.txt @@ -1,9 +1,11 @@ +# use the requirements.txt syntax to add dependencies symengine>=0.3.1.dev1 -numpy==1.15.4 -urdfdom-py==0.4.0 -rosunit==1.14.4 -cython==0.26.1 -qpoases==3.1.0 -giskard_msgs==0.1.0 -py_trees_ros==0.5.14 -py_trees==0.6.1 \ No newline at end of file +numpy>1.15.0, <=1.15.4 +urdfdom-py>=0.4.0 +rosunit>=1.14.4 +cython>=0.26.1 +qpoases>=3.1.0 +giskard_msgs>=0.1.0 +py_trees_ros>=0.5.14 +py_trees>=0.6.1 +pybullet==2.3.5 \ No newline at end of file diff --git a/src/giskardpy/utils.py b/src/giskardpy/utils.py index dbb843e39e..947cbfe603 100644 --- a/src/giskardpy/utils.py +++ b/src/giskardpy/utils.py @@ -8,6 +8,8 @@ import numpy as np from itertools import product, chain from numpy import pi +from rospy import logwarn +import re import errno from os import tmpfile @@ -519,57 +521,104 @@ def add_edges(root, root_dot_name, visibility_level): -def rospkg_exits(name): +def compare_version(version1, operator, version2): """ - checks whether a ros package with the given name and version exits - :param name: the name and version of the ros package in requirements format e.g. giskard_msgs<=0.1.0 - :return: True if it exits else False + compares two version numbers by means of the given operator + :param version1: version number 1 e.g. 0.1.0 + :type version1: str + :param operator: ==,<=,>=,<,> + :type operator: str + :param version2: version number 1 e.g. 3.2.0 + :type version2: str + :return: """ - r = rospkg.RosPack() - try: - l = name.split('=') - if l[0].endswith('<'): - m = r.get_manifest(l[0][:-1]) - version_m = m.version.split('.') - version_d = l[len(l) - 1].split('.') - k = max(len(version_m), len(version_d)) - for i in range(k): - if version_m[i] < version_d[i]: - return True - elif version_m[i] > version_d[i]: - print("found ROS package " + l[0][:-1] + "==" + str( - m.version) + " but " + name + " is required") - return False + version1 = version1.split('.') + version2 = version2.split('.') + if operator == '==': + if (len(version1) != len(version2)): + return False + for i in range(len(version1)): + if version1[i] != version2[i]: + return False + return True + elif operator == '<=': + k = min(len(version1), len(version2)) + for i in range(k): + if version1[i] > version2[i]: + return True + elif version1[i] < version2[i]: + return False + if len(version1) < len(version2): + return False + else: return True - elif l[0].endswith('>'): - m = r.get_manifest(l[0][:-1]) - version_m = m.version.split('.') - version_d = l[len(l) - 1].split('.') - k = max(len(version_m), len(version_d)) - for i in range(k): - if version_m[i] > version_d[i]: - return True - elif version_m[i] < version_d[i]: - print("found ROS package " + l[0][:-1] + "==" + str( - m.version) + " but " + name + " is required") - return False + elif operator == '>=': + k = min(len(version1), len(version2)) + for i in range(k): + if version1[i] < version2[i]: + return True + elif version1[i] > version2[i]: + return False + if len(version1) > len(version2): + return False + else: return True + elif operator == '<': + k = min(len(version1), len(version2)) + for i in range(k): + if version1[i] > version2[i]: + return True + elif version1[i] < version2[i]: + return False + if len(version1) < len(version2): + return False else: - m = r.get_manifest(l[0]) - version_m = m.version.split('.') - version_d = l[len(l)-1].split('.') - if(len(version_m) != len(version_d)): - print("found ROS package " + l[0] + "==" + str(m.version) + " but " + name + " is required") + return True + elif operator == '>': + k = min(len(version1), len(version2)) + for i in range(k): + if version1[i] < version2[i]: + return True + elif version1[i] > version2[i]: return False - for i in range(len(version_m)): - if version_m[i] != version_d[i]: - print("found ROS package " + l[0] + "==" + str(m.version) + " but " + name + " is required") - return False + if len(version1) > len(version2): + return False + else: return True + else: + return False + +def rospkg_exists(name): + """ + checks whether a ros package with the given name and version exists + :param name: the name and version of the ros package in requirements format e.g. giskard_msgs<=0.1.0 + :type name: str + :return: True if it exits else False + """ + r = rospkg.RosPack() + name = name.replace(' ', '') + version_list = name.split(',') + version_entry1 = re.split('(==|>=|<=|<|>)', version_list[0]) + package_name=version_entry1[0] + try: + m = r.get_manifest(package_name) except Exception as e: - print(name + " not found") + logwarn('package {name} not found'.format(name=name)) + return False + if len(version_entry1) == 1: + return True + if not compare_version(version_entry1[2], version_entry1[1], m.version): + logwarn('found ROS package {installed_name}=={installed_version} but {r} is required}'.format(installed_name=package_name, installed_version=str(m.version), r=name)) return False + for entry in version_list[1:]: + operator_and_version = re.split('(==|>=|<=|<|>)', entry) + if not compare_version(operator_and_version[2], operator_and_version[1], m.version): + logwarn('found ROS package {installed_name}=={installed_version} but {r} is required}'.format(installed_name=package_name, installed_version=str(m.version), r=name)) + return False + + return True + def check_dependencies(): """ @@ -581,12 +630,13 @@ def check_dependencies(): with open(r.get_path('giskardpy') + '/dependencies.txt') as f: dependencies = f.readlines() + dependencies = [x.split('#')[0] for x in dependencies] dependencies = [x.strip() for x in dependencies] for d in dependencies: try: pkg_resources.require(d) except pkg_resources.DistributionNotFound as e: - rospkg_exits(d) + rospkg_exists(d) except pkg_resources.VersionConflict as e: - print('require ' + str(e.req) + ' but found ' + str(e.dist)) \ No newline at end of file + logwarn('found {version_f} but version {version_r} is required'.format(version_r=str(e.req), version_f=str(e.dist))) \ No newline at end of file