Skip to content
This repository was archived by the owner on Nov 5, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions share/chpython/auto.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
unset PYTHON_AUTO_VERSION

function chpython_auto() {
local dir="$PWD/" version

until [[ -z "$dir" ]]; do
dir="${dir%/*}"

if { read -r version < "$dir/.python-version"; } 2>/dev/null || [[ -n "$version" ]]; then
version="${version%%[[:space:]]}"

if [[ "$version" == "$PYTHON_AUTO_VERSION" ]]; then return
else
PYTHON_AUTO_VERSION="$version"
chpython "$version"
return $?
fi
fi
done

if [[ -n "$PYTHON_AUTO_VERSION" ]]; then
chpython_reset
unset PYTHON_AUTO_VERSION
fi
}

if [[ -n "$ZSH_VERSION" ]]; then
if [[ ! "$preexec_functions" == *chpython_auto* ]]; then
preexec_functions+=("chpython_auto")
fi
elif [[ -n "$BASH_VERSION" ]]; then
trap '[[ "$BASH_COMMAND" != "$PROMPT_COMMAND" ]] && chpython_auto' DEBUG
fi
103 changes: 39 additions & 64 deletions share/chpython/chpython.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,94 +1,57 @@
CHPYTHON_VERSION='0.1.0.dev'
PYTHONS=()

[ -d "${HOME}/.pythons" ] && PYTHONS+=("${HOME}/.pythons"/*)
for dir in "$PREFIX/opt/pythons" "$HOME/.pythons"; do
[[ -d "$dir" && -n "$(ls -A "$dir")" ]] && PYTHONS+=("$dir"/*)
done
unset dir

function _chpython_exec {
local python
python=$1
shift
# TODO: Clear path so invoking `chpython 3.5 python -V` when
# $CHPYTHON_VERSION is set to a 2.x Python gives a command not
# found error instead of running $CHPYTHON_VERSION/bin/python.
env PATH="$python/bin:$PATH" $*
}

function _chpython_reset {
function chpython_reset() {
[ -z "$CHPYTHON_ROOT" ] && return
PATH=":$PATH:"
PATH=${PATH//:$CHPYTHON_ROOT\/bin:/:}
PATH=${PATH#:}; PATH=${PATH%:}

PATH=":$PATH:"; PATH=${PATH//:$CHPYTHON_ROOT\/bin:/:}
PATH="${PATH#:}"; PATH="${PATH%:}"
unset CHPYTHON_ROOT
hash -r
type python || type python3
}

function _chpython_select {
local dir python match
for dir in ${PYTHONS[@]}; do
dir=${dir%%/}
python=${dir##*/}
case "$python" in
"$1")
# Match using 3-part version number, e.g. `chruby 2.7.10`
match=$dir && break
;;
"$1"*)
# Match best using 2-part version number, e.g., `chpython 2.7`
match=$dir
;;
esac
done
echo "$match"
}

function _chpython_use {
if [[ ! -x "$1/bin/python" && ! -x "$1/bin/python3" ]]; then
echo "chpython: neither $1/bin/python nor $1/bin/python3 are executable" >&2
function _chpython_use() {
if [[ ! -x "$1/bin/python" ]]; then
echo "chpython: $1/bin/python is not executable" >&2
return 1
fi

# TODO: Alias *3 stuff to base name, so, e.g., `python` can be called
# instead of `python3`
[[ -n "$CHPYTHON_ROOT" ]] && chpython_reset

export CHPYTHON_ROOT=$1
export CHPYTHON_ROOT="$1"
export PATH="${CHPYTHON_ROOT}/bin:${PATH}"
local python_version
if [[ -e "$1/bin/python3" ]]; then
PYTHON_VERSION="$($1/bin/python --version)"
else
PYTHON_VERSION="$($1/bin/python --version 2>&1 | awk '{print $2}')"
fi
hash -r
type python || type python3
}

function chpython {

function chpython() {
case "$1" in
-h|--help)
cat <<EOS
Usage:
chpython [PYTHON|VERSION|system]
chpython exec [PYTHON|VERSION] args...
EOS
;;
-V|--version)
echo "chpython $CHPYTHON_VERSION"
;;
exec)
shift
local match
match=$(_chpython_select $1)
if [ -z "$match" ]; then
echo "chpython: unknown Python: $1" >&2
return 1
fi

shift
_chpython_exec $match $*
;;
system)
_chpython_reset
;;
system) chpython_reset ;;
'')
local dir python
for dir in ${PYTHONS[@]}; do
dir="${dir%%/}"
python=${dir##*/}
for dir in "${PYTHONS[@]}"; do
dir="${dir%%/}"; python="${dir##*/}"
if [[ "$dir" == "$CHPYTHON_ROOT" ]]; then
echo " * ${python}"
else
Expand All @@ -97,15 +60,27 @@ EOS
done
;;
*)
local match
match=$(_chpython_select $1)
local dir python match
for dir in "${PYTHONS[@]}"; do
dir="${dir%%/}"; python="${dir##*/}"
case "$python" in
"$1")
# Match using 3-part version number, e.g. `chruby 2.7.10`
match="$dir" && break
;;
"$1"*)
# Match best using 2-part version number, e.g., `chpython 2.7`
match="$dir"
;;
esac
done
if [ -z "$match" ]; then
echo "chpython: unknown Python: $1" >&2
return 1
fi

shift
_chpython_use $match $*
_chpython_use "$match"
;;
esac
}