├── bin └── xenv ├── .gitignore ├── share ├── xenv-envs │ ├── Renv │ ├── crenv │ ├── exenv │ ├── goenv │ ├── nodenv │ ├── phpenv │ ├── pyenv │ ├── rbenv │ └── plenv └── xenv-plugins │ ├── Renv │ └── R-build │ ├── nodenv │ └── node-build │ ├── phpenv │ └── php-build │ ├── rbenv │ ├── ruby-build │ └── gem-rehash │ ├── crenv │ └── crystal-build │ └── exenv │ └── elixir-build ├── .editorconfig ├── libexec ├── xenv-root ├── xenv-rehash ├── xenv ├── xenv-help ├── xenv-sh-rehash ├── xenv-update ├── xenv-init ├── xenv-uninstall └── xenv-install ├── lib └── init.sh ├── LICENSE └── README.md /bin/xenv: -------------------------------------------------------------------------------- 1 | ../libexec/xenv -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /plugin 2 | /envs 3 | 4 | -------------------------------------------------------------------------------- /share/xenv-envs/Renv: -------------------------------------------------------------------------------- 1 | https://github.com/viking/Renv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/crenv: -------------------------------------------------------------------------------- 1 | https://github.com/pine/crenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/exenv: -------------------------------------------------------------------------------- 1 | https://github.com/mururu/exenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/goenv: -------------------------------------------------------------------------------- 1 | https://github.com/syndbg/goenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/nodenv: -------------------------------------------------------------------------------- 1 | https://github.com/nodenv/nodenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/phpenv: -------------------------------------------------------------------------------- 1 | https://github.com/phpenv/phpenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/pyenv: -------------------------------------------------------------------------------- 1 | https://github.com/yyuu/pyenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/rbenv: -------------------------------------------------------------------------------- 1 | https://github.com/rbenv/rbenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-envs/plenv: -------------------------------------------------------------------------------- 1 | https://github.com/tokuhirom/plenv.git 2 | -------------------------------------------------------------------------------- /share/xenv-plugins/Renv/R-build: -------------------------------------------------------------------------------- 1 | https://github.com/viking/R-build.git 2 | -------------------------------------------------------------------------------- /share/xenv-plugins/nodenv/node-build: -------------------------------------------------------------------------------- 1 | https://github.com/nodenv/node-build.git 2 | -------------------------------------------------------------------------------- /share/xenv-plugins/phpenv/php-build: -------------------------------------------------------------------------------- 1 | https://github.com/php-build/php-build.git 2 | -------------------------------------------------------------------------------- /share/xenv-plugins/rbenv/ruby-build: -------------------------------------------------------------------------------- 1 | https://github.com/rbenv/ruby-build.git 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | -------------------------------------------------------------------------------- /share/xenv-plugins/crenv/crystal-build: -------------------------------------------------------------------------------- 1 | https://github.com/pine/crystal-build.git 2 | -------------------------------------------------------------------------------- /share/xenv-plugins/exenv/elixir-build: -------------------------------------------------------------------------------- 1 | https://github.com/mururu/elixir-build.git 2 | -------------------------------------------------------------------------------- /share/xenv-plugins/rbenv/gem-rehash: -------------------------------------------------------------------------------- 1 | https://github.com/rbenv/rbenv-gem-rehash.git 2 | -------------------------------------------------------------------------------- /libexec/xenv-root: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Get the xenv root directory 4 | 5 | echo "$XENV_ROOT" 6 | 7 | -------------------------------------------------------------------------------- /libexec/xenv-rehash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Reload fresh envs into the environment 4 | 5 | echo 'Please run:' 6 | echo ' eval "$(xenv init - $SHELL)"' 7 | -------------------------------------------------------------------------------- /libexec/xenv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Base path setup 4 | cd $(dirname "${BASH_SOURCE[0]}") 5 | cd .. 6 | XENV_ROOT=$(pwd) 7 | export XENV_ROOT 8 | 9 | # Base dirs 10 | 11 | mkdir -p "$XENV_ROOT/envs" 12 | 13 | # Load shared functions 14 | source "$XENV_ROOT/lib/init.sh" 15 | 16 | if [ "$#" = "0" ]; then 17 | xenv_exec "help" 18 | else 19 | xenv_exec "$@" 20 | fi 21 | 22 | -------------------------------------------------------------------------------- /libexec/xenv-help: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Display this page 4 | 5 | echo "xenv" 6 | echo "Usage: xenv [arg]..." 7 | echo 8 | echo "Some useful xenv commands are:" 9 | 10 | for f in "$XENV_ROOT/libexec/xenv-"*; do 11 | cmd_name=${f##*/xenv-} 12 | if [[ "$cmd_name" == sh-* ]]; then 13 | continue 14 | fi 15 | cmd_desc="$(grep -m 1 '# Desc: ' $f | cut -c 9-)" 16 | printf " %-12s %s\n" "$cmd_name" "$cmd_desc" 17 | done 18 | 19 | -------------------------------------------------------------------------------- /libexec/xenv-sh-rehash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "$(find $XENV_ROOT/envs -maxdepth 1 | tail -n +2)" ]; then 4 | return 5 | fi 6 | 7 | 8 | for f in "$XENV_ROOT/envs/"*; do 9 | if [ -e "$f" ]; then 10 | env_name="${f##*/}" 11 | env_var="$(echo $env_name | tr '[a-z]' '[A-Z]')_ROOT" 12 | env_var_value="$(eval echo \$$env_var)" 13 | eval export "$env_var"="$XENV_ROOT/envs/$env_name" 14 | if [[ ! ":$PATH:" == *"$XENV_ROOT/envs/$env_name/bin"* ]]; then 15 | export PATH="$XENV_ROOT/envs/$env_name/bin:$PATH" 16 | fi 17 | if [[ "$env_name" == "pyenv" ]]; then 18 | # pyenv has a separate path command now 19 | eval "$($env_name init --path $SHELL)" 20 | fi 21 | eval "$($env_name init - $SHELL)" 22 | fi 23 | done 24 | -------------------------------------------------------------------------------- /lib/init.sh: -------------------------------------------------------------------------------- 1 | pushd() { 2 | command -- pushd &>/dev/null "$@" 3 | } 4 | 5 | popd() { 6 | command -- pushd &>/dev/null 7 | } 8 | 9 | xenv_exec() { 10 | local cmd="$1" 11 | shift 12 | local cmd_file="$XENV_ROOT/libexec/xenv-$cmd" 13 | if [ ! -e "$cmd_file" ]; then 14 | echo "xenv: command not found: $cmd" 15 | exit 1 16 | fi 17 | command -- "$cmd_file" "$@" 18 | } 19 | 20 | read_line() { 21 | local var="$1" 22 | local file="$2" 23 | read -r "$var" < "$file" 24 | } 25 | 26 | list_dir() { 27 | local var="$1" 28 | local path="$2" 29 | local result=() 30 | shopt -s nullglob 31 | for f in "$path/"*; do 32 | local fname="${f##*/}" 33 | result+=("$fname") 34 | done 35 | "$var"=$result 36 | } 37 | 38 | export -f pushd 39 | export -f popd 40 | export -f xenv_exec 41 | export -f read_line 42 | -------------------------------------------------------------------------------- /libexec/xenv-update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Update xenv and every env and plugin 4 | 5 | shopt -s nullglob 6 | 7 | git_update() { 8 | local repo="$1" 9 | local name="$2" 10 | pushd "$repo" 11 | 12 | if [ ! -e "./.git" ]; then 13 | popd 14 | return 15 | fi 16 | echo "Updating $name" 17 | local pre_commit="$(git rev-parse --short HEAD)" 18 | git pull -f &>/dev/null 19 | local post_commit="$(git rev-parse --short HEAD)" 20 | if [ ! "$pre_commit" = "$post_commit" ]; then 21 | echo " $pre_commit -> $post_commit" 22 | fi 23 | popd 24 | } 25 | 26 | git_update "$XENV_ROOT" "xenv" 27 | 28 | for f in "$XENV_ROOT/envs/"*; do 29 | env_name="${f##*/}" 30 | git_update "$f" "$env_name" 31 | for g in "$f/plugins/"*; do 32 | plugin_name="${g##*/}" 33 | git_update "$g" "$env_name/$plugin_name" 34 | done 35 | done 36 | 37 | -------------------------------------------------------------------------------- /libexec/xenv-init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Init xenv 4 | 5 | opt_no_action=true 6 | opt_rehash=true 7 | opt_shell='' 8 | 9 | while [ ! "$#" = "0" ]; do 10 | case "$1" in 11 | -) 12 | opt_no_action=false ;; 13 | --no-rehash) 14 | opt_rehash=false ;; 15 | *) 16 | opt_shell="$1" ;; 17 | esac 18 | shift 19 | done 20 | 21 | if $opt_no_action; then 22 | echo "Add this to your shell config:" 23 | echo ' eval "$(xenv init -)"' 24 | exit 25 | fi 26 | 27 | # Placeholder function 28 | echo 'export XENV_ROOT="$(command -- xenv root)"' 29 | echo 30 | echo 'function xenv() {' 31 | echo ' if [ "$1" = rehash ]; then' 32 | echo ' local cmd="$1"' 33 | echo ' shift' 34 | echo ' source "$XENV_ROOT/libexec/xenv-sh-$cmd"' 35 | echo ' else' 36 | echo ' command -- xenv "$@"' 37 | echo ' fi' 38 | echo '}' 39 | echo 40 | echo 'xenv rehash' 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2017 Maxime Bacoux 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /libexec/xenv-uninstall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Uninstall an env or a plugin 4 | 5 | usage() { 6 | echo "Usage:" 7 | echo " xenv uninstall " 8 | echo " xenv uninstall -p " 9 | exit 1 10 | } 11 | 12 | parse_options() { 13 | while [ ! "$#" = "0" ]; do 14 | case "$1" in 15 | -p|--plugin) 16 | opt_plugin=true ;; 17 | *) 18 | parse_raw "$1" ;; 19 | esac 20 | shift 21 | done 22 | } 23 | 24 | parse_raw() { 25 | if [ -z "${ENV_NAME+x}" ]; then 26 | ENV_NAME="$1" 27 | else 28 | if $opt_plugin && [ -z "${PLUGIN_NAME+x}" ]; then 29 | PLUGIN_NAME="$1" 30 | else 31 | usage 32 | fi 33 | fi 34 | } 35 | 36 | opt_plugin=false 37 | 38 | parse_options "$@" 39 | 40 | if [ -z "${ENV_NAME+x}" ]; then 41 | usage 42 | elif $opt_plugin && [ -z "${PLUGIN_NAME+x}" ]; then 43 | usage 44 | fi 45 | 46 | if $opt_plugin; then 47 | PLUGIN_DIR="$XENV_ROOT/envs/$ENV_NAME/plugins/$PLUGIN_NAME" 48 | PLUGIN_MANIFEST="$XENV_ROOT/share/xenv-plugins/$ENV_NAME/$PLUGIN_NAME" 49 | if [ ! -e "$PLUGIN_DIR" ] || [ ! -e "$PLUGIN_MANIFEST" ]; then 50 | echo "Plugin $PLUGIN_NAME does not exist" 51 | exit 1 52 | fi 53 | rm -rf "$PLUGIN_DIR" 54 | echo "Plugin $PLUGIN_NAME was removed" 55 | else 56 | ENV_DIR="$XENV_ROOT/envs/$ENV_NAME" 57 | ENV_MANIFEST="$XENV_ROOT/share/xenv-envs/$ENV_NAME" 58 | if [ ! -e "$ENV_DIR" ] || [ ! -e "$ENV_MANIFEST" ]; then 59 | echo "Env $ENV_NAME does not exist" 60 | exit 1 61 | fi 62 | rm -rf "$ENV_DIR" 63 | echo "Env $ENV_NAME was removed" 64 | fi 65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xenv 2 | 3 | An env to manage envs. 4 | 5 | ## Introduction 6 | 7 | xenv is a set of small self-contained shell scripts, used to install and update other scripts such as rbenv, pyenv, nodenv and their plugins. 8 | xenv can update these scripts with git, allowing you to keep them frequently up-to-date. 9 | 10 | ## Install 11 | 12 | xenv can be installed system-wide or per-user. 13 | 14 | For a system-wide install: 15 | 16 | $ git clone https://github.com/Nax/xenv.git /opt/xenv 17 | 18 | For a per user install: 19 | 20 | $ git clone https://github.com/Nax/xenv.git ~/.xenv 21 | 22 | Then, in your shell config, make sure xenv is in the PATH, and run 23 | 24 | $ eval "$(xenv init - $SHELL)" 25 | 26 | When using a system-wide installation, you will probably need to create some groups and manage permissions carefully. 27 | For this reason, the user install is preferred in most cases. 28 | 29 | ## Usage 30 | 31 | Install rbenv: 32 | 33 | $ xenv install rbenv 34 | 35 | Install ruby-build (rbenv plugin): 36 | 37 | $ xenv install -p rbenv ruby-build 38 | 39 | Don't forget to `xenv rehash` after each env install. 40 | 41 | Update installed envs, plugins and xenv itself: 42 | 43 | $ xenv update 44 | 45 | Remove nodenv: 46 | 47 | $ xenv uninstall nodenv 48 | 49 | Check what envs you can install: 50 | 51 | $ xenv install -l 52 | 53 | Check what plugins you can install: 54 | 55 | $ xenv install -p -l 56 | 57 | Check what envs are installed: 58 | 59 | $ xenv install -L 60 | 61 | Check what plugins are installed: 62 | 63 | $ xenv install -p -L 64 | 65 | ## License 66 | 67 | xenv is distributed under the MIT license. 68 | 69 | ## Author 70 | 71 | The original [xenv](https://github.com/Nax/xenv.git) implementation was created by [Maxime Bacoux (Nax)](https://github.com/Nax/). 72 | -------------------------------------------------------------------------------- /libexec/xenv-install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Desc: Install an env or a plugin 4 | 5 | shopt -s nullglob 6 | 7 | opt_list=false 8 | opt_local=false 9 | opt_force=false 10 | opt_plugin=false 11 | 12 | ENVS_DIR="$XENV_ROOT/share/xenv-envs" 13 | PLUGINS_DIR="$XENV_ROOT/share/xenv-plugins" 14 | 15 | usage() { 16 | echo "Usage:" 17 | echo " xenv install [-f] " 18 | echo " xenv install -p " 19 | echo " xenv install [-p] -l" 20 | echo " xenv install [-p] -L" 21 | exit 1 22 | } 23 | 24 | parse_raw() { 25 | if [ -n "${ENV_NAME+x}" ]; then 26 | if $opt_plugin && [ -z "${PLUGIN_NAME+x}" ]; then 27 | PLUGIN_NAME="$1" 28 | else 29 | usage 30 | fi 31 | else 32 | ENV_NAME="$1" 33 | fi 34 | } 35 | 36 | parse_options() { 37 | while [ ! "$#" = "0" ]; do 38 | case "$1" in 39 | -l|--list) 40 | opt_list=true ;; 41 | -L|--local) 42 | opt_local=true ;; 43 | -f|--force) 44 | opt_force=true ;; 45 | -p|--plugin) 46 | opt_plugin=true ;; 47 | *) 48 | parse_raw "$1" ;; 49 | esac 50 | shift 51 | done 52 | } 53 | 54 | install_env() { 55 | local env_name="$1" 56 | 57 | if [ -e "$XENV_ROOT/envs/$env_name" ]; then 58 | $opt_force || exit 59 | fi 60 | 61 | if [ ! -e "$ENVS_DIR/$env_name" ]; then 62 | echo "Unknown env $env_name" 63 | exit 1 64 | fi 65 | 66 | read_line GIT_URL "$ENVS_DIR/$env_name" 67 | git clone "$GIT_URL" "$XENV_ROOT/envs/$env_name" 68 | 69 | echo "$env_name was installed." 70 | } 71 | 72 | install_plugin() { 73 | local env_name="$1" 74 | local plugin_name="$2" 75 | 76 | if [ ! -e "$XENV_ROOT/envs/$env_name" ]; then 77 | echo "$env_name is not installed" 78 | exit 1 79 | fi 80 | 81 | if [ ! -e "$PLUGINS_DIR/$env_name/$plugin_name" ]; then 82 | echo "Unknown plugin $plugin_name" 83 | exit 1 84 | fi 85 | 86 | read_line GIT_URL "$PLUGINS_DIR/$env_name/$plugin_name" 87 | mkdir -p "$XENV_ROOT/envs/$env_name/plugins" 88 | git clone "$GIT_URL" "$XENV_ROOT/envs/$env_name/plugins/$plugin_name" 89 | 90 | echo "$plugin_name was installed" 91 | } 92 | 93 | parse_options "$@" 94 | 95 | if $opt_list; then 96 | for f in "$ENVS_DIR/"*; do 97 | env_name="${f##*/}" 98 | if $opt_plugin; then 99 | for g in "$PLUGINS_DIR/$env_name/"*; do 100 | plugin_name="${g##*/}" 101 | echo " $env_name/$plugin_name" 102 | done 103 | else 104 | echo " $env_name" 105 | fi 106 | done 107 | exit 108 | fi 109 | 110 | if $opt_local; then 111 | for f in "$XENV_ROOT/envs/"*; do 112 | env_name="${f##*/}" 113 | if [ ! -e "$ENVS_DIR/$env_name" ]; then 114 | continue 115 | fi 116 | if $opt_plugin; then 117 | for g in "$XENV_ROOT/envs/$env_name/plugins/"*; do 118 | plugin_name="${g##*/}" 119 | if [ ! -e "$PLUGINS_DIR/$env_name/$plugin_name" ]; then 120 | continue 121 | fi 122 | echo " $env_name/$plugin_name" 123 | done 124 | else 125 | echo " $env_name" 126 | fi 127 | done 128 | exit 129 | fi 130 | 131 | if [ -z "${ENV_NAME+x}" ]; then 132 | usage 133 | fi 134 | 135 | if $opt_plugin; then 136 | if [ -z "${PLUGIN_NAME+x}" ]; then 137 | usage 138 | fi 139 | install_plugin "$ENV_NAME" "$PLUGIN_NAME" 140 | else 141 | install_env "$ENV_NAME" 142 | fi 143 | 144 | --------------------------------------------------------------------------------