edc / bass

Make Bash utilities usable in Fish shell
MIT License
2.2k stars 70 forks source link

Unable to source a bash file #59

Closed JeremyBYU closed 5 years ago

JeremyBYU commented 5 years ago

I found this bash file online and am trying to source it with bass. It basically allows anaconda and ROS to coexist together; basically just modified python path and path env variables. However it doesnt seem to working when used with bash. Is the script to complicated to being converted for bass?

Script:

#!/bin/bash

### This script wraps all executables in the anaconda bin folder so that they can be used without adding Anaconda
### to the path which would break some functionality of ROS (Robot Operating System)
###
### The commands e.g. jupyter notebook will cause the script to add anaconda to the path, start jupyter notebook
### and after jupyter notebook terminated remove anaconda from the path again
###
### Notable commands:
### * release-the-snake       Adds conda to the path and removes all aliases defined by this script
###                           Conda will stay in the PATH until the end of the session (terminal is closed) or
###                           until "cage-the-snake" is called
### * cage-the-snake          Removes conda from the path and redefines all aliases for anaconda executables
### * source activate [env]   Works just like with anaconda in the PATH, will activate the environment or (root) and
###                           Anaconda will stay in the PATH for the remaining session or until "source deactivate" is run
### * source deactivate       Deactivates the environment and if Anaconda wasn't released manually using release-the-snake
###                           Anaconda will be removed from the PATH again.

if [ -z ${_ROS_CONDA_ADDED+x} ]
then
  _ROS_CONDA_PATH=~/miniconda3/bin
  _ROS_CONDA_ADDED=0
  _ROS_CONDA_ALIASES=''
  _ROS_CONDA_RELEASED_MANUALLY=0
  _ROS_CONDA_PYTHONPATH_WITHOUT_ROS=$PYTHONPATH
fi

function _ROS_CONDA_addAliases {
  if [[ $_ROS_CONDA_ALIASES != '' ]]
  then
    echo "ROS Conda Wrapper: Error! Aliases already defined!"
    _ROS_CONDA_removeAliases
  fi

  for file in $_ROS_CONDA_PATH/*
  do
    local name
    name=${file##*/}
    if ! [ -x "$(command -v $name)" ]
    then
      alias $name='_ROS_CONDA_runWithConda '$name' $@'
      _ROS_CONDA_ALIASES=$_ROS_CONDA_ALIASES" "$name
    fi
  done
}

function _ROS_CONDA_removeAliases {
  for cmd in $_ROS_CONDA_ALIASES
  do
    unalias $cmd
  done
  _ROS_CONDA_ALIASES=''
}

function _ROS_CONDA_runWithConda {
  _ROS_CONDA_ensureCondaInPath
  command $@
  _ROS_CONDA_removeCondaFromPath
}

function _ROS_CONDA_ensureCondaInPath {
  if [ $_ROS_CONDA_ADDED -eq 1 ]
  then
    return 1 # false
  fi
  _ROS_CONDA_ADDED=1

  # Check that the path doesn't start, end or contain the ros conda path
  if [[  $PATH != $_ROS_CONDA_PATH":"* && $PATH != *":"$_ROS_CONDA_PATH && $PATH != *":"$_ROS_CONDA_PATH":"* ]]
  then
    export PATH=$_ROS_CONDA_PATH:$PATH
    # Backup and clear python path to keep ros from checking ros directories for python modules
    _ROS_CONDA_PYTHONPATH_BACKUP=$PYTHONPATH
    export PYTHONPATH=$_ROS_CONDA_PYTHONPATH_WITHOUT_ROS

    # Unalias the stuff
    _ROS_CONDA_removeAliases

    return 0 # true
  fi
  return 1
}

function _ROS_CONDA_removeCondaFromPath {
  if [[ $PATH = $_ROS_CONDA_PATH":"* ]]
  then
    export PATH=${PATH#$_ROS_CONDA_PATH:}
  elif [[ $PATH = *":"$_ROS_CONDA_PATH ]]
  then
    export PATH=${PATH%:$_ROS_CONDA_PATH}
  elif [[ $PATH = *":"$_ROS_CONDA_PATH":"* ]]
  then
    export PATH=${PATH//:$_ROS_CONDA_PATH:/:}
  fi

  if [ $_ROS_CONDA_ADDED -eq 1 ]
  then
    # Restore ROS PYTHONPATH
    export PYTHONPATH=$_ROS_CONDA_PYTHONPATH_BACKUP
    _ROS_CONDA_addAliases
  fi

  _ROS_CONDA_ADDED=0
}

function _ROS_CONDA_sourceWrapper {
  if [ $1 == "activate" ]
  then
    _ROS_CONDA_ensureCondaInPath
    if [ $# == 1 ]
    then
    # If only source activate call source activate root.
    # Otherwise it will fail. Don't know why though
      command source activate
    else
      command source $@
    fi
  elif [ $1 == "deactivate" ]
  then
    command source deactivate
    if [ $_ROS_CONDA_RELEASED_MANUALLY -eq 0 ]
    then
      _ROS_CONDA_removeCondaFromPath
    fi
  else
    command source $@
  fi
}

if [ $_ROS_CONDA_ADDED -eq 0 ]
then
  if [[ $_ROS_CONDA_ALIASES != '' ]]
  then
    _ROS_CONDA_removeAliases
  fi
  _ROS_CONDA_addAliases
fi

alias source='_ROS_CONDA_sourceWrapper'
alias release-the-snake='_ROS_CONDA_RELEASED_MANUALLY=1; if _ROS_CONDA_ensureCondaInPath; then echo "All hail the snake!"; else echo "The snake is in another castle!
Jk, you released it already."; fi'
alias cage-the-snake='_ROS_CONDA_RELEASED_MANUALLY=0; _ROS_CONDA_removeCondaFromPath; echo "The snake has been caged if it wasn'"'"'t already."'

Error when running bass source FILE_NAME.bash

 (line 1): $@ is not supported. In fish, please use $argv.
function activate --wraps _ROS_CONDA_runWithConda --description 'alias activate=_ROS_CONDA_runWithConda activate $@';  _ROS_CONDA_runWithConda activate $@ $argv; end
                                                                                                                                                         ^
from sourcing file -
    called on line 71 of file /usr/share/fish/functions/alias.fish

in function “alias”
    called on line 3 of file -
    with parameter list “activate=_ROS_CONDA_runWithConda activate $@”

from sourcing file -
    called on line 15 of file ~/.config/fish/functions/bass.fish

in function “bass”
    called on standard input
    with parameter list “source /home/jeremy/.anaconda_with_ros_wrapper.bash”

source: Error while reading file “-”
- (line 1): $@ is not supported. In fish, please use $argv.
function deactivate --wraps _ROS_CONDA_runWithConda --description 'alias deactivate=_ROS_CONDA_runWithConda deactivate $@';  _ROS_CONDA_runWithConda deactivate $@ $argv; end
                                                                                                                                                                 ^
from sourcing file -
    called on line 71 of file /usr/share/fish/functions/alias.fish

in function “alias”
    called on line 5 of file -
    with parameter list “deactivate=_ROS_CONDA_runWithConda deactivate $@”

from sourcing file -
    called on line 15 of file ~/.config/fish/functions/bass.fish

in function “bass”
    called on standard input
    with parameter list “source /home/jeremy/.anaconda_with_ros_wrapper.bash”

source: Error while reading file “-”
- (line 1): Expected end of the statement, but instead found a string
function release-the-snake --wraps _ROS_CONDA_RELEASED_MANUALLY=1 --description alias\ release-the-snake=_ROS_CONDA_RELEASED_MANUALLY=1\;\ if\ _ROS_CONDA_ensureCondaInPath\;\ then\ echo\ \"All\ hail\ the\ snake!\"\;\ else\ echo\ \"The\ snake\ is\ in\ another\ castle!\nJk,\ you\ released\ it\ already.\"\;\ fi;  _ROS_CONDA_RELEASED_MANUALLY=1; if _ROS_CONDA_ensureCondaInPath; then echo "All hail the snake!"; else echo "The snake is in another castle! $argv; end
                                                                                                                                                                                                                                                                                                                                                                                                                               ^
from sourcing file -
    called on line 71 of file /usr/share/fish/functions/alias.fish

in function “alias”
    called on line 6 of file -
    with parameter list “release-the-snake=_ROS_CONDA_RELEASED_MANUALLY=1; if _ROS_CONDA_ensureCondaInPath; then echo "All hail the snake!"; else echo "The snake is in another castle!
Jk, you released it already."; fi”

from sourcing file -
    called on line 15 of file ~/.config/fish/functions/bass.fish

in function “bass”
    called on standard input
    with parameter list “source /home/jeremy/.anaconda_with_ros_wrapper.bash”

source: Error while reading file “-”
edc commented 5 years ago

The immediate issue is that we need to replace $@ with $argv when translating bash alias to fish, but that won't get us very far: because of the way it works, Bass' support of alias is very basic. In this script, the aliases wraps around bash functions, and it's not easy to get it to work nicely.

My suggestion is you change the script and replace aliases with functions, and then you can use something like bass source foo.sh ';' func1 to invoke individual function. I tested the following simple script, and it seemed to work:

# foo.sh
function x {
  echo "in function x:" $@
}

function y {
  x $@
}

Invoking bass source /tmp/x.bash ';' y arg1 arg2 arg3, and I get:

in function x: arg1 arg2 arg3
JeremyBYU commented 5 years ago

Thank you for your input.