From ba42e681640ab3e9467d7d966dec00f2f832d477 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Laurent?= <francois.laurent@posteo.net>
Date: Tue, 12 Nov 2024 22:27:46 +0100
Subject: [PATCH] feat(install.sh): --free-python-dependencies flag

---
 scripts/install.sh  | 194 ++++++++++++++++++++++++++++++++------------
 scripts/larvatagger |   4 +-
 2 files changed, 144 insertions(+), 54 deletions(-)

diff --git a/scripts/install.sh b/scripts/install.sh
index fead1e9..994b588 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -6,6 +6,7 @@ if [ -z "$BIN_DIR" ]; then
   BIN_DIR=~/.local/bin
 else
   echo "Using environment variable: BIN_DIR= $BIN_DIR"
+  echo "Only ~/.local/bin is fully supported at the moment"
 fi
 if [ -z "$LARVATAGGER_PATH" ]; then
   LARVATAGGER_PATH=~/.local/share/larvatagger
@@ -22,6 +23,21 @@ if [ "$1" = "--uninstall" ]; then
   done
   rm -rf "$BIN_DIR/larvatagger"
   rm -rf "$LARVATAGGER_PATH"
+
+  # testing only; does not apply to all platforms; do not pass the --full option!
+  if [ "$2" = "--full" ]; then
+    PYTHON="python3"
+    if [[ "`python3 -V`" =~ "Python 3.6" ]] && command -v python3.8 &>/dev/null; then
+      # issue on Maestro
+      PYTHON="python3.8"
+    fi
+    command -v poetry &>/dev/null && curl -sSL https://install.python-poetry.org | $PYTHON - --uninstall
+    command -v pyenv &>/dev/null && rm -rf $(pyenv root)
+    command -v juliaup &>/dev/null && juliaup self uninstall
+    rm -rf ~/.juliaup
+    # TODO: clean up .bash_profile for pyenv-related stuff and restart the shell
+    rm -rf ~/.julia
+  fi
 else
 
 PYTHON_VERSION=3.8
@@ -30,6 +46,7 @@ PYTHON_VERSION=3.8
 # determine whether or not to report externally sourced variables
 internal_WITH_BACKEND=
 internal_MAGGOTUBA_ADAPTER_BRANCH=
+internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES=
 for arg in "$@"; do
   if [ "$arg" = "--with-default-backend" ]; then
     WITH_BACKEND=1
@@ -45,9 +62,13 @@ for arg in "$@"; do
     MAGGOTUBA_ADAPTER_BRANCH=torch2
     internal_MAGGOTUBA_ADAPTER_BRANCH=1
     PYTHON_VERSION=3.11
+  elif [ "$arg" = "--free-python-dependencies" ]; then
+    internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES=1
   fi
 done
 
+PYTHON="python$PYTHON_VERSION"
+
 if ! command -v curl &>/dev/null; then
   if command -v brew &>/dev/null; then
     # macOS users are not given the choice as they usually do not care about freedom
@@ -76,20 +97,97 @@ if ! command -v realpath &>/dev/null; then
   fi
 fi
 
-if ! command -v julia &>/dev/null; then
+if [ -z "$JULIA_VERSION" ]; then
+  JULIA_VERSION=1.10
+else
+  echo "Using environment variable: JULIA_VERSION= $JULIA_VERSION"
+fi
+
+JULIA="julia"
+
+install_juliaup() {
   if [ -z "$JULIA_INSTALL_ARGS" ]; then
     JULIA_INSTALL_ARGS=-y
   else
     echo "Using environment variable: JULIA_INSTALL_ARGS= $JULIA_INSTALL_ARGS"
   fi
-  curl -fsSL https://install.julialang.org | sh -s -- $JULIA_INSTALL_ARGS
-  if [ -f ~/.bashrc ]; then
+  curl -fsSL https://install.julialang.org | sh -s -- $JULIA_INSTALL_ARGS --default-channel $JULIA_VERSION
+  if [ -f ~/.bashrc -a -n "`grep "# >>> juliaup initialize >>>" ~/.bashrc`" ]; then
     source ~/.bashrc
-  elif [ -f ~/.bash_profile ]; then
+  elif [ -f ~/.bash_profile -a -n "`grep "# >>> juliaup initialize >>>" ~/.bash_profile`" ]; then
     source ~/.bash_profile
   fi
+}
+if ! command -v $JULIA &>/dev/null; then
+  install_juliaup
+elif ! [[ "`$JULIA -v`" =~ "julia version $JULIA_VERSION" ]]; then
+  install_juliaup
 fi
 
+add_local_bin_to_path() {
+  if [ "`realpath $BIN_DIR`" = "`realpath ~/.local/bin`" ]; then
+    # ~/.local/bin not in $PATH?
+    if [ "$SHELL" = "/bin/zsh" ]; then
+      rcfile=~/.zshrc
+    elif [ "$SHELL" = "/bin/bash" ]; then
+      if [ -f ~/.bashrc ]; then
+        rcfile=~/.bashrc
+      elif [ -f ~/.bash_profile ]; then
+        rcfile=~/.bash_profile
+      fi
+    fi
+    echo "Extending the PATH environment variable in $rcfile"
+    cat <<"EOF" >>$rcfile
+
+export PATH=$PATH:~/.local/bin
+EOF
+  else
+    echo "the larvatagger command is available in directory:"
+    echo "  $BIN_DIR"
+    echo "consider adding the directory to the PATH variable"
+  fi
+  export PATH=$PATH:$BIN_DIR
+}
+
+install_pyenv_on_ubuntu2004() {
+  echo
+  echo "INFO: installing pyenv and its dependencies"
+  echo
+  if ! [ -d ~/.pyenv ]; then
+    sudo apt-get update
+    sudo apt-get install --no-install-recommends curl build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev xz-utils libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev #tk-dev
+    curl https://pyenv.run | bash
+  fi
+  export PATH=~/.pyenv/bin:$PATH
+  eval "$(~/.pyenv/bin/pyenv init -)"
+  cat <<"EOF" >>~/.bash_profile
+
+command -v pyenv &>/dev/null || export PATH=~/.pyenv/bin:$PATH
+eval "$(~/.pyenv/bin/pyenv init -)"
+EOF
+  pyenv install $PYTHON_VERSION
+}
+
+install_pyenv() {
+  echo
+  echo "INFO: installing pyenv"
+  echo
+  if ! [ -d ~/.pyenv ]; then
+    curl https://pyenv.run | bash
+  fi
+  if ! command -v pyenv &>/dev/null; then
+    export PATH=~/.pyenv/bin:$PATH
+    eval "$(~/.pyenv/bin/pyenv init -)"
+    cat <<"EOF" >>~/.bash_profile
+
+command -v pyenv &>/dev/null || export PATH=~/.pyenv/bin:$PATH
+eval "$(~/.pyenv/bin/pyenv init -)"
+EOF
+  fi
+  pyenv install $PYTHON_VERSION
+  pyenv shell $PYTHON_VERSION
+}
+
 if [ -n "$WITH_BACKEND" ]; then
   if [ "`uname`" = "Darwin" ]; then
     echo "WARNING: the default tagging backend is not supported by macOS"
@@ -98,28 +196,18 @@ if [ -n "$WITH_BACKEND" ]; then
     if command -v pyenv &>/dev/null; then
       [ `pyenv versions | grep $PYTHON_VERSION` ] || pyenv install $PYTHON_VERSION
     elif [[ "`uname -r`" =~ "-microsoft-standard-WSL2" ]]; then
-      echo
-      echo "INFO: installing pyenv and its dependencies"
-      echo
-      if ! [ -d ~/.pyenv ]; then
-        sudo apt-get update
-        sudo apt-get install --no-install-recommends curl build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev xz-utils libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev #tk-dev
-        curl https://pyenv.run | bash
-      fi
-      export PATH=~/.pyenv/bin:$PATH
-      eval "$(~/.pyenv/bin/pyenv init -)"
-      cat <<"EOF" >>~/.bashrc
-
-command -v pyenv &>/dev/null || export PATH=~/.pyenv/bin:$PATH
-eval "$(~/.pyenv/bin/pyenv init -)"
-EOF
-      pyenv install $PYTHON_VERSION
+      install_pyenv_on_ubuntu2004
+    elif [[ "`hostname`" =~ ".cluster.embl.de" ]]; then
+      install_pyenv
+    elif [ "`hostname`" = "maestro-submit" ]; then
+      # we could use `module load Python/<version>` but modules are removed without notice
+      install_pyenv
     else
       check_brew
       if command -v brew &>/dev/null; then
         brew install python@$PYTHON_VERSION
       else
-        echo "WARNING: command python$PYTHON_VERSION not found"
+        echo "WARNING: command $PYTHON not found"
       fi
     fi
   fi
@@ -127,7 +215,9 @@ EOF
     if command -v pipx &>/dev/null; then
       pipx install poetry
     else
-      curl -fsSL https://install.python-poetry.org | python3 -
+      # explicit Python version for Maestro
+      curl -fsSL https://install.python-poetry.org | $PYTHON -
+      command -v poetry &>/dev/null || add_local_bin_to_path
     fi
   fi
 fi
@@ -158,8 +248,8 @@ else
   curl -fsSL https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/archive/${LARVATAGGER_BRANCH}/larvatagger.jl-${LARVATAGGER_BRANCH}.tar.gz | tar zxv
   mv larvatagger.jl-${LARVATAGGER_BRANCH} LarvaTagger.jl
 fi
-(cd LarvaTagger.jl && julia --project=. -e 'using Pkg; Pkg.instantiate()')
-[ -d PlanarLarvae ] && (cd LarvaTagger.jl && julia --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae")')
+(cd LarvaTagger.jl && $JULIA --project=. -e 'using Pkg; Pkg.instantiate()')
+[ -d PlanarLarvae ] && (cd LarvaTagger.jl && $JULIA --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae")')
 
 if [ -z "$WITH_BACKEND" ]; then
 
@@ -167,7 +257,16 @@ mkdir -p "$BIN_DIR"
 cat <<EOF >"$BIN_DIR"/larvatagger
 #!/usr/bin/env bash
 
+if command -v juliaup &>/dev/null; then
+  PREVIOUS_CHANNEL=\`juliaup status | grep '*' | cut -d'*' -f2 | cut -d\\  -f3\`
+  juliaup default $JULIA_VERSION &>/dev/null
+fi
+
 OPEN_BROWSER=1 "$LARVATAGGER_PATH/LarvaTagger.jl/scripts/larvatagger" \$@
+
+if command -v juliaup &>/dev/null; then
+  juliaup default \$PREVIOUS_CHANNEL &>/dev/null
+fi
 EOF
 
 else
@@ -191,8 +290,8 @@ else
   curl -fsSL https://gitlab.pasteur.fr/nyx/TaggingBackends/-/archive/${TAGGINGBACKENDS_BRANCH}/TaggingBackends-${TAGGINGBACKENDS_BRANCH}.tar.gz | tar zxv
   mv TaggingBackends-${TAGGINGBACKENDS_BRANCH} TaggingBackends
 fi
-(cd TaggingBackends && julia --project=. -e 'using Pkg; Pkg.instantiate()')
-[ -d PlanarLarvae ] && (cd TaggingBackends && julia --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae")')
+(cd TaggingBackends && activate && PYTHON=`command -v python` && $JULIA --project=. -e 'using Pkg; Pkg.instantiate()')
+[ -d PlanarLarvae ] && (cd TaggingBackends && $JULIA --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae")')
 (cd TaggingBackends && activate && JULIA_PROJECT=$(pwd) poetry install)
 
 if [ -d MaggotUBA-core ]; then
@@ -221,46 +320,37 @@ else
 fi
 # setting JULIA_PROJECT may not be necessary at this point
 export JULIA_PROJECT=$(realpath TaggingBackends)
-(cd MaggotUBA && activate && (cat requirements.txt | xargs -I % sh -c 'poetry add "%"' || true) && poetry install -v)
+
+if [ -z "$internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES" ]; then
+  (cd MaggotUBA && activate && (cat requirements.txt | xargs -I % sh -c 'poetry add "%"' || true) && poetry install -v)
+else
+  (cd MaggotUBA && activate && poetry install -v)
+fi
 [ -d TaggingBackends ] && (cd MaggotUBA && activate && poetry remove taggingbackends && poetry add ../TaggingBackends)
 [ -d MaggotUBA-core ] && (cd MaggotUBA && activate && poetry remove maggotuba-core && poetry add ../MaggotUBA-core)
-(cd MaggotUBA && scripts/make_models.jl default)
+(cd MaggotUBA && scripts/make_models.jl default) # julia version does not matter here
 
 mkdir -p "$BIN_DIR"
 cat <<EOF >"$BIN_DIR"/larvatagger
 #!/usr/bin/env bash
 
+if command -v juliaup &>/dev/null; then
+  PREVIOUS_CHANNEL=\`juliaup status | grep '*' | cut -d'*' -f2 | cut -d\\  -f3\`
+  juliaup default $JULIA_VERSION &>/dev/null
+fi
+
 JULIA_PROJECT="$(realpath "$LARVATAGGER_PATH/TaggingBackends")" BACKENDS_PATH="$LARVATAGGER_PATH" OPEN_BROWSER=1 "$LARVATAGGER_PATH/LarvaTagger.jl/scripts/larvatagger" \$@
+
+if command -v juliaup &>/dev/null; then
+  juliaup default \$PREVIOUS_CHANNEL &>/dev/null
+fi
 EOF
 
 fi
 
 chmod a+x "$BIN_DIR/larvatagger"
 
-if ! command -v larvatagger &>/dev/null; then
-  if [ "`realpath $BIN_DIR`" = "`realpath ~/.local/bin`" ]; then
-    # ~/.local/bin not in $PATH?
-    if [ "$SHELL" = "/bin/zsh" ]; then
-      rcfile=~/.zshrc
-    elif [ "$SHELL" = "/bin/bash" ]; then
-      if [ -f ~/.bashrc ]; then
-        rcfile=~/.bashrc
-      elif [ -f ~/.bash_profile ]; then
-        rcfile=~/.bash_profile
-      fi
-    fi
-    echo "Extending the PATH environment variable in $rcfile"
-    cat <<"EOF" >>$rcfile
-
-export PATH=$PATH:~/.local/bin
-EOF
-  else
-    echo "the larvatagger command is available in directory:"
-    echo "  $BIN_DIR"
-    echo "consider adding the directory to the PATH variable"
-  fi
-  export PATH=$PATH:$BIN_DIR
-fi
+command -v larvatagger &>/dev/null || add_local_bin_to_path
 
 ##
 popd
diff --git a/scripts/larvatagger b/scripts/larvatagger
index db34a6c..b46c90c 100755
--- a/scripts/larvatagger
+++ b/scripts/larvatagger
@@ -23,10 +23,10 @@ open)
   shift
   ltargs=
   if [ -n "$BACKENDS_PATH" ]; then
-    ltargs="--backends=\"$BACKENDS_PATH\" $args"
+    ltargs="--backends=\"$BACKENDS_PATH\" $ltargs"
   fi
   if [ -n "$OPEN_BROWSER" ]; then
-    ltargs="--browser $args"
+    ltargs="--browser $ltargs"
   fi
   eval "\"$currentdir/larvatagger-gui.jl\" $jlargs\"$datapath\" $ltargs$@"
   ;;
-- 
GitLab