@@ -11,6 +11,7 @@ ROS_CONDA_WRAPPER_PROGNAME="ROS Conda wrapper"
11
11
ROS_CONDA_WRAPPER_ERROR=false
12
12
ROS_CONDA_WRAPPER_VERSION=" 1.0.1"
13
13
ROS_CONDA_CONFIG_FILE_NAME=" ${HOME} /.ros_conda_wrapper_rc_cfg"
14
+ ROS_CONDA_ROS_PYTHONPATH_BACKUP=()
14
15
15
16
# Bash echo colours
16
17
ORANGE_CC=' \033[0;33m'
@@ -123,30 +124,39 @@ function _ros_conda_path_fix_outside() {
123
124
# This function makes sure the anaconda bin and condabin folders
124
125
# are further on the path than the /usr/bin, /bin and
125
126
# /opt/ros/<ROSVERSION>/bin when outside an anaconda environment.
126
- # It further makes sure that the anaconda site packages folder is
127
- # removed from the $PYTHONPATH.
127
+
128
+ # Create local variables
129
+ local path_changed=false
130
+
131
+ # Split PATH into array and get path length
132
+ local defaultIFS=" $IFS " ; IFS=$' \t\n ' ; local path_array=(${PATH//:/ } ); IFS=" $defaultIFS "
133
+ local arr_len=" ${# path_array[@]} "
128
134
129
135
# Make sure the Conda paths are at the end of the PATH variable
130
136
ros_conda_path_array=(
131
137
" ${ROS_CONDA_CONDA_PATH} /condabin"
132
138
" ${ROS_CONDA_CONDA_PATH} /bin"
133
139
" ${ROS_CONDA_CONDA_PATH} /envs/${CONDA_DEFAULT_ENV} /bin"
134
140
)
135
- local path_changed=false
136
141
for path in " ${ros_conda_path_array[@]} " ; do
137
142
if [[ :${PATH} : == * :" ${path} " :* ]] ; then
138
143
139
- # Remove all occurances from PATH variable
144
+ # Remove all occurrences from PATH variable
140
145
while [[ " :${PATH} :" == * :" ${path} " :* ]] ; do
146
+
141
147
# Remove path from PATH variable
142
- PATH=${PATH// " :${path} :" / " :" } # delete any instances in the middle
143
- PATH=${PATH/# " ${path} :" / } # delete any instance at the beginning
144
- PATH=${PATH/% " :${path} " / } # delete any instance in the at the end
148
+ if [[ " ${arr_len} " -eq 1 ]]; then # If Path length is 1
149
+ PATH=${PATH// " ${path} " / } # delete instance
150
+ else
151
+ PATH=${PATH// " :${path} :" / " :" } # delete any instances in the middle
152
+ PATH=${PATH/# " ${path} :" / } # delete any instance at the beginning
153
+ PATH=${PATH/% " :${path} " / } # delete any instance in the at the end
154
+ fi
145
155
done
146
156
147
157
# Add path to the end
148
158
PATH=" ${PATH: +${PATH} : }${path} "
149
- local path_changed=true
159
+ path_changed=true
150
160
fi
151
161
done
152
162
@@ -161,28 +171,38 @@ function _ros_conda_path_fix_inside() {
161
171
# are earlier on the path than the /usr/bin, /bin and
162
172
# /opt/ros/<ROSVERSION>/bin when inside an anaconda environment.
163
173
174
+ # Create local variables
175
+ local path_changed=false
176
+
177
+ # Split PATH into array and get path length
178
+ local defaultIFS=" $IFS " ; IFS=$' \t\n ' ; local path_array=(${PATH//:/ } ); IFS=" $defaultIFS "
179
+ local arr_len=" ${# path_array[@]} "
180
+
164
181
# Make sure the Conda paths are at the beginning of the PATH variable
165
182
ros_conda_path_array=(
166
183
" ${ROS_CONDA_CONDA_PATH} /condabin"
167
184
" ${ROS_CONDA_CONDA_PATH} /bin"
168
185
" ${ROS_CONDA_CONDA_PATH} /envs/${CONDA_DEFAULT_ENV} /bin"
169
186
)
170
- local path_changed=false
171
187
for path in " ${ros_conda_path_array[@]} " ; do
172
188
if [[ " :${PATH} :" == * :" ${path} " :* ]] ; then
173
189
174
- # Remove all occurances from PATH variable
190
+ # Remove all occurrences from PATH variable
175
191
while [[ " :${PATH} :" == * :" ${path} " :* ]] ; do
176
192
177
193
# Remove path from PATH variable
178
- PATH=${PATH// " :${path} :" / " :" } # delete any instances in the middle
179
- PATH=${PATH/# " ${path} :" / } # delete any instance at the beginning
180
- PATH=${PATH/% " :${path} " / } # delete any instance in the at the end
194
+ if [[ " ${arr_len} " -eq 1 ]]; then # If Path length is 1
195
+ PATH=${PATH// " ${path} " / } # delete instance
196
+ else
197
+ PATH=${PATH// " :${path} :" / " :" } # delete any instances in the middle
198
+ PATH=${PATH/# " ${path} :" / } # delete any instance at the beginning
199
+ PATH=${PATH/% " :${path} " / } # delete any instance in the at the end
200
+ fi
181
201
done
182
202
183
- # Prepent to PATH variable
203
+ # Prepend to PATH variable
184
204
PATH=" ${path}${PATH: +: ${PATH} } "
185
- local path_changed=true
205
+ path_changed=true
186
206
fi
187
207
done
188
208
@@ -193,69 +213,66 @@ function _ros_conda_path_fix_inside() {
193
213
}
194
214
195
215
function _ros_conda_pythonpath_fix_outside() {
196
- # This function makes sure the anaconda site packages folder
197
- # is removed from the PYTHONPATH when outside an anaconda
198
- # environment.
216
+ # This function makes sure that the ROS python dist-packages path
217
+ # IS present on the PYTHONPATH when inside a Conda environment.
199
218
200
- # Remove any Conda site-packages folder from the PYTHONPATH
219
+ # Create local variables
201
220
local path_changed=false
202
- while [[ " :${PYTHONPATH} :" == * :" ${ROS_CONDA_CONDA_PATH} " * " site-packages" :* ]]; do
203
221
204
- # Remove path from PATH variable
205
- PYTHONPATH=${PYTHONPATH// " :${ROS_CONDA_CONDA_PATH} " * " site-packages:" / " :" } # delete any instances in the middle
206
- PYTHONPATH=${PYTHONPATH/# " ${ROS_CONDA_CONDA_PATH} " * " site-packages:" / } # delete any instance at the beginning
207
- PYTHONPATH=${PYTHONPATH/% " :${ROS_CONDA_CONDA_PATH} " * " site-packages" / } # delete any instance in the at the end
208
- local path_changed=true
222
+ # Restore ROS python paths if they are not yet found on the PYTHONPATH
223
+ for ros_python_path in " ${ROS_CONDA_ROS_PYTHONPATH_BACKUP[@]} " ; do
224
+ if [[ -d " $ros_python_path " ]]; then
225
+ if [[ " :$PYTHONPATH :" != * " :${ros_python_path} :" * ]]; then
226
+
227
+ # Prepend to PYTHONPATH variable
228
+ PYTHONPATH=" $ros_python_path ${PYTHONPATH: +: ${PYTHONPATH} } "
229
+ path_changed=true
230
+ fi
231
+ fi
209
232
done
210
233
211
- # Export PATH
234
+ # Export PYTHONPATH
212
235
if [[ " $path_changed " = true ]]; then
236
+
237
+ # Export PYTHONPATH
213
238
export PYTHONPATH
214
239
fi
215
240
}
216
241
217
242
function _ros_conda_pythonpath_fix_inside() {
218
- # This function makes sure that the anaconda site packages
219
- # folder comes before the ROS melodic dist-packages folder
220
- # when inside a anaconda environment.
243
+ # This function makes sure that the ROS python dist-packages path
244
+ # is NOT present on the PYTHONPATH when inside a Conda environment.
221
245
222
- # Get Conda environment name and path
223
- if [[ " $CONDA_DEFAULT_ENV " == " base" || " $CONDA_DEFAULT_ENV " == " root" ]]; then
224
- local _conda_site_packages_path=" $CONDA_BASE_SITE_PACKAGES_PATH "
225
- else
226
- local _conda_site_packages_path=" $( find ${ROS_CONDA_CONDA_PATH} /envs/${CONDA_DEFAULT_ENV} /lib -iname site-packages 2> /dev/null) "
227
- fi
246
+ # Create local variables
247
+ local path_changed=false
248
+ local new_pythonpath_array=()
228
249
229
- # Remove any previously added site-packages folder from the PYTHONPATH
230
- while [[ " : ${PYTHONPATH} : " == * : " ${ROS_CONDA_CONDA_PATH} " * " site-packages " : * ]] ; do
250
+ # Split PYTHONPATH or PYTHONPATH into array
251
+ local defaultIFS= " $IFS " ; IFS= $' \t\n ' ; local pythonpath_array=( ${PYTHONPATH //:/ } ) ; IFS= " $defaultIFS "
231
252
232
- # Remove path from PATH variable
233
- PYTHONPATH=${PYTHONPATH// " :${ROS_CONDA_CONDA_PATH} " * " site-packages:" / " :" } # delete any instances in the middle
234
- PYTHONPATH=${PYTHONPATH/# " ${ROS_CONDA_CONDA_PATH} " * " site-packages:" / } # delete any instance at the beginning
235
- PYTHONPATH=${PYTHONPATH/% " :${ROS_CONDA_CONDA_PATH} " * " site-packages" / } # delete any instance in the at the end
236
- done
253
+ # Loop through the paths and retrieve the python paths
254
+ for path in " ${pythonpath_array[@]} " ; do
237
255
238
- # Prepend Conda site-packages folder to the PYTHONPATH
239
- if [[ -d " $_conda_site_packages_path " ]]; then
240
- if [[ " :$PYTHONPATH :" != * " :${_conda_site_packages_path} :" * ]]; then
256
+ # Test if path is ros path
257
+ if [[ " $path " == " /opt/ros/" * " /dist-packages" ]]; then
241
258
242
- # Add Conda site-packages folder to PYTHONPATH
243
- PYTHONPATH=" ${_conda_site_packages_path} :${PYTHONPATH} "
259
+ # Add to ROS_PYTHONPATH_BACKUP array
260
+ ROS_CONDA_ROS_PYTHONPATH_BACKUP+=(" ${path} " )
261
+ path_changed=true
244
262
else
245
263
246
- # Remove any Conda site-packages folder from the PYTHONPATH if it exists
247
- while [[ " :$PYTHONPATH :" == * " :${_conda_site_packages_path} :" * ]]; do
248
- # Remove path from PATH variable
249
- PYTHONPATH=${PYTHONPATH// " :${_conda_site_packages_path} :" / " :" } # delete any instances in the middle
250
- PYTHONPATH=${PYTHONPATH/# " ${_conda_site_packages_path} :" / } # delete any instance at the beginning
251
- PYTHONPATH=${PYTHONPATH/% " :${_conda_site_packages_path} " / } # delete any instance in the at the end
252
- done
253
-
254
- # Add Conda site-packages folder to PYTHONPATH
255
- PYTHONPATH=" ${_conda_site_packages_path} :${PYTHONPATH} "
264
+ # Pass to new PYTHONPATH array
265
+ new_pythonpath_array+=(" ${path} " )
256
266
fi
267
+ done
268
+
269
+ # Export PYTHONPATH
270
+ if [[ " $path_changed " = true ]]; then
257
271
258
- # Export PATH
272
+ # Convert new PYTHONPATH back to : delimited string
273
+ PYTHONPATH=$( IFS=$' :' ; echo " ${new_pythonpath_array[*]} " ) # Converting bash array back into a delimited string
274
+
275
+ # Export PYTHONPATH
259
276
export PYTHONPATH
260
277
fi
261
278
}
@@ -849,7 +866,7 @@ function _ros_conda_source_wrapper() {
849
866
local had_error=false
850
867
851
868
# Execute source command
852
- \s ource " $@ " 2> /dev/null || had_error=true
869
+ \s ource " $@ " || had_error=true
853
870
854
871
# Fix paths if source was successful
855
872
if [[ " $had_error " == false ]]; then
@@ -871,40 +888,34 @@ function _ros_conda_source_wrapper() {
871
888
872
889
# Execute source command
873
890
local had_error=false
874
- \s ource " $@ " 2> /dev/null || had_error=true
891
+ \s ource " $@ " || had_error=true
875
892
876
893
# Fix paths if source was successful
877
894
if [[ " $had_error " == false ]]; then
878
895
879
896
# Get full path
880
897
local sourced_path=" $1 "
881
- case sourced_path in
882
- /* )
883
- local sourced_path_absolute=" $sourced_path "
884
- ;;
885
- ./* )
886
-
887
- local sourced_path_absolute=" ${PWD} /${sourced_path: 2} "
888
- ;;
889
- * )
890
- local sourced_path_absolute=" ${PWD} /${sourced_path} "
891
- ;;
892
- esac
893
-
894
- # Check if sourced file was inside catkin_ws
895
- if [[ -e " $( dirname $( dirname " ${sourced_path_absolute} " ) ) /.catkin_workspace" ]]; then
896
-
897
- # Check if your inside or outside an anaconda environment
898
- if [[ ! -z " $CONDA_DEFAULT_ENV " ]]; then # Inside environment
899
-
900
- # Fix PATH and PYTHONPATH
901
- _ros_conda_path_fix_inside
902
- _ros_conda_pythonpath_fix_inside
903
- else
898
+ local sourced_path_absolute=" $( cd $( dirname ${sourced_path} ) 2> /dev/null && pwd -P) /$( basename ${sourced_path} ) "
899
+ if [[ -e " $sourced_path_absolute " ]]; then
900
+
901
+ # Get main catkin_ws path
902
+ local catkin_ws_path=" $( dirname $( dirname ${sourced_path_absolute} ) ) "
904
903
905
- # Fix PATH and PYTHONPATH
906
- _ros_conda_path_fix_outside
907
- _ros_conda_pythonpath_fix_outside
904
+ # Check if sourced file was inside catkin_ws
905
+ if [[ -e " ${catkin_ws_path} /.catkin_workspace" || -e " ${catkin_ws_path} /.catkin_tools" ]]; then
906
+
907
+ # Check if your inside or outside an anaconda environment
908
+ if [[ ! -z " $CONDA_DEFAULT_ENV " ]]; then # Inside environment
909
+
910
+ # Fix PATH and PYTHONPATH
911
+ _ros_conda_path_fix_inside
912
+ _ros_conda_pythonpath_fix_inside
913
+ else
914
+
915
+ # Fix PATH and PYTHONPATH
916
+ _ros_conda_path_fix_outside
917
+ _ros_conda_pythonpath_fix_outside
918
+ fi
908
919
fi
909
920
fi
910
921
fi
@@ -938,7 +949,7 @@ function _ros_conda_dot_source_wrapper() {
938
949
local had_error=false
939
950
940
951
# Execute source command
941
- \. " $@ " 2> /dev/null || had_error=true
952
+ \. " $@ " || had_error=true
942
953
943
954
# Fix paths if source was successful
944
955
if [[ " $had_error " == false ]]; then
@@ -960,40 +971,34 @@ function _ros_conda_dot_source_wrapper() {
960
971
961
972
# Execute source command
962
973
local had_error=false
963
- \. " $@ " 2> /dev/null || had_error=true
974
+ \. " $@ " || had_error=true
964
975
965
976
# Fix paths if source was successful
966
977
if [[ " $had_error " == false ]]; then
967
978
968
979
# Get full path
969
980
local sourced_path=" $1 "
970
- case sourced_path in
971
- /* )
972
- local sourced_path_absolute=" $sourced_path "
973
- ;;
974
- ./* )
975
-
976
- local sourced_path_absolute=" ${PWD} /${sourced_path: 2} "
977
- ;;
978
- * )
979
- local sourced_path_absolute=" ${PWD} /${sourced_path} "
980
- ;;
981
- esac
982
-
983
- # Check if sourced file was inside catkin_ws
984
- if [[ -e " $( dirname $( dirname " ${sourced_path_absolute} " ) ) /.catkin_workspace" ]]; then
985
-
986
- # Check if your inside or outside an anaconda environment
987
- if [[ ! -z " $CONDA_DEFAULT_ENV " ]]; then # Inside environment
988
-
989
- # Fix PATH and PYTHONPATH
990
- _ros_conda_path_fix_inside
991
- _ros_conda_pythonpath_fix_inside
992
- else
981
+ local sourced_path_absolute=" $( cd $( dirname ${sourced_path} ) 2> /dev/null && pwd -P) /$( basename ${sourced_path} ) "
982
+ if [[ -e " $sourced_path_absolute " ]]; then
983
+
984
+ # Get main catkin_ws path
985
+ local catkin_ws_path=" $( dirname $( dirname ${sourced_path_absolute} ) ) "
986
+
987
+ # Check if sourced file was inside catkin_ws
988
+ if [[ -e " ${catkin_ws_path} /.catkin_workspace" || -e " ${catkin_ws_path} /.catkin_tools" ]]; then
993
989
994
- # Fix PATH and PYTHONPATH
995
- _ros_conda_path_fix_outside
996
- _ros_conda_pythonpath_fix_outside
990
+ # Check if your inside or outside an anaconda environment
991
+ if [[ ! -z " $CONDA_DEFAULT_ENV " ]]; then # Inside environment
992
+
993
+ # Fix PATH and PYTHONPATH
994
+ _ros_conda_path_fix_inside
995
+ _ros_conda_pythonpath_fix_inside
996
+ else
997
+
998
+ # Fix PATH and PYTHONPATH
999
+ _ros_conda_path_fix_outside
1000
+ _ros_conda_pythonpath_fix_outside
1001
+ fi
997
1002
fi
998
1003
fi
999
1004
fi
0 commit comments