cleanedup completion function local vars, aligned zsh with bash, more unit tests

This commit is contained in:
Thibault Kruse 2012-03-04 06:45:25 +00:00
parent fd9da19c56
commit 14946ca96c
5 changed files with 151 additions and 25 deletions

View File

@ -1,3 +1,7 @@
# rosbash - functions to support ROS users
# Useful things to know:
# 'local' variables get unset after function, all others stay forever
# COMPREPLY is the var used by bash complete builtin
function _rossed { function _rossed {
if [[ `uname` == Darwin || `uname` == FreeBSD ]]; then if [[ `uname` == Darwin || `uname` == FreeBSD ]]; then
@ -7,9 +11,13 @@ function _rossed {
fi fi
} }
# _ros_location_find
# based on $ROS_LOCATIONS, which the user can set to any colon
# separated of key=folder pairs also resolves keys 'log' and
# 'test_results' to ROS defaults finally resolves to package, then
# stack echoes its result
function _ros_location_find { function _ros_location_find {
local homedir ROS_LOCATION_KEYS_ARR ROS_LOCATIONS_ARR loc
homedir=`echo $HOME | sed -e "s/\//\t\//g" -e "s/\t/\\\\\/g"` homedir=`echo $HOME | sed -e "s/\//\t\//g" -e "s/\t/\\\\\/g"`
ROS_LOCATION_KEYS_ARR=(`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\1 /g'`) ROS_LOCATION_KEYS_ARR=(`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\1 /g'`)
ROS_LOCATIONS_ARR=(`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\2 /g' -e "s/~/${homedir}/g"`) ROS_LOCATIONS_ARR=(`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\2 /g' -e "s/~/${homedir}/g"`)
@ -43,6 +51,7 @@ function _ros_location_find {
} }
function _ros_list_locations { function _ros_list_locations {
local ROS_LOCATION_KEYS packages stacks
ROS_LOCATION_KEYS=`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\1 /g'` ROS_LOCATION_KEYS=`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\1 /g'`
packages=`export ROS_CACHE_TIMEOUT=-1.0 && rospack list-names` packages=`export ROS_CACHE_TIMEOUT=-1.0 && rospack list-names`
stacks=`export ROS_CACHE_TIMEOUT=-1.0 && rosstack list-names` stacks=`export ROS_CACHE_TIMEOUT=-1.0 && rosstack list-names`
@ -51,6 +60,7 @@ function _ros_list_locations {
} }
function _ros_package_find { function _ros_package_find {
local loc
loc=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find $1 2> /dev/null` loc=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find $1 2> /dev/null`
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
return 1 return 1
@ -60,20 +70,25 @@ function _ros_package_find {
} }
function _ros_list_packages { function _ros_list_packages {
local packages
packages=`export ROS_CACHE_TIMEOUT=-1.0 && rospack list-names` packages=`export ROS_CACHE_TIMEOUT=-1.0 && rospack list-names`
echo $packages | tr ' ' '\n' echo $packages | tr ' ' '\n'
return 0 return 0
} }
function _ros_list_stacks { function _ros_list_stacks {
local stacks
stacks=`export ROS_CACHE_TIMEOUT=-1.0 && rosstack list-names` stacks=`export ROS_CACHE_TIMEOUT=-1.0 && rosstack list-names`
echo $stacks | tr ' ' '\n' echo $stacks | tr ' ' '\n'
return 0 return 0
} }
# takes as argument either just a package-path or just a pkgname
# returns 0 for no argument or if package (+ path) exist, 1 else
# on success with arguments returns [pkgname, abspath, relpath basename]
function _ros_decode_path { function _ros_decode_path {
local rosname rosdir reldir last local rosname rosdir reldir last
rosvals=()
if [[ -z $1 ]]; then if [[ -z $1 ]]; then
return 0 return 0
fi fi
@ -101,6 +116,7 @@ function _ros_decode_path {
} }
function rospython { function rospython {
local pkgname
if [[ $1 = "--help" ]]; then if [[ $1 = "--help" ]]; then
echo -e "usage: rospython [package] \n\nRun python loading package manifest first." echo -e "usage: rospython [package] \n\nRun python loading package manifest first."
return 0 return 0
@ -193,7 +209,7 @@ function rosls {
} }
function _roscmd { function _roscmd {
local pkgdir exepath opt catkin_source_dir catkin_binary_dir local pkgdir exepath opt catkin_source_dir catkin_binary_dir opts arg
if [[ -n $CATKIN_SOURCE_DIR ]]; then if [[ -n $CATKIN_SOURCE_DIR ]]; then
catkin_source_dir=`ROS_ROOT=$CATKIN_SOURCE_DIR ROS_PACKAGE_PATH= _ros_package_find $1` catkin_source_dir=`ROS_ROOT=$CATKIN_SOURCE_DIR ROS_PACKAGE_PATH= _ros_package_find $1`
fi fi
@ -309,9 +325,6 @@ function _msg_opts {
pkgname=${1} pkgname=${1}
fi fi
echo Pkg: $pkgname
echo Msg: $msgname
if [[ -z ${searchmsg} ]]; then if [[ -z ${searchmsg} ]]; then
pkgs=(`rospack list`) pkgs=(`rospack list`)
@ -482,6 +495,7 @@ function _roscomplete_test {
} }
function _roscomplete_rosbag { function _roscomplete_rosbag {
local opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -523,6 +537,7 @@ function _roscomplete_rosbag {
} }
function _roscomplete_rospack { function _roscomplete_rospack {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -537,6 +552,7 @@ function _roscomplete_rospack {
} }
function _roscomplete_rosnode { function _roscomplete_rosnode {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -573,6 +589,7 @@ function _roscomplete_rosnode {
} }
function _roscomplete_rosparam { function _roscomplete_rosparam {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -602,6 +619,7 @@ function _roscomplete_rosparam {
} }
function _roscomplete_rostopic { function _roscomplete_rostopic {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -661,6 +679,7 @@ function _roscomplete_rostopic {
} }
function _roscomplete_rosservice { function _roscomplete_rosservice {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -732,6 +751,7 @@ function _msg_opts {
} }
function _roscomplete_rosmsg { function _roscomplete_rosmsg {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -757,6 +777,7 @@ function _roscomplete_rosmsg {
} }
function _roscomplete_roscreate_pkg { function _roscomplete_roscreate_pkg {
local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
@ -780,7 +801,7 @@ function _roscomplete_roswtf {
} }
function _roscomplete_rosclean { function _roscomplete_rosclean {
local arg local arg opts
COMPREPLY=() COMPREPLY=()
arg="${COMP_WORDS[COMP_CWORD]}" arg="${COMP_WORDS[COMP_CWORD]}"
if [[ $COMP_CWORD == 1 ]]; then if [[ $COMP_CWORD == 1 ]]; then

View File

@ -1,6 +1,67 @@
# roszsh - functions to support ROS users
# Useful things to know:
# 'local' variables get unset after function, all others stay forever
# 'reply' is the var used by zsh compctl builtin
function _rossed {
if [[ `uname` == Darwin || `uname` == FreeBSD ]]; then
sed -E "$@"
else
sed -r "$@"
fi
}
# _ros_location_find
# based on $ROS_LOCATIONS, which the user can set to any colon
# separated of key=folder pairs also resolves keys 'log' and
# 'test_results' to ROS defaults finally resolves to package, then
# stack echoes its result
function _ros_location_find {
local homedir ROS_LOCATION_KEYS_ARR ROS_LOCATIONS_ARR loc
homedir=`echo $HOME | sed -e "s/\//\t\//g" -e "s/\t/\\\\\/g"`
ROS_LOCATION_KEYS_ARR=(`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\1 /g'`)
ROS_LOCATIONS_ARR=(`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\2 /g' -e "s/~/${homedir}/g"`)
for (( i = 1 ; i <= ${#ROS_LOCATION_KEYS_ARR[@]} ; i++ )); do
if [[ $1 == ${ROS_LOCATION_KEYS_ARR[$i]} ]]; then
echo ${ROS_LOCATIONS_ARR[i]}
return 0
fi
done
if [[ $1 == log ]]; then
echo `roslaunch-logs`
return 0
elif [[ $1 == test_results ]]; then
echo `rosrun rosunit test_results_dir.py`
return 0
fi
loc=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find $1 2> /dev/null`
if [[ $? != 0 ]]; then
loc=`export ROS_CACHE_TIMEOUT=-1.0 && rosstack find $1 2> /dev/null`
if [[ $? != 0 ]]; then
return 1
fi
echo $loc
return 0
fi
echo $loc
return 0
}
function _ros_list_locations {
local ROS_LOCATION_KEYS packages stacks
ROS_LOCATION_KEYS=`echo $ROS_LOCATIONS | _rossed -e 's/([^:=]*)=([^:=]*)(:*[^=])*(:|$)/\1 /g'`
packages=`export ROS_CACHE_TIMEOUT=-1.0 && rospack list-names`
stacks=`export ROS_CACHE_TIMEOUT=-1.0 && rosstack list-names`
echo $packages $stacks log test_results $ROS_LOCATION_KEYS | tr ' ' '\n'
return 0
}
function _ros_decode_path { function _ros_decode_path {
local rosname rosdir reldir last rospackdir rosstack_result rosstackdir local rosname rosdir reldir last rospackdir rosstack_result rosstackdir
rosvals=()
if [[ -z $1 ]]; then if [[ -z $1 ]]; then
return 0 return 0
fi fi
@ -138,7 +199,7 @@ function rosls {
} }
function _roscmd { function _roscmd {
local pkgdir exepath opt local pkgdir exepath opt arg
pkgdir=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find $1 2> /dev/null` pkgdir=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find $1 2> /dev/null`
if [[ $? != 0 ]] ; then if [[ $? != 0 ]] ; then
echo "Couldn't find package [$1]" echo "Couldn't find package [$1]"
@ -232,7 +293,7 @@ function _roscomplete_sub_dir {
} }
function _roscomplete_search_dir { function _roscomplete_search_dir {
local words arg opts pkgdir local words arg opts pkgdir pkgdir_result stack_result
reply=() reply=()
words=(${=BUFFER}) words=(${=BUFFER})
pkgdir=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find ${words[2]} 2> /dev/null` pkgdir=`export ROS_CACHE_TIMEOUT=-1.0 && rospack find ${words[2]} 2> /dev/null`
@ -264,6 +325,7 @@ function _roscomplete_launchfile {
} }
function _roscomplete_rosbag { function _roscomplete_rosbag {
local opts
reply=() reply=()
if [[ ${CURRENT} == 2 ]]; then if [[ ${CURRENT} == 2 ]]; then
@ -305,6 +367,7 @@ function _roscomplete_rosbag {
} }
function _roscomplete_rospack { function _roscomplete_rospack {
local opts
reply=() reply=()
if [[ ${CURRENT} == 2 ]]; then if [[ ${CURRENT} == 2 ]]; then
opts="help find list list-names list-duplicates langs depends depends-manifests depends1 depends-indent depends-msgsrv depends-why rosdep rosdep0 vcs vcs0 depends-on depends-on1 export plugins cflags-only-I cflags-only-other libs-only-L libs-only-l libs-only-other profile" opts="help find list list-names list-duplicates langs depends depends-manifests depends1 depends-indent depends-msgsrv depends-why rosdep rosdep0 vcs vcs0 depends-on depends-on1 export plugins cflags-only-I cflags-only-other libs-only-L libs-only-l libs-only-other profile"
@ -316,6 +379,7 @@ function _roscomplete_rospack {
} }
function _roscomplete_rosnode { function _roscomplete_rosnode {
local opts
reply=() reply=()
if [[ ${CURRENT} == 2 ]]; then if [[ ${CURRENT} == 2 ]]; then
@ -348,11 +412,11 @@ function _roscomplete_rosnode {
;; ;;
esac esac
fi fi
} }
function _roscomplete_rosparam {
reply=()
function _roscomplete_rosparam {
local opts
reply=()
if [[ ${CURRENT} == 2 ]]; then if [[ ${CURRENT} == 2 ]]; then
opts="set get load dump delete list" opts="set get load dump delete list"
@ -446,6 +510,7 @@ function _roscomplete_rostopic {
} }
function _roscomplete_rosservice { function _roscomplete_rosservice {
local opts
reply=() reply=()
@ -478,6 +543,7 @@ function _roscomplete_rosservice {
} }
function _msg_opts { function _msg_opts {
local pkgname msgname searchmsg pkgs count pkgname2 opts result
unset searchmsg unset searchmsg
if [[ $1 =~ .+/.* ]]; then if [[ $1 =~ .+/.* ]]; then
@ -517,6 +583,7 @@ function _msg_opts {
} }
function _roscomplete_rosmsg { function _roscomplete_rosmsg {
local opts
reply=() reply=()
@ -541,6 +608,7 @@ function _roscomplete_rosmsg {
} }
function _srv_opts { function _srv_opts {
local pkgname srvname searchsrv pkgs count opts pkgpath result
unset searchsrv unset searchsrv
if [[ $1 =~ .+/.* ]]; then if [[ $1 =~ .+/.* ]]; then
@ -580,9 +648,9 @@ function _srv_opts {
} }
function _roscomplete_rossrv { function _roscomplete_rossrv {
local opts
reply=() reply=()
if [[ ${CURRENT} == 2 ]]; then if [[ ${CURRENT} == 2 ]]; then
opts="show list md5 package packages" opts="show list md5 package packages"
reply=(${=opts}) reply=(${=opts})
@ -603,17 +671,16 @@ function _roscomplete_rossrv {
fi fi
} }
function _roscomplete_roscreate_pkg { function _roscomplete_roscreate_pkg {
local opts
reply=() reply=()
if [[ ${CURRENT} > 2 ]]; then if [[ ${CURRENT} > 2 ]]; then
opts=`rospack list-names` opts=`rospack list-names`
reply=(${=opts}) reply=(${=opts})
fi fi
} }
compctl -K "_roscomplete_sub_dir" -S / "roscd" "rospd" "rosls" compctl -K "_roscomplete_sub_dir" -S / "roscd" "rospd" "rosls"
compctl -K "_roscomplete_rosmake" "rosmake" compctl -K "_roscomplete_rosmake" "rosmake"

View File

@ -7,12 +7,18 @@
. ../rosbash . ../rosbash
echo Testing BASH
. test_zshbash.sh
# roslaunch completion
export COMP_CWORD=1 export COMP_CWORD=1
_roscomplete_launch roslaunch _roscomplete_launch roslaunch
if [[ ! ${COMPREPLY[@]} =~ rosbash ]]; then if [[ ! ${COMPREPLY[@]} =~ rosbash ]]; then
echo "rosbash package missing from" ${COMPREPLY[@]} ; exit 1 echo "rosbash package missing from" ${COMPREPLY[@]} ; exit 1
fi fi
echo success 1 echo success roslaunch pkg
export COMP_WORDS=("roslaunch" "--") export COMP_WORDS=("roslaunch" "--")
export COMP_CWORD=1 export COMP_CWORD=1
@ -20,7 +26,7 @@ _roscomplete_launch roslaunch "--" roslaunch
if [[ ! ${COMPREPLY[@]} == "--files --args --nodes --find-node --child --local --screen --server_uri --run_id --wait --port --core --pid --dump-params" ]]; then if [[ ! ${COMPREPLY[@]} == "--files --args --nodes --find-node --child --local --screen --server_uri --run_id --wait --port --core --pid --dump-params" ]]; then
echo "roslaunch --options missing" from ${COMPREPLY[@]} ; exit 1 echo "roslaunch --options missing" from ${COMPREPLY[@]} ; exit 1
fi fi
echo success 2 echo success roslaunch --option
export COMP_WORDS=("roslaunch" "roslaunch") export COMP_WORDS=("roslaunch" "roslaunch")
export COMP_CWORD=2 export COMP_CWORD=2
@ -28,4 +34,10 @@ _roscomplete_launch roslaunch roslaunch
if [[ ! ${COMPREPLY[@]} =~ "example.launch" ]]; then if [[ ! ${COMPREPLY[@]} =~ "example.launch" ]]; then
echo "example.launch missing from " ${COMPREPLY[@]} ; exit 1 echo "example.launch missing from " ${COMPREPLY[@]} ; exit 1
fi fi
echo success 3 echo success roslaunch launchfiles
# if [[ ! ${COMPREPLY[@]} =~ "example.launch" ]]; then
# echo "example.launch missing from " ${COMPREPLY[@]} ; exit 1
# fi
# echo success 4

View File

@ -0,0 +1,21 @@
#! /usr/bin/env zsh
# This script is supposed to be a unit test for rosbash, also used for manual checks against other operating systems.
# TODO extend this script
. ../roszsh
echo "Testing ZSH"
. ./test_zshbash.sh
# roslaunch completion
BUFFER=("foo roslaunch")
_roscomplete_search_dir
if [[ ! ${reply[@]} =~ "example.launch" ]]; then
echo "rosbash package missing from" ${reply[@]} ; exit 1
fi
echo success roslaunch launchfiles

View File

@ -10,9 +10,14 @@ TEST_PATH = os.path.join(PKG_PATH, 'test')
class TestRosBash(unittest.TestCase): class TestRosBash(unittest.TestCase):
def setUp(self): def setUp(self):
self.cmd = os.path.join(TEST_PATH, 'test_rosbash.bash') self.cmdbash = os.path.join(TEST_PATH, 'test_rosbash.bash')
self.assertTrue(os.path.exists(self.cmd)) self.assertTrue(os.path.exists(self.cmdbash))
self.cmdzsh = os.path.join(TEST_PATH, 'test_roszsh.zsh')
self.assertTrue(os.path.exists(self.cmdzsh))
def test_rosbash_completion(self): def test_rosbash_completion(self):
subprocess.check_call([self.cmd], cwd = TEST_PATH) subprocess.check_call([self.cmdbash], cwd = TEST_PATH)
def test_roszsh_completion(self):
subprocess.check_call([self.cmdzsh], cwd = TEST_PATH)