Skip to content

Commit

Permalink
Merge pull request #26 from xavierabellan/feature/activate-deactivate
Browse files Browse the repository at this point in the history
Proposal to add tykky shell convenience function to activate and deactivate environments
  • Loading branch information
Nortamo authored Oct 3, 2024
2 parents ac139a6 + 423b0f0 commit f09158f
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 4 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,25 @@ How verbosely to report program actions
- 2 general (default)
- `>2` debug
## Activating and Deactivating wrapped environments
A `tykky` convenience shell function is provided to mimic the conda activate and
deactivate helpers. To use it, you must load those functions into your shell with:
`source etc/profile.d/tykky`
Then you may activate a tykky installation with
`tykky activate <env_dir>`
If you define the environment variable `TYKKY_PATH`, environments may also be
found by name inside that colon-separated list of paths in `TYKKY_PATH`.
You may deactivate the tykky environment in your shell with:
`tykky deactivate`
Alternatively, you may also manually add `<env_dir>/bin` to your `$PATH`.
## Misc features ideas
Expand Down
36 changes: 36 additions & 0 deletions etc/bash_completion.d/tykky_completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
__tykky_completions() {
if [ "${#COMP_WORDS[@]}" == "2" ]; then
COMPREPLY=($(compgen -W "activate deactivate" "${COMP_WORDS[1]}"))
return
fi
if [[ ${#COMP_WORDS[@]} -gt 2 ]]; then
if [[ "${COMP_WORDS[1]}" == "activate" && "${COMP_WORDS[2]}" != *"/"* ]]; then
local __tykky_env_list=""
local __tykky_path __candidate
local oldIFS=$IFS
IFS=:
for __tykky_path in ${TYKKY_PATH:-~/.tykky}; do
IFS=$oldIFS
for __candidate in $__tykky_path/*; do
if [[ -d "$__candidate" && -f "$__candidate/common.sh" && -d "$__candidate/bin" ]]; then
__tykky_env_list+="$(basename $__candidate) "
fi
done
done
COMPREPLY=($(compgen -W "$__tykky_env_list" "${COMP_WORDS[2]}"))
return
elif [[ "${COMP_WORDS[1]}" == "activate" && "${COMP_WORDS[2]}" == *"/"* ]]; then
COMPREPLY=( $(compgen -d -- "${COMP_WORDS[2]}") )
local i
for i in "${!COMPREPLY[@]}"; do
if [[ -d "${COMPREPLY[$i]}" && ! -f "${COMPREPLY[$i]}/common.sh" && ! -d "${COMPREPLY[$i]}/bin" ]]; then
COMPREPLY[$i]="${COMPREPLY[$i]}/"
fi
done
compopt -o nospace
fi
fi
return
}

complete -F __tykky_completions tykky
42 changes: 42 additions & 0 deletions etc/profile.d/tykky.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Tykky shell functions to activate/deactivate environments

__tykky_dir=""
if [ -n "${BASH_SOURCE:-}" ]; then
__tykky_dir="$(dirname "${BASH_SOURCE[0]}")"
elif [ -n "${ZSH_VERSION:-}" ]; then
__tykky_dir="$(dirname "${(%):-%N}")"
elif [ -n "${KSH_VERSION:-}" ]; then
__tykky_dir="$(dirname "${.sh.file}")"
else
# Generic POSIX shell case or dash
__tykky_dir="$(dirname "$0")"
fi

__tykky_dir="$(realpath $(dirname $(dirname "$__tykky_dir")))"

# Add the tykky tools to PATH if not present
if [ "${PATH#*$__tykky_dir/bin:}" = "$PATH" ]; then
export PATH="$__tykky_dir/bin:$PATH"
fi

# Make available tykky functions for this shell and subshells
for __function in $__tykky_dir/share/sh_functions/*; do
source $__function
if [ -z "$KSH_VERSION" ]; then
export -f $(basename $__function)
fi
done
unset __function

# KSH does not support exporting functions
if [ "${FPATH#*$__tykky_dir/share/sh_functions:}" = "$FPATH" ]; then
export FPATH="$__tykky_dir/share/sh_functions:$FPATH"
fi

# Enable BASH autocompletion
if [ -n "${BASH_VERSIONi:-}" ] && [ -n "${PS1:-}" ]; then
__tykky_bash_completion_file="$_tykky_dir/etc/bash_completion.d/tykky_completion"
[ -f "$__tykky_bash_completion_file" ] && . "$__tykky_bash_completion_file"
unset __tykky_bash_completion_file
fi
unset __tykky_dir
27 changes: 23 additions & 4 deletions frontends/containerize
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,27 @@ fi
$M_SCRIPT_DIR/../post.sh || { print_err "Failed to move to install dir"; false ; }
test -f "$_usr_yaml" && rm "$_usr_yaml"
end=`date +%s`
print_info "Done, duration: $((end-start))s" 1
print_info "Program has been installed to $CW_INSTALLATION_PREFIX
\tTo use add the bin folder to your path e.g:
\texport PATH=\"$_inst_path/bin:\$PATH\"" 1


if command -v tykky &>/dev/null ; then
_env_root=$(realpath $(dirname $_inst_path))
_env_name=$CW_INSTALLATION_PREFIX
IFS=':' read -r -a _paths <<< "${TYKKY_PATH:-$HOME/.tykky}"
for _path in "${_paths[@]}"; do
if [ "$_env_root" = "$(realpath $_path)" ]; then
_env_name=$(basename $CW_INSTALLATION_PREFIX)
break
fi
done
info_msg="Environment has been installed to $CW_INSTALLATION_PREFIX
\tTo use, activate with:
\ttykky activate $_env_name
\tAlternatively, add the bin folder to your path e.g:
\texport PATH=\"$_inst_path/bin:\$PATH\""
else
info_msg="Program has been installed to $CW_INSTALLATION_PREFIX
\tTo use add the bin folder to your path e.g:
\texport PATH=\"$_inst_path/bin:\$PATH\""
fi
print_info "Done, duration: $((end-start))s" 1
print_info "$info_msg" 1
25 changes: 25 additions & 0 deletions share/sh_functions/__tykky_activate
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Tykky shell functions to activate/deactivate environments
__tykky_activate() {
# Activate a Tykky environment. Change PS1 if interactive by default,
# unless TYKKY_CHANGE_PS1 is set to 0

if [ -z "${2:-}" ]; then
echo "ERROR: You must specify a valid tykky environment to activate" >&2
false
return
fi
__candidate=$(__tykky_get_env_path $2)
if [ "$?" -ne 0 ]; then
false
return
fi
if [ -n "$__candidate" ]; then
__tykky_deactivate
export TYKKY_PREFIX="$(realpath $__candidate)"
export PATH=$TYKKY_PREFIX/bin:$PATH
if [ -n "${PS1:-}" ] && [ "${TYKKY_CHANGE_PS1:-}" != "0" ]; then
PS1="($(basename $(echo $TYKKY_PREFIX))) $PS1"
fi
fi
unset __candidate
}
13 changes: 13 additions & 0 deletions share/sh_functions/__tykky_deactivate
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Tykky shell functions to activate/deactivate environments
__tykky_deactivate() {
# Deactivate a Tykky environment. Change PS1 if interactive by default,

if [ -n "${TYKKY_PREFIX:-}" ]; then
export PATH=$(echo $PATH | sed -e "s|$TYKKY_PREFIX/bin:||g")
if [ -n "${PS1:-}" ]; then
PS1="$(echo "$PS1" | sed -e "s|^($(basename $TYKKY_PREFIX)) ||")"
fi
unset TYKKY_PREFIX
fi
}

68 changes: 68 additions & 0 deletions share/sh_functions/__tykky_get_env_path
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Tykky shell functions to activate/deactivate environments
__tykky_get_env_path() {
# Get and validate installation path of a tykky environment.
# If a name is passed as an argument, try to find it in colon-separated
# list TYKKY_PATH

__candidate=""
case "$1" in
*/*)
__candidate="${1%/}"
;;
*)
oldIFS=$IFS
IFS=:
for __tykky_path in ${TYKKY_PATH:-""}; do
IFS=$oldIFS
if [ -d "$__tykky_path/$1" ]; then
if [ -n "$__candidate" ]; then
echo "WARNING: Additional candidate tykky environments found in TYKKY_PATH for $1, only the first one will be considered" >&2
echo -e "\tfirst candidate: $__candidate" >&2
echo -e "\tnew candidate: $__tykky_path/$1" >&2
else
__candidate="${__tykky_path%/}/${1%/}"
fi
#break
fi
done
if [ -d "$1" ];then
# If there is a matching foldername in the current directory
# and the name does not match anyhing in tykky_path, also test that for convinience
# this is to be consistent with that the first case allows relative paths
# so then relative paths in the current directory withouth / should also work
if [ -z "$__candidate" ];then
__candidate=$PWD/$1

# Ambiguous reference as we might have multiple matches
else
_tp_candidate=$(readlink -f $__candidate)
_d_candidate=$(readlink -f $1)
# if same folder let's not emit a warning
# following pseudo standard -> command line arguments override environment settings
if [ ! "$_tp_candidate" = "$_d_candidate" ];then
echo "WARNING: Multiple candidate tykky environments for $1, activating the one in the current directory" >&2
echo -e "\tfrom TYKKY_PATH: $_tp_candidate" >&2
echo -e "\tfrom current directory: $_d_candidate" >&2
fi

fi
fi

;;
esac

# Validation of genunine tykky installation
if [ -f "$__candidate/common.sh" ] && [ -d "$__candidate/bin" ]; then
echo "$__candidate"
unset __candidate __tykky_path
else
unset __candidate __tykky_path
echo "ERROR: $1 is not a valid tykky environment" >&2
if [ ! -d "$1" ] ; then
echo -e "\t$1 does not exists or parent folder is not in TYKKY_PATH" >&2
echo -e "\tCurrent value: TYKKY_PATH=$TYKKY_PATH" >&2
fi
false
fi

}
17 changes: 17 additions & 0 deletions share/sh_functions/tykky
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Tykky shell functions to activate/deactivate environments
tykky() {
# Top level shell function to activate and deactivate Tykky environments

case "${1:-}" in
activate)
__tykky_activate "$@"
;;
deactivate)
__tykky_deactivate "$@"
;;
*)
echo "Usage: tykky activate <env_name_or_dir>"
echo " tykky deactivate"
;;
esac
}

0 comments on commit f09158f

Please sign in to comment.