Skip to content

Instantly share code, notes, and snippets.

@166MMX
Last active April 5, 2024 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 166MMX/10ab6d2840228d4308e8f78526c2b198 to your computer and use it in GitHub Desktop.
Save 166MMX/10ab6d2840228d4308e8f78526c2b198 to your computer and use it in GitHub Desktop.
work in progress intelligent - currently not so much - wip PATH manager
#!/usr/bin/env sh
set -e -u
# https://peterlyons.com/problog/2012/09/managing-per-project-interpreters-and-the-path/
# Function to append a directory to PATH if it exists
add_path() {
if [ -d "$1" ]; then
PATH="$PATH:$1"
fi
}
PROGRAM_FILES="$(cygpath --windows "$PROGRAMFILES")"
APP_DATA="$(cygpath --windows "$APPDATA")"
G_NODE_18="$APP_DATA/JetBrains/IntelliJIdea2022.3/node/node-v18.15.0-win-x64"
G_NODE_16="$APP_DATA/JetBrains/IntelliJIdea2022.3/node/node-v16.4.2-win-x64"
G_PYTHON_3_12="$PROGRAM_FILES/Python312/"
U_JAVA="$HOME/.jdks"
U_JAVA_21="$HOME/temurin-21.0.2"
U_JAVA_17="$HOME/temurin-17.0.10"
G_JAVA_8="$PROGRAM_FILES/Eclipse Adoptium/jdk-8.0.352.8-hotspot"
G_JAVA_17="$PROGRAM_FILES/Eclipse Adoptium/jdk-17.0.5.8-hotspot"
setup_homebrew() {
[ -d '/usr/local/bin' ] && PATH="/usr/local/bin:$PATH"
}
setup_java() {
PWD_JAVA_VERSION="$PWD/.java-version"
# Dynamically configure JAVA_HOME based on the project's Java version
# pom.xml - maven
# build.gradle - gradle
# .java-version - jenv
[ -f "$PWD_JAVA_VERSION" ] && {
read -r JAVA_VERSION < "$PWD_JAVA_VERSION"
}
[ -n "${JAVA_VERSION:}" ] && {
U_JAVA_VAR="U_JAVA_${JAVA_VERSION##.}"
G_JAVA_VAR="G_JAVA_${JAVA_VERSION##.}"
if [ -n "${!U_JAVA_VAR}" ]; then
JAVA_HOME="${!U_JAVA_VAR}"
elif [ -z "${!G_JAVA_VAR}" ]; then
JAVA_HOME="${!G_JAVA_VAR}"
elif [ -z "${G_JAVA:}" ]; then
JAVA_HOME="${G_JAVA:}"
else
JAVA_HOME=''
fi
export JAVA_HOME
add_path "$JAVA_HOME/bin"
}
}
setup_node() {
# package.json - node.js
# .node-version
# .nvmrc - nvm
# * https://github.com/nvm-sh/nvm?tab=readme-ov-file#nvmrc
# * https://github.com/tj/n?tab=readme-ov-file#specifying-nodejs-versions
# * https://github.com/shadowspawn/node-version-usage
# Project node_modules
## Node.js
add_path "$PWD/node_modules/.bin"
}
setup_python() {
## Global
G_PYTHON="$G_PYTHON_3_12"
add_path "$G_PYTHON"
add_path "$G_PYTHON/bin" # Unix
add_path "$G_PYTHON/Scripts" # Windows
## Project venv
# https://docs.python.org/3/library/venv.html#how-venvs-work
add_path "$PWD/.venv/bin" # POSIX
add_path "$PWD/.venv/Scripts" # Windows
# .python-version - pyenv
# requirements.txt
# Pipfile - pipenv
# pyproject.toml - poetry
:
}
setup_ruby() {
RBENV_ROOT="$HOME/.rbenv"
# Gemfile - rbenv
# https://github.com/rbenv/rbenv
# Initialize rbenv, if available
[ -d "$RBENV_ROOT/bin" ] && {
add_path "$RBENV_ROOT/bin"
export PATH
export RBENV_ROOT
eval "$(rbenv init -)"
}
}
setup_perl() {
#/usr/bin/core_perl # git for windows / msys2
#/usr/bin/vendor_perl # git for windows / msys2
PLENV_ROOT="$HOME/.plenv"
#PWD_PERL_VERSION="$PWD/.perl-version"
# https://github.com/tokuhirom/plenv
# Setup plenv if it exists
if [ -d "$PLENV_ROOT/bin" ]; then
add_path "$PLENV_ROOT/bin"
export PATH
export PLENV_ROOT
eval "$(plenv init -)"
fi
# Check for a project-specific .perl-version file
#if [ -f "$PWD_PERL_VERSION" ]; then
# read -r PERL_VERSION < "$PWD_PERL_VERSION"
# PLENV_VERSION="$PERL_VERSION"
# export PLENV_VERSION
#fi
# Only proceed if the specified Perl version is installed under plenv
#if [ -n "${PERL_VERSION:}" ] && [ -d "$PL_ENV/versions/$PERL_VERSION" ]; then
# add_path "$HOME/.plenv/versions/$PERL_VERSION/bin"
#fi
}
setup_dotnet() {
#/c/Program Files/dotnet
:
}
setup_winget() {
#/c/Program Files/WinGet/Links
:
}
setup_msys2() {
add_path '/bin'
if [ "$MSYSTEM" = "MINGW64" ]; then
add_path '/mingw64/bin'
elif [ "$MSYSTEM" = "MINGW32" ]; then
add_path '/mingw32/bin'
elif [ "$MSYSTEM" = "MSYS" ]; then
add_path '/usr/bin'
fi
add_path '/sbin'
add_path '/usr/sbin'
add_path '/usr/X11/bin'
}
setup_windows() {
#/c/Windows
#/c/Windows/System32/OpenSSH
#/c/Windows/System32/Wbem
#/c/Windows/System32/WindowsPowerShell/v1.0
#/c/Windows/system32
:
}
setup_apps() {
# Add directories for installed applications
add_path "$PROGRAM_FILES/7-Zip"
add_path "$PROGRAM_FILES/Amazon/AWSCLIV2"
add_path "$PROGRAM_FILES/JetBrains/IntelliJ IDEA 2022.3.1/bin"
add_path "$PROGRAM_FILES/Microsoft VS Code/bin"
add_path "$PROGRAM_FILES/Vagrant/bin"
add_path "$PROGRAM_FILES/gs/gs10.00.0/bin"
}
setup_path() {
# Normal system stuff comes first for security
# So others can't override basic commands like ls
# Reset PATH to a basic, secure set of directories
PATH=''
# Personal
add_path "$HOME/.local/bin"
add_path "$HOME/.bin"
add_path "$HOME/bin"
setup_msys2
setup_windows
setup_homebrew
setup_winget
setup_java
setup_node
setup_perl
setup_python
setup_ruby
setup_dotnet
setup_apps
# Projects
add_path "$HOME/projects/dotfiles/bin"
export PATH
}
# Run setup_path during shell startup or manually as needed
setup_path
if [ -n "${ZSH_VERSION}" ]; then
chpwd() {
[ -d .git ] || \
[ -d node_modules/.bin ] || \
[ -d python/bin ] || \
[ -d node/bin ] && setupPath
}
fi
# Adjust PATH automatically in some shells
case "$SHELL" in
*zsh)
autoload -U add-zsh-hook
add-zsh-hook chpwd
;;
*bash)
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ;}setup_path"
;;
esac
PROMPT_COMMAND="$PROMPT_COMMAND;setup_path"
# Function to wrap the Python command to use virtual environments, if available
python_exec_wrapper() {
# This holds the initial directory to start searching for .venv
search_dir=""
# Loop through all arguments to find a .py file and extract its directory
for arg in "$@"; do
case "$arg" in
*.py)
# Extract directory from the script's path
search_dir="$(dirname -- "$arg")"
# Break the loop once the first .py file is found
break
;;
esac
done
# If no .py file is found in arguments, use the current directory
[ -z "$search_dir" ] && search_dir="$(pwd)"
# Initialize a flag to indicate whether a .venv directory has been found
found_venv=""
# Search for .venv by moving up directories
while [ -n "$search_dir" ] && [ -z "$found_venv" ]; do
if [ -d "$search_dir/.venv" ] && [ -x "$search_dir/.venv/bin/python" ]; then
found_venv="$search_dir/.venv"
else
# Move up a directory
search_dir="$(cd "$search_dir/.." && pwd)"
# If we've reached the root directory, stop the loop
[ "$search_dir" = '/' ] && search_dir=''
fi
done
# Execute the Python script using the found .venv or the system Python interpreter
if [ -n "$found_venv" ]; then
echo "Using Python interpreter from .venv at $found_venv"
"$found_venv/bin/python" "$@"
else
echo "Using system Python interpreter"
command python "$@"
fi
}
# Alias the custom python function
alias python='python_exec_wrapper'
# To make this function available in your shell, you can source this script file
# or define the function directly in your shell's initialization files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment