def roslocate_info(stack, distro, dev): """ Looks up stack yaml on the web :raises: ROSInstallException on errors """ # TODO: use roslocate from code cmd = ['roslocate', 'info', '--distro=%s' % (distro), stack] if dev is True: cmd.append('--dev') try: proc = Popen(cmd, stdout=PIPE, stderr=PIPE) except OSError as exc: raise ROSInstallException('%s\nfailed to execute roslocate; is your ROS environment configured?' % (exc)) stdout, stderr = proc.communicate() if proc.returncode != 0: sys.stderr.write('[rosws] Warning: failed to locate stack "%s" in distro "%s". Falling back on non-distro-specific search; compatibility problems may ensue.\n' % (stack, distro)) # Could be that the stack hasn't been released; try roslocate # again, without specifying the distro. cmd = ['roslocate', 'info', stack] if dev is True: cmd.append('--dev') try: proc = Popen(cmd, stdout=PIPE, stderr=PIPE) except OSError as exc: raise ROSInstallException('%s\nfailed to execute roslocate; is your ROS environment configured?' % (exc)) stdout, stderr = proc.communicate() if proc.returncode != 0: raise ROSInstallException('roslocate failed: %s' % (stderr)) return yaml.load(stdout)
def get_ros_stack_version(): """ Reads/Infers the ros stack version. Avoid using this function if you can. """ # TODO: switch to `rosversion -d` after it's been released (r14279, # r14280) cmd = ['rosversion', 'ros'] try: proc = Popen(cmd, stdout=PIPE, stderr=PIPE) except OSError as exc: raise ROSInstallException('%s\nfailed to execute rosversion; is your ROS environment configured?' % (exc)) stdout, stderr = proc.communicate() if proc.returncode != 0: raise ROSInstallException('rosversion failed: %s' % (stderr)) ver = distutils.version.StrictVersion(stdout).version if len(ver) < 2: raise ROSInstallException('invalid ros version: %s' % (stdout)) return ver
def rosversion_to_distro_name(ver): """ Reads/Infers the distro name from ROS / or the ros stack version. Avoid using this function if you can. """ if len(ver) < 2: raise ROSInstallException('invalid ros version: %s' % (ver)) major, minor = ver[0:2] if major == 1 and minor == 10: return 'groovy' if major == 1 and minor == 8: return 'fuerte' if major == 1 and minor == 6: return 'electric' elif major == 1 and minor == 5: return 'unstable' elif major == 1 and minor == 4: return 'diamondback' else: raise ROSInstallException('unknown ros version: %s' % (ver))
def get_dependent_stacks(stack): """ Calls rosstack depends-on to get a list of dependance stacks. Avoid using this function if you can. """ # roslib.stacks doesn't expose the dependency parts of rosstack, so # we'll call it manually cmd = ['rosstack', 'depends-on', stack] try: proc = Popen(cmd, stdout=PIPE, stderr=PIPE) except OSError as exc: raise ROSInstallException('%s\nfailed to execute rosstack; is your ROS environment configured?' % (exc)) stdout, stderr = proc.communicate() if proc.returncode != 0: raise ROSInstallException('rosstack failed: %s' % (stderr)) # Make sure to exclude empty lines deps = [] for line in stdout.splitlines(): if len(line) > 0: deps.append(line) return deps
def generate_setup(config, no_ros_allowed=False): ros_root = get_ros_stack_path(config) if ros_root is None: if not no_ros_allowed: candidates = [] for t in config.get_config_elements(): if os.path.basename(t.get_local_name()) == 'ros': candidates.append(t.get_path()) raise ROSInstallException(""" No 'ros' stack detected in candidates %s. Please add the location of a ros distribution to this command. See http://ros.org/wiki/rosinstall.""" % (candidates)) text = generate_setup_sh_text(workspacepath=config.get_base_path()) setup_path = os.path.join(config.get_base_path(), 'setup.sh') with open(setup_path, 'w') as fhand: fhand.write(text) for shell in ['bash', 'zsh']: text = generate_setup_bash_text(shell) setup_path = os.path.join(config.get_base_path(), 'setup.%s' % shell) with open(setup_path, 'w') as fhand: fhand.write(text)
def generate_setup_bash_text(shell): ''' Generates the contents that go into a setup.bash or setup.zsh file. The intent of such a file is to enable shell extensions, such as special ros commands and tab completion. The generation is complex because the setup of the system changed between ROS electric and fuerte. In fuerte, the distro setup.sh also loads distro rosbash based on CATKIN_SHELL. Before fuerte, it is up to setup.bash to do so. ''' if shell == 'bash': script_path = """ SCRIPT_PATH="${BASH_SOURCE[0]}"; if([ -h "${SCRIPT_PATH}" ]) then while([ -h "${SCRIPT_PATH}" ]) do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done fi export OLDPWDBAK=$OLDPWD pushd . > /dev/null cd `dirname ${SCRIPT_PATH}` > /dev/null SCRIPT_PATH=`pwd`; popd > /dev/null export OLDPWD=$OLDPWDBAK """ call_setup_sh = ". $SCRIPT_PATH/setup.sh" elif shell == 'zsh': script_path = 'SCRIPT_PATH="$(dirname $0)"' call_setup_sh = """ emulate sh # emulate POSIX . $SCRIPT_PATH/setup.sh emulate zsh # back in zsh """ else: raise ROSInstallException("%s shell unsupported." % shell) text = """#!/usr/bin/env %(shell)s %(header)s CATKIN_SHELL=%(shell)s %(script_path)s # Load the path of this particular setup.%(shell)s if [ ! -f "$SCRIPT_PATH/setup.sh" ]; then echo "Bug: shell script unable to determine its own location: $SCRIPT_PATH" return 22 fi # unset _ros_decode_path (function of rosbash) to check later whether setup.sh has sourced ros%(shell)s unset -f _ros_decode_path 1> /dev/null 2>&1 %(call_setup_sh)s # if we have a ROS_ROOT, then we might need to source rosbash (pre-fuerte) if [ ! -z "${ROS_ROOT}" ]; then # check whether setup.sh also already sourced rosbash # Cannot rely on $? due to set -o errexit in build scripts RETURNCODE=`type _ros_decode_path 2> /dev/null | grep function 1>/dev/null 2>&1 || echo error` # for ROS electric and before, source rosbash if [ ! "$RETURNCODE" = "" ]; then RETURNCODE=`rospack help 1> /dev/null 2>&1 || echo error` if [ "$RETURNCODE" = "" ]; then ROSSHELL_PATH=`rospack find rosbash`/ros%(shell)s if [ -e "$ROSSHELL_PATH" ]; then . $ROSSHELL_PATH fi else echo "rospack could not be found, you cannot have ros%(shell)s features until you bootstrap ros" fi fi fi """ % { 'shell': shell, 'script_path': script_path, 'call_setup_sh': call_setup_sh, 'header': SHELL_HEADER } return text