├── .gitignore ├── LICENSE ├── README.md ├── bin └── rakuenv ├── completions ├── rakuenv.bash ├── rakuenv.fish └── rakuenv.zsh ├── libexec ├── rakuenv ├── rakuenv---version ├── rakuenv-commands ├── rakuenv-completions ├── rakuenv-exec ├── rakuenv-global ├── rakuenv-help ├── rakuenv-hooks ├── rakuenv-init ├── rakuenv-install ├── rakuenv-local ├── rakuenv-prefix ├── rakuenv-rehash ├── rakuenv-reset ├── rakuenv-root ├── rakuenv-sh-rehash ├── rakuenv-sh-shell ├── rakuenv-shims ├── rakuenv-uninstall ├── rakuenv-version ├── rakuenv-version-file ├── rakuenv-version-file-read ├── rakuenv-version-file-write ├── rakuenv-version-name ├── rakuenv-version-origin ├── rakuenv-versions ├── rakuenv-whence └── rakuenv-which └── rakuenv.d └── rehash └── rehash_zef.bash /.gitignore: -------------------------------------------------------------------------------- 1 | /plugins 2 | /shims 3 | /version 4 | /versions 5 | /sources 6 | /cache 7 | /libexec/*.dylib 8 | /src/Makefile 9 | /src/*.o 10 | /gems 11 | /build 12 | /git_reference 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Sam Stephenson 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rakuenv 2 | 3 | Raku Environment Manager 4 | 5 | ![](https://user-images.githubusercontent.com/1589550/103409907-46402880-4bac-11eb-9ccf-183c213916be.png) 6 | 7 | ## Install 8 | 9 | 1. Clone rakuenv into `~/.rakuenv`. 10 | 11 | ```console 12 | ❯ git clone https://github.com/skaji/rakuenv ~/.rakuenv 13 | ``` 14 | 15 | 2. Add `~/.rakuenv/bin` to your `$PATH`. 16 | 17 | ```sh 18 | # bash 19 | ❯ echo 'export PATH="$HOME/.rakuenv/bin:$PATH"' >> ~/.bash_profile 20 | # zsh 21 | ❯ echo 'export PATH="$HOME/.rakuenv/bin:$PATH"' >> ~/.zshrc 22 | # fish 23 | ❯ set -Ux fish_user_paths $HOME/.rakuenv/bin $fish_user_paths 24 | ``` 25 | 26 | 3. Add `rakuenv init` to your shell to enable shims and autocompletion. 27 | 28 | ```sh 29 | # bash 30 | ❯ echo 'eval "$(rakuenv init -)"' >> ~/.bash_profile 31 | ``` 32 | 33 | Please change `~/.bash_profile` as in step 2. 34 | 35 | 4. Restart your shell so that PATH changes take effect. (Opening a new 36 | terminal tab will usually do it.) 37 | 38 | ## Usage 39 | 40 | ```console 41 | ❯ rakuenv install --list 42 | 2020.12-01 43 | 2020.11-01 44 | 2020.10-01 45 | 2020.09-01 46 | 2020.08.2-01 47 | 2020.08.1-01 48 | 2020.07-01 49 | 2020.06-01 50 | 2020.05.1-01 51 | 2020.02.1-01 52 | 2020.01-01 53 | 2019.11-01 54 | 55 | ❯ rakuenv install 2020.12-01 56 | Downloading https://rakudo.org/dl/rakudo/rakudo-moar-2020.12-01-macos-x86_64-clang.tar.gz 57 | Extracting /Users/skaji/.rakuenv/cache/rakudo-moar-2020.12-01-macos-x86_64-clang.tar.gz 58 | Successfully installed 2020.12-01 59 | You may want to execute 'rakuenv global 2020.12-01' 60 | 61 | ❯ rakuenv global 2020.12-01 62 | 63 | ❯ raku -v 64 | Welcome to Rakudo(tm) v2020.12. 65 | Implementing the Raku(tm) programming language v6.d. 66 | Built on MoarVM version 2020.12. 67 | ``` 68 | 69 | ## License 70 | 71 | rakuenv is a fork of https://github.com/rbenv/rbenv; 72 | you can redistribute rakuenv and/or modify it under the same terms as rbenv itself. 73 | 74 | See [LICENSE](LICENSE) for rbenv's license. 75 | -------------------------------------------------------------------------------- /bin/rakuenv: -------------------------------------------------------------------------------- 1 | ../libexec/rakuenv -------------------------------------------------------------------------------- /completions/rakuenv.bash: -------------------------------------------------------------------------------- 1 | _rakuenv() { 2 | COMPREPLY=() 3 | local word="${COMP_WORDS[COMP_CWORD]}" 4 | 5 | if [ "$COMP_CWORD" -eq 1 ]; then 6 | COMPREPLY=( $(compgen -W "$(rakuenv commands)" -- "$word") ) 7 | else 8 | local words=("${COMP_WORDS[@]}") 9 | unset words[0] 10 | unset words[$COMP_CWORD] 11 | local completions=$(rakuenv completions "${words[@]}") 12 | COMPREPLY=( $(compgen -W "$completions" -- "$word") ) 13 | fi 14 | } 15 | 16 | complete -F _rakuenv rakuenv 17 | -------------------------------------------------------------------------------- /completions/rakuenv.fish: -------------------------------------------------------------------------------- 1 | function __fish_rakuenv_needs_command 2 | set cmd (commandline -opc) 3 | if [ (count $cmd) -eq 1 -a $cmd[1] = 'rakuenv' ] 4 | return 0 5 | end 6 | return 1 7 | end 8 | 9 | function __fish_rakuenv_using_command 10 | set cmd (commandline -opc) 11 | if [ (count $cmd) -gt 1 ] 12 | if [ $argv[1] = $cmd[2] ] 13 | return 0 14 | end 15 | end 16 | return 1 17 | end 18 | 19 | complete -f -c rakuenv -n '__fish_rakuenv_needs_command' -a '(rakuenv commands)' 20 | for cmd in (rakuenv commands) 21 | complete -f -c rakuenv -n "__fish_rakuenv_using_command $cmd" -a \ 22 | "(rakuenv completions (commandline -opc)[2..-1])" 23 | end 24 | -------------------------------------------------------------------------------- /completions/rakuenv.zsh: -------------------------------------------------------------------------------- 1 | if [[ ! -o interactive ]]; then 2 | return 3 | fi 4 | 5 | compctl -K _rakuenv rakuenv 6 | 7 | _rakuenv() { 8 | local words completions 9 | read -cA words 10 | 11 | if [ "${#words}" -eq 2 ]; then 12 | completions="$(rakuenv commands)" 13 | else 14 | completions="$(rakuenv completions ${words[2,-2]})" 15 | fi 16 | 17 | reply=("${(ps:\n:)completions}") 18 | } 19 | -------------------------------------------------------------------------------- /libexec/rakuenv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ "$1" = "--debug" ]; then 5 | export RAKUENV_DEBUG=1 6 | shift 7 | fi 8 | 9 | if [ -n "$RAKUENV_DEBUG" ]; then 10 | export PS4='+ [${BASH_SOURCE##*/}:${LINENO}] ' 11 | set -x 12 | fi 13 | 14 | abort() { 15 | { if [ "$#" -eq 0 ]; then cat - 16 | else echo "rakuenv: $*" 17 | fi 18 | } >&2 19 | exit 1 20 | } 21 | 22 | if enable -f "${BASH_SOURCE%/*}"/../libexec/rakuenv-realpath.dylib realpath 2>/dev/null; then 23 | abs_dirname() { 24 | local path 25 | path="$(realpath "$1")" 26 | echo "${path%/*}" 27 | } 28 | else 29 | [ -z "$RAKUENV_NATIVE_EXT" ] || abort "failed to load \`realpath' builtin" 30 | 31 | READLINK=$(type -p greadlink readlink | head -1) 32 | [ -n "$READLINK" ] || abort "cannot find readlink - are you missing GNU coreutils?" 33 | 34 | resolve_link() { 35 | $READLINK "$1" 36 | } 37 | 38 | abs_dirname() { 39 | local cwd="$PWD" 40 | local path="$1" 41 | 42 | while [ -n "$path" ]; do 43 | cd "${path%/*}" 44 | local name="${path##*/}" 45 | path="$(resolve_link "$name" || true)" 46 | done 47 | 48 | pwd 49 | cd "$cwd" 50 | } 51 | fi 52 | 53 | if [ -z "${RAKUENV_ROOT}" ]; then 54 | RAKUENV_ROOT="${HOME}/.rakuenv" 55 | else 56 | RAKUENV_ROOT="${RAKUENV_ROOT%/}" 57 | fi 58 | export RAKUENV_ROOT 59 | 60 | if [ -z "${RAKUENV_DIR}" ]; then 61 | RAKUENV_DIR="$PWD" 62 | else 63 | [[ $RAKUENV_DIR == /* ]] || RAKUENV_DIR="$PWD/$RAKUENV_DIR" 64 | cd "$RAKUENV_DIR" 2>/dev/null || abort "cannot change working directory to \`$RAKUENV_DIR'" 65 | RAKUENV_DIR="$PWD" 66 | cd "$OLDPWD" 67 | fi 68 | export RAKUENV_DIR 69 | 70 | 71 | shopt -s nullglob 72 | 73 | bin_path="$(abs_dirname "$0")" 74 | for plugin_bin in "${RAKUENV_ROOT}/plugins/"*/bin; do 75 | PATH="${plugin_bin}:${PATH}" 76 | done 77 | export PATH="${bin_path}:${PATH}" 78 | 79 | RAKUENV_HOOK_PATH="${RAKUENV_HOOK_PATH}:${RAKUENV_ROOT}/rakuenv.d" 80 | if [ "${bin_path%/*}" != "$RAKUENV_ROOT" ]; then 81 | # Add rakuenv's own `rakuenv.d` unless rakuenv was cloned to RAKUENV_ROOT 82 | RAKUENV_HOOK_PATH="${RAKUENV_HOOK_PATH}:${bin_path%/*}/rakuenv.d" 83 | fi 84 | RAKUENV_HOOK_PATH="${RAKUENV_HOOK_PATH}:/usr/local/etc/rakuenv.d:/etc/rakuenv.d:/usr/lib/rakuenv/hooks" 85 | for plugin_hook in "${RAKUENV_ROOT}/plugins/"*/etc/rakuenv.d; do 86 | RAKUENV_HOOK_PATH="${RAKUENV_HOOK_PATH}:${plugin_hook}" 87 | done 88 | RAKUENV_HOOK_PATH="${RAKUENV_HOOK_PATH#:}" 89 | export RAKUENV_HOOK_PATH 90 | 91 | shopt -u nullglob 92 | 93 | 94 | command="$1" 95 | case "$command" in 96 | "" ) 97 | { rakuenv---version 98 | rakuenv-help 99 | } | abort 100 | ;; 101 | -v | --version ) 102 | exec rakuenv---version 103 | ;; 104 | -h | --help ) 105 | exec rakuenv-help 106 | ;; 107 | * ) 108 | command_path="$(command -v "rakuenv-$command" || true)" 109 | if [ -z "$command_path" ]; then 110 | if [ "$command" == "shell" ]; then 111 | abort "shell integration not enabled. Run \`rakuenv init' for instructions." 112 | else 113 | abort "no such command \`$command'" 114 | fi 115 | fi 116 | 117 | shift 1 118 | if [ "$1" = --help ]; then 119 | if [[ "$command" == "sh-"* ]]; then 120 | echo "rakuenv help \"$command\"" 121 | else 122 | exec rakuenv-help "$command" 123 | fi 124 | else 125 | exec "$command_path" "$@" 126 | fi 127 | ;; 128 | esac 129 | -------------------------------------------------------------------------------- /libexec/rakuenv---version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Display the version of rakuenv 3 | # 4 | # Displays the version number of this rakuenv release, including the 5 | # current revision from git, if available. 6 | # 7 | # The format of the git revision is: 8 | # -- 9 | # where `num_commits` is the number of commits since `version` was 10 | # tagged. 11 | 12 | set -e 13 | [ -n "$RAKUENV_DEBUG" ] && set -x 14 | 15 | version="1.1.1" 16 | git_revision="" 17 | 18 | if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q rakuenv; then 19 | git_revision="$(git describe --tags HEAD 2>/dev/null || true)" 20 | git_revision="${git_revision#v}" 21 | fi 22 | 23 | echo "rakuenv ${git_revision:-$version}" 24 | -------------------------------------------------------------------------------- /libexec/rakuenv-commands: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: List all available rakuenv commands 3 | # Usage: rakuenv commands [--sh|--no-sh] 4 | 5 | set -e 6 | [ -n "$RAKUENV_DEBUG" ] && set -x 7 | 8 | # Provide rakuenv completions 9 | if [ "$1" = "--complete" ]; then 10 | echo --sh 11 | echo --no-sh 12 | exit 13 | fi 14 | 15 | if [ "$1" = "--sh" ]; then 16 | sh=1 17 | shift 18 | elif [ "$1" = "--no-sh" ]; then 19 | nosh=1 20 | shift 21 | fi 22 | 23 | IFS=: paths=($PATH) 24 | 25 | shopt -s nullglob 26 | 27 | { for path in "${paths[@]}"; do 28 | for command in "${path}/rakuenv-"*; do 29 | command="${command##*rakuenv-}" 30 | if [ -n "$sh" ]; then 31 | if [ "${command:0:3}" = "sh-" ]; then 32 | echo "${command##sh-}" 33 | fi 34 | elif [ -n "$nosh" ]; then 35 | if [ "${command:0:3}" != "sh-" ]; then 36 | echo "${command##sh-}" 37 | fi 38 | else 39 | echo "${command##sh-}" 40 | fi 41 | done 42 | done 43 | } | sort | uniq 44 | -------------------------------------------------------------------------------- /libexec/rakuenv-completions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage: rakuenv completions [arg1 arg2...] 3 | 4 | set -e 5 | [ -n "$RAKUENV_DEBUG" ] && set -x 6 | 7 | COMMAND="$1" 8 | if [ -z "$COMMAND" ]; then 9 | rakuenv-help --usage completions >&2 10 | exit 1 11 | fi 12 | 13 | # Provide rakuenv completions 14 | if [ "$COMMAND" = "--complete" ]; then 15 | exec rakuenv-commands 16 | fi 17 | 18 | COMMAND_PATH="$(command -v "rakuenv-$COMMAND" || command -v "rakuenv-sh-$COMMAND")" 19 | 20 | # --help is provided automatically 21 | echo --help 22 | 23 | if grep -iE "^([#%]|--|//) provide rakuenv completions" "$COMMAND_PATH" >/dev/null; then 24 | shift 25 | exec "$COMMAND_PATH" --complete "$@" 26 | fi 27 | -------------------------------------------------------------------------------- /libexec/rakuenv-exec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Run an executable with the selected Raku version 4 | # 5 | # Usage: rakuenv exec [arg1 arg2...] 6 | # 7 | # Runs an executable by first preparing PATH so that the selected Raku 8 | # version's `bin' directory is at the front. 9 | # 10 | # For example, if the currently selected Raku version is 1.9.3-p327: 11 | # rakuenv exec bundle install 12 | # 13 | # is equivalent to: 14 | # PATH="$RAKUENV_ROOT/versions/1.9.3-p327/bin:$PATH" bundle install 15 | 16 | set -e 17 | [ -n "$RAKUENV_DEBUG" ] && set -x 18 | 19 | # Provide rakuenv completions 20 | if [ "$1" = "--complete" ]; then 21 | exec rakuenv-shims --short 22 | fi 23 | 24 | RAKUENV_VERSION="$(rakuenv-version-name)" 25 | RAKUENV_COMMAND="$1" 26 | 27 | if [ -z "$RAKUENV_COMMAND" ]; then 28 | rakuenv-help --usage exec >&2 29 | exit 1 30 | fi 31 | 32 | export RAKUENV_VERSION 33 | RAKUENV_COMMAND_PATH="$(rakuenv-which "$RAKUENV_COMMAND")" 34 | RAKUENV_BIN_PATH="${RAKUENV_COMMAND_PATH%/*}" 35 | 36 | OLDIFS="$IFS" 37 | IFS=$'\n' scripts=(`rakuenv-hooks exec`) 38 | IFS="$OLDIFS" 39 | for script in "${scripts[@]}"; do 40 | source "$script" 41 | done 42 | 43 | shift 1 44 | if [ "$RAKUENV_VERSION" != "system" ]; then 45 | export PATH="${RAKUENV_BIN_PATH}:${PATH}" 46 | fi 47 | exec -a "$RAKUENV_COMMAND" "$RAKUENV_COMMAND_PATH" "$@" 48 | -------------------------------------------------------------------------------- /libexec/rakuenv-global: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Set or show the global Raku version 4 | # 5 | # Usage: rakuenv global 6 | # 7 | # Sets the global Raku version. You can override the global version at 8 | # any time by setting a directory-specific version with `rakuenv local' 9 | # or by setting the `RAKUENV_VERSION' environment variable. 10 | # 11 | # should be a string matching a Raku version known to rakuenv. 12 | # The special version string `system' will use your default system Raku. 13 | # Run `rakuenv versions' for a list of available Raku versions. 14 | 15 | set -e 16 | [ -n "$RAKUENV_DEBUG" ] && set -x 17 | 18 | # Provide rakuenv completions 19 | if [ "$1" = "--complete" ]; then 20 | echo system 21 | exec rakuenv-versions --bare 22 | fi 23 | 24 | RAKUENV_VERSION="$1" 25 | RAKUENV_VERSION_FILE="${RAKUENV_ROOT}/version" 26 | 27 | if [ -n "$RAKUENV_VERSION" ]; then 28 | rakuenv-version-file-write "$RAKUENV_VERSION_FILE" "$RAKUENV_VERSION" 29 | else 30 | rakuenv-version-file-read "$RAKUENV_VERSION_FILE" || echo system 31 | fi 32 | -------------------------------------------------------------------------------- /libexec/rakuenv-help: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Display help for a command 4 | # 5 | # Usage: rakuenv help [--usage] COMMAND 6 | # 7 | # Parses and displays help contents from a command's source file. 8 | # 9 | # A command is considered documented if it starts with a comment block 10 | # that has a `Summary:' or `Usage:' section. Usage instructions can 11 | # span multiple lines as long as subsequent lines are indented. 12 | # The remainder of the comment block is displayed as extended 13 | # documentation. 14 | 15 | set -e 16 | [ -n "$RAKUENV_DEBUG" ] && set -x 17 | 18 | # Provide rakuenv completions 19 | if [ "$1" = "--complete" ]; then 20 | echo --usage 21 | exec rakuenv-commands 22 | fi 23 | 24 | command_path() { 25 | local command="$1" 26 | command -v rakuenv-"$command" || command -v rakuenv-sh-"$command" || true 27 | } 28 | 29 | extract_initial_comment_block() { 30 | sed -ne " 31 | /^#/ !{ 32 | q 33 | } 34 | 35 | s/^#$/# / 36 | 37 | /^# / { 38 | s/^# // 39 | p 40 | } 41 | " 42 | } 43 | 44 | collect_documentation() { 45 | # shellcheck disable=SC2016 46 | $(type -p gawk awk | head -1) ' 47 | /^Summary:/ { 48 | summary = substr($0, 10) 49 | next 50 | } 51 | 52 | /^Usage:/ { 53 | reading_usage = 1 54 | usage = usage "\n" $0 55 | next 56 | } 57 | 58 | /^( *$| )/ && reading_usage { 59 | usage = usage "\n" $0 60 | next 61 | } 62 | 63 | { 64 | reading_usage = 0 65 | help = help "\n" $0 66 | } 67 | 68 | function escape(str) { 69 | gsub(/[`\\$"]/, "\\\\&", str) 70 | return str 71 | } 72 | 73 | function trim(str) { 74 | sub(/^\n*/, "", str) 75 | sub(/\n*$/, "", str) 76 | return str 77 | } 78 | 79 | END { 80 | if (usage || summary) { 81 | print "summary=\"" escape(summary) "\"" 82 | print "usage=\"" escape(trim(usage)) "\"" 83 | print "help=\"" escape(trim(help)) "\"" 84 | } 85 | } 86 | ' 87 | } 88 | 89 | documentation_for() { 90 | local filename 91 | filename="$(command_path "$1")" 92 | if [ -n "$filename" ]; then 93 | extract_initial_comment_block < "$filename" | collect_documentation 94 | fi 95 | } 96 | 97 | print_summary() { 98 | local command="$1" 99 | local summary usage help 100 | local longest_command_word_count=11 101 | eval "$(documentation_for "$command")" 102 | 103 | if [ -n "$summary" ]; then 104 | printf " %-${longest_command_word_count}s %s\n" "$command" "$summary" 105 | fi 106 | } 107 | 108 | print_summaries() { 109 | for command; do 110 | print_summary "$command" 111 | done 112 | } 113 | 114 | print_help() { 115 | local command="$1" 116 | local summary usage help 117 | eval "$(documentation_for "$command")" 118 | [ -n "$help" ] || help="$summary" 119 | 120 | if [ -n "$usage" ] || [ -n "$summary" ]; then 121 | if [ -n "$usage" ]; then 122 | echo "$usage" 123 | else 124 | echo "Usage: rakuenv ${command}" 125 | fi 126 | if [ -n "$help" ]; then 127 | echo 128 | echo "$help" 129 | echo 130 | fi 131 | else 132 | echo "Sorry, this command isn't documented yet." >&2 133 | return 1 134 | fi 135 | } 136 | 137 | print_usage() { 138 | local command="$1" 139 | local summary usage help 140 | eval "$(documentation_for "$command")" 141 | [ -z "$usage" ] || echo "$usage" 142 | } 143 | 144 | unset usage 145 | if [ "$1" = "--usage" ]; then 146 | usage="1" 147 | shift 148 | fi 149 | 150 | if [ -z "$1" ] || [ "$1" == "rakuenv" ]; then 151 | echo "Usage: rakuenv []" 152 | [ -z "$usage" ] || exit 153 | echo 154 | echo "Some useful rakuenv commands are:" 155 | print_summaries commands local global shell install uninstall reset rehash version versions which whence install-zef 156 | echo 157 | echo "See \`rakuenv help ' for information on a specific command." 158 | echo "For full documentation, see: https://github.com/skaji/rakuenv#readme" 159 | else 160 | command="$1" 161 | if [ -n "$(command_path "$command")" ]; then 162 | if [ -n "$usage" ]; then 163 | print_usage "$command" 164 | else 165 | print_help "$command" 166 | fi 167 | else 168 | echo "rakuenv: no such command \`$command'" >&2 169 | exit 1 170 | fi 171 | fi 172 | -------------------------------------------------------------------------------- /libexec/rakuenv-hooks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: List hook scripts for a given rakuenv command 3 | # Usage: rakuenv hooks 4 | 5 | set -e 6 | [ -n "$RAKUENV_DEBUG" ] && set -x 7 | 8 | # Provide rakuenv completions 9 | if [ "$1" = "--complete" ]; then 10 | echo exec 11 | echo rehash 12 | echo version-name 13 | echo version-origin 14 | echo which 15 | exit 16 | fi 17 | 18 | RAKUENV_COMMAND="$1" 19 | if [ -z "$RAKUENV_COMMAND" ]; then 20 | rakuenv-help --usage hooks >&2 21 | exit 1 22 | fi 23 | 24 | if ! enable -f "${BASH_SOURCE%/*}"/rakuenv-realpath.dylib realpath 2>/dev/null; then 25 | if [ -n "$RAKUENV_NATIVE_EXT" ]; then 26 | echo "rakuenv: failed to load \`realpath' builtin" >&2 27 | exit 1 28 | fi 29 | READLINK=$(type -p greadlink readlink | head -1) 30 | if [ -z "$READLINK" ]; then 31 | echo "rakuenv: cannot find readlink - are you missing GNU coreutils?" >&2 32 | exit 1 33 | fi 34 | 35 | resolve_link() { 36 | $READLINK "$1" 37 | } 38 | 39 | realpath() { 40 | local cwd="$PWD" 41 | local path="$1" 42 | local name 43 | 44 | while [ -n "$path" ]; do 45 | name="${path##*/}" 46 | [ "$name" = "$path" ] || cd "${path%/*}" 47 | path="$(resolve_link "$name" || true)" 48 | done 49 | 50 | echo "${PWD}/$name" 51 | cd "$cwd" 52 | } 53 | fi 54 | 55 | IFS=: hook_paths=($RAKUENV_HOOK_PATH) 56 | 57 | shopt -s nullglob 58 | for path in "${hook_paths[@]}"; do 59 | for script in "$path/$RAKUENV_COMMAND"/*.bash; do 60 | realpath "$script" 61 | done 62 | done 63 | shopt -u nullglob 64 | -------------------------------------------------------------------------------- /libexec/rakuenv-init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Configure the shell environment for rakuenv 3 | # Usage: eval "$(rakuenv init - [--no-rehash] [])" 4 | 5 | set -e 6 | [ -n "$RAKUENV_DEBUG" ] && set -x 7 | 8 | # Provide rakuenv completions 9 | if [ "$1" = "--complete" ]; then 10 | echo - 11 | echo --no-rehash 12 | echo bash 13 | echo fish 14 | echo ksh 15 | echo zsh 16 | exit 17 | fi 18 | 19 | print="" 20 | no_rehash="" 21 | for args in "$@" 22 | do 23 | if [ "$args" = "-" ]; then 24 | print=1 25 | shift 26 | fi 27 | 28 | if [ "$args" = "--no-rehash" ]; then 29 | no_rehash=1 30 | shift 31 | fi 32 | done 33 | 34 | shell="$1" 35 | if [ -z "$shell" ]; then 36 | shell="$(ps -p "$PPID" -o 'args=' 2>/dev/null || true)" 37 | shell="${shell%% *}" 38 | shell="${shell##-}" 39 | shell="${shell:-$SHELL}" 40 | shell="${shell##*/}" 41 | fi 42 | 43 | root="${0%/*}/.." 44 | 45 | if [ -z "$print" ]; then 46 | case "$shell" in 47 | bash ) 48 | if [ -f "${HOME}/.bashrc" ] && [ ! -f "${HOME}/.bash_profile" ]; then 49 | profile='~/.bashrc' 50 | else 51 | profile='~/.bash_profile' 52 | fi 53 | ;; 54 | zsh ) 55 | profile='~/.zshrc' 56 | ;; 57 | ksh ) 58 | profile='~/.profile' 59 | ;; 60 | fish ) 61 | profile='~/.config/fish/config.fish' 62 | ;; 63 | * ) 64 | profile='your profile' 65 | ;; 66 | esac 67 | 68 | { echo "# Load rakuenv automatically by appending" 69 | echo "# the following to ${profile}:" 70 | echo 71 | case "$shell" in 72 | fish ) 73 | echo 'status --is-interactive; and source (rakuenv init -|psub)' 74 | ;; 75 | * ) 76 | echo 'eval "$(rakuenv init -)"' 77 | ;; 78 | esac 79 | echo 80 | } >&2 81 | 82 | exit 1 83 | fi 84 | 85 | mkdir -p "${RAKUENV_ROOT}/"{shims,versions} 86 | 87 | case "$shell" in 88 | fish ) 89 | echo "set -gx PATH '${RAKUENV_ROOT}/shims' \$PATH" 90 | echo "set -gx RAKUENV_SHELL $shell" 91 | ;; 92 | * ) 93 | echo 'export PATH="'${RAKUENV_ROOT}'/shims:${PATH}"' 94 | echo "export RAKUENV_SHELL=$shell" 95 | ;; 96 | esac 97 | 98 | completion="${root}/completions/rakuenv.${shell}" 99 | if [ -r "$completion" ]; then 100 | echo "source '$completion'" 101 | fi 102 | 103 | if [ -z "$no_rehash" ]; then 104 | echo 'command rakuenv rehash 2>/dev/null' 105 | fi 106 | 107 | commands=(`rakuenv-commands --sh`) 108 | case "$shell" in 109 | fish ) 110 | cat < 6 | # 7 | # Options: 8 | # -l, --list list available versions 9 | # --as=NAME install rakudo as NAME 10 | # --debug turn on debug output 11 | # -g, --global execute rakuenv global after installation 12 | # -r, --rehash execute rakuenv rehash after installation 13 | # 14 | # Examples: 15 | # rakuenv install -l 16 | # rakuenv install latest # automatically select the latest version 17 | # rakuenv install 2020.12-01 18 | # rakuenv install 2019.11-01 --as test 19 | set -uo pipefail 20 | shopt -s nullglob 21 | 22 | # Provide rakuenv completions 23 | 24 | RAKUDO_RELEASES_URL=https://raw.githubusercontent.com/skaji/rakudo-releases/main/rakudo-releases.v1.csv 25 | 26 | info() { 27 | echo "$@" >&2 28 | } 29 | 30 | die() { 31 | info "$@" 32 | exit 1 33 | } 34 | 35 | http_get() { 36 | local url=$1 37 | if curl --version &>/dev/null; then 38 | curl -fsSL $url 39 | elif wget --version &>/dev/null; then 40 | wget -q -O - $url 41 | else 42 | die "Need curl or wget" 43 | fi 44 | } 45 | 46 | http_download() { 47 | local url=$1 48 | local file=$2 49 | local tmp_file=$file.$(date +%s) 50 | local ret=1 51 | if curl --version &>/dev/null; then 52 | curl -fsSL -o $tmp_file $url 53 | ret=$? 54 | elif wget --version &>/dev/null; then 55 | wget -q -O $tmp_file $url 56 | ret=$? 57 | else 58 | die "Need curl or wget" 59 | fi 60 | if [[ $ret -eq 0 ]]; then 61 | mv $tmp_file $file 62 | else 63 | rm -f $tmp_file 64 | return 1 65 | fi 66 | } 67 | 68 | download_url() { 69 | local version=$1 70 | local platform=$(platform) 71 | local archname=$(archname) 72 | http_get $RAKUDO_RELEASES_URL | \ 73 | \grep ,archive, | \ 74 | \grep ,moar, | \ 75 | \grep ",$platform," | \ 76 | \grep ",$archname," | \ 77 | \grep ",$version," | \ 78 | \cut -d, -f9 79 | } 80 | 81 | available() { 82 | local platform=$(platform) 83 | local archname=$(archname) 84 | http_get $RAKUDO_RELEASES_URL | \ 85 | \grep ,archive, | \ 86 | \grep ,moar, | \ 87 | \grep ",$platform," | \ 88 | \grep ",$archname," | \ 89 | \cut -d, -f11 90 | } 91 | 92 | platform() { 93 | local uname=$(uname -s) 94 | if [[ $uname = "Darwin" ]]; then 95 | echo macos 96 | elif [[ $uname = "Linux" ]]; then 97 | echo linux 98 | else 99 | die "Unsupported platform '$uname'" 100 | fi 101 | } 102 | 103 | archname() { 104 | local uname=$(uname -m) 105 | if [[ $uname = "x86_64" ]]; then 106 | echo x86_64 107 | elif [[ $uname = "arm64" ]]; then 108 | echo arm64 109 | else 110 | die "Unsupported archname '$uname'" 111 | fi 112 | } 113 | 114 | run() { 115 | local version=$1 116 | local as=$2 117 | local root=${RAKUENV_ROOT-$HOME/.rakuenv} 118 | 119 | if [[ -e $root/versions/$as ]]; then 120 | die "Already exists $as" 121 | fi 122 | 123 | local cache= 124 | for f in "$root/cache/rakudo-moar-$version"-*; do 125 | cache="$f" 126 | done 127 | if [[ -z $cache ]]; then 128 | local download_url=$(download_url $version) 129 | if [[ -z $download_url ]]; then 130 | die "Unknown version '$version', try 'rakuenv install --list'" 131 | fi 132 | mkdir -p $root/cache 133 | cache="$root/cache"/${download_url##*/} 134 | echo "Downloading $download_url" >&2 135 | if ! http_download $download_url $cache; then 136 | die "Failed to download tarball" 137 | fi 138 | fi 139 | 140 | mkdir -p "$root/versions/$as" 141 | info "Extracting $cache" 142 | tar xf $cache -C "$root/versions/$as" --strip-components 1 143 | if [[ -e $root/versions/$as/bin/rakudo ]]; then 144 | info "Successfully installed $as" 145 | else 146 | rm -rf "$root/versions/$as" 147 | die "Failed to extract $cache" 148 | fi 149 | } 150 | 151 | main() { 152 | local option_debug= 153 | local option_as= 154 | local option_list= 155 | local option_help= 156 | local option_rehash= 157 | local option_global= 158 | local argv=() 159 | local _argv=("$@") 160 | local _v 161 | while [[ ${#_argv[@]} -gt 0 ]]; do 162 | case "${_argv[0]}" in 163 | --debug) 164 | option_debug=1 165 | _argv=("${_argv[@]:1}") 166 | ;; 167 | --as | --as=*) 168 | if [[ ${_argv[0]} =~ ^--as= ]]; then 169 | _v="${_argv[0]##--as=}" 170 | _argv=("${_argv[@]:1}") 171 | else 172 | if [[ ${#_argv[@]} -eq 1 ]] || [[ ${_argv[1]} =~ ^- ]]; then 173 | echo "${_argv[0]} option requires an argument" >&2 174 | return 1 175 | fi 176 | _v="${_argv[1]}" 177 | _argv=("${_argv[@]:2}") 178 | fi 179 | option_as="$_v" 180 | ;; 181 | --list | -l| --complete) 182 | option_list=1 183 | _argv=("${_argv[@]:1}") 184 | ;; 185 | --help | -h) 186 | option_help=1 187 | _argv=("${_argv[@]:1}") 188 | ;; 189 | --rehash | -r) 190 | option_rehash=1 191 | _argv=("${_argv[@]:1}") 192 | ;; 193 | --global | -g) 194 | option_global=1 195 | _argv=("${_argv[@]:1}") 196 | ;; 197 | -[a-zA-Z0-9][a-zA-Z0-9]*) 198 | _v="${_argv[0]:1}" 199 | _argv=($(echo "$_v" | \grep -o . | \sed -e 's/^/-/') "${_argv[@]:1}") 200 | ;; 201 | -*) 202 | echo "Unknown option ${_argv[0]}" >&2 203 | return 1 204 | ;; 205 | *) 206 | argv+=("${_argv[0]}") 207 | _argv=("${_argv[@]:1}") 208 | ;; 209 | esac 210 | done 211 | 212 | if [[ -n $option_debug ]]; then 213 | set -x 214 | fi 215 | if [[ -n $option_list ]]; then 216 | available 217 | exit 0 218 | fi 219 | if [[ -n $option_help ]]; then 220 | exec rakuenv-help install 221 | fi 222 | if [[ ${#argv[@]} -eq 0 ]]; then 223 | die "Need VERSION argument" 224 | fi 225 | local version="${argv[0]}" 226 | if [[ $version = latest ]]; then 227 | version=$(available | \head -1) 228 | fi 229 | local as=$version 230 | if [[ -n $option_as ]]; then 231 | as=$option_as 232 | fi 233 | run $version $as 234 | if [[ -n $option_global ]]; then 235 | rakuenv-global $as 236 | else 237 | info "You may want to execute 'rakuenv global $as'" 238 | fi 239 | if [[ -n $option_rehash ]]; then 240 | rakuenv-rehash 241 | fi 242 | } 243 | 244 | main "$@" 245 | -------------------------------------------------------------------------------- /libexec/rakuenv-local: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Set or show the local application-specific Raku version 4 | # 5 | # Usage: rakuenv local 6 | # rakuenv local --unset 7 | # 8 | # Sets the local application-specific Raku version by writing the 9 | # version name to a file named `.raku-version'. 10 | # 11 | # When you run a Raku command, rakuenv will look for a `.raku-version' 12 | # file in the current directory and each parent directory. If no such 13 | # file is found in the tree, rakuenv will use the global Raku version 14 | # specified with `rakuenv global'. A version specified with the 15 | # `RAKUENV_VERSION' environment variable takes precedence over local 16 | # and global versions. 17 | # 18 | # should be a string matching a Raku version known to rakuenv. 19 | # The special version string `system' will use your default system Raku. 20 | # Run `rakuenv versions' for a list of available Raku versions. 21 | 22 | set -e 23 | [ -n "$RAKUENV_DEBUG" ] && set -x 24 | 25 | # Provide rakuenv completions 26 | if [ "$1" = "--complete" ]; then 27 | echo --unset 28 | echo system 29 | exec rakuenv-versions --bare 30 | fi 31 | 32 | RAKUENV_VERSION="$1" 33 | 34 | if [ "$RAKUENV_VERSION" = "--unset" ]; then 35 | rm -f .raku-version 36 | elif [ -n "$RAKUENV_VERSION" ]; then 37 | rakuenv-version-file-write .raku-version "$RAKUENV_VERSION" 38 | else 39 | if version_file="$(rakuenv-version-file "$PWD")"; then 40 | rakuenv-version-file-read "$version_file" 41 | else 42 | echo "rakuenv: no local version configured for this directory" >&2 43 | exit 1 44 | fi 45 | fi 46 | -------------------------------------------------------------------------------- /libexec/rakuenv-prefix: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Display prefix for a Raku version 3 | # Usage: rakuenv prefix [] 4 | # 5 | # Displays the directory where a Raku version is installed. If no 6 | # version is given, `rakuenv prefix' displays the location of the 7 | # currently selected version. 8 | 9 | set -e 10 | [ -n "$RAKUENV_DEBUG" ] && set -x 11 | 12 | # Provide rakuenv completions 13 | if [ "$1" = "--complete" ]; then 14 | echo system 15 | exec rakuenv-versions --bare 16 | fi 17 | 18 | if [ -n "$1" ]; then 19 | export RAKUENV_VERSION="$1" 20 | elif [ -z "$RAKUENV_VERSION" ]; then 21 | RAKUENV_VERSION="$(rakuenv-version-name)" 22 | fi 23 | 24 | if [ "$RAKUENV_VERSION" = "system" ]; then 25 | if RAKU_PATH="$(rakuenv-which raku 2>/dev/null)"; then 26 | RAKU_PATH="${RAKU_PATH%/*}" 27 | RAKUENV_PREFIX_PATH="${RAKU_PATH%/bin}" 28 | echo "${RAKUENV_PREFIX_PATH:-/}" 29 | exit 30 | else 31 | echo "rakuenv: system version not found in PATH" >&2 32 | exit 1 33 | fi 34 | fi 35 | 36 | RAKUENV_PREFIX_PATH="${RAKUENV_ROOT}/versions/${RAKUENV_VERSION}" 37 | if [ ! -d "$RAKUENV_PREFIX_PATH" ]; then 38 | echo "rakuenv: version \`${RAKUENV_VERSION}' not installed" >&2 39 | exit 1 40 | fi 41 | 42 | echo "$RAKUENV_PREFIX_PATH" 43 | -------------------------------------------------------------------------------- /libexec/rakuenv-rehash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Rehash rakuenv shims (run this after installing executables) 3 | 4 | set -e 5 | [ -n "$RAKUENV_DEBUG" ] && set -x 6 | 7 | SHIM_PATH="${RAKUENV_ROOT}/shims" 8 | PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.rakuenv-shim" 9 | 10 | # Create the shims directory if it doesn't already exist. 11 | mkdir -p "$SHIM_PATH" 12 | 13 | # Ensure only one instance of rakuenv-rehash is running at a time by 14 | # setting the shell's `noclobber` option and attempting to write to 15 | # the prototype shim file. If the file already exists, print a warning 16 | # to stderr and exit with a non-zero status. 17 | set -o noclobber 18 | { echo > "$PROTOTYPE_SHIM_PATH" 19 | } 2>| /dev/null || 20 | { if [ -w "$SHIM_PATH" ]; then 21 | echo "rakuenv: cannot rehash: $PROTOTYPE_SHIM_PATH exists" 22 | else 23 | echo "rakuenv: cannot rehash: $SHIM_PATH isn't writable" 24 | fi 25 | exit 1 26 | } >&2 27 | set +o noclobber 28 | 29 | # If we were able to obtain a lock, register a trap to clean up the 30 | # prototype shim when the process exits. 31 | trap remove_prototype_shim EXIT 32 | 33 | remove_prototype_shim() { 34 | rm -f "$PROTOTYPE_SHIM_PATH" 35 | } 36 | 37 | # The prototype shim file is a script that re-execs itself, passing 38 | # its filename and any arguments to `rakuenv exec`. This file is 39 | # hard-linked for every executable and then removed. The linking 40 | # technique is fast, uses less disk space than unique files, and also 41 | # serves as a locking mechanism. 42 | create_prototype_shim() { 43 | cat > "$PROTOTYPE_SHIM_PATH" </dev/null 2>&1; then 76 | rm -f "$SHIM_PATH"/* 77 | fi 78 | break 79 | done 80 | } 81 | 82 | # List basenames of executables for every Raku version 83 | list_executable_names() { 84 | local version file 85 | rakuenv-versions --bare --skip-aliases | \ 86 | while read -r version; do 87 | for file in "${RAKUENV_ROOT}/versions/${version}/bin/"* "${RAKUENV_ROOT}/versions/${version}/share/perl6/site/bin/"*; do 88 | echo "${file##*/}" 89 | done 90 | done 91 | } 92 | 93 | # The basename of each argument passed to `make_shims` will be 94 | # registered for installation as a shim. In this way, plugins may call 95 | # `make_shims` with a glob to register many shims at once. 96 | make_shims() { 97 | local file shim 98 | for file; do 99 | shim="${file##*/}" 100 | register_shim "$shim" 101 | done 102 | } 103 | 104 | registered_shims=" " 105 | 106 | # Registers the name of a shim to be generated. 107 | register_shim() { 108 | registered_shims="${registered_shims}${1} " 109 | } 110 | 111 | # Install all the shims registered via `make_shims` or `register_shim` directly. 112 | install_registered_shims() { 113 | local shim file 114 | for shim in $registered_shims; do 115 | file="${SHIM_PATH}/${shim}" 116 | [ -e "$file" ] || cp "$PROTOTYPE_SHIM_PATH" "$file" 117 | done 118 | } 119 | 120 | # Once the registered shims have been installed, we make a second pass 121 | # over the contents of the shims directory. Any file that is present 122 | # in the directory but has not been registered as a shim should be 123 | # removed. 124 | remove_stale_shims() { 125 | local shim 126 | for shim in "$SHIM_PATH"/*; do 127 | if [[ "$registered_shims" != *" ${shim##*/} "* ]]; then 128 | rm -f "$shim" 129 | fi 130 | done 131 | } 132 | 133 | shopt -s nullglob 134 | 135 | # Create the prototype shim, then register shims for all known 136 | # executables. 137 | create_prototype_shim 138 | remove_outdated_shims 139 | # shellcheck disable=SC2046 140 | make_shims $(list_executable_names | sort -u) 141 | 142 | 143 | # Allow plugins to register shims. 144 | OLDIFS="$IFS" 145 | IFS=$'\n' scripts=(`rakuenv-hooks rehash`) 146 | IFS="$OLDIFS" 147 | 148 | for script in "${scripts[@]}"; do 149 | source "$script" 150 | done 151 | 152 | install_registered_shims 153 | remove_stale_shims 154 | -------------------------------------------------------------------------------- /libexec/rakuenv-reset: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Reset rakudo installation 4 | # 5 | # Usage: rakuenv reset 6 | # 7 | # Options: 8 | # -h, --help show help 9 | # --debug turn on debug output 10 | # 11 | # Examples: 12 | # rakuenv reset 2020.12-01 13 | set -uo pipefail 14 | shopt -s nullglob 15 | 16 | # Provide rakuenv completions 17 | 18 | die() { 19 | echo "$@" >&2 20 | exit 1 21 | } 22 | 23 | run() { 24 | local version="$1" 25 | local root=${RAKUENV_ROOT-$HOME/.rakuenv} 26 | local target="$root/versions/$version" 27 | if [[ ! -e $target ]]; then 28 | die "version '$version' not installed" 29 | fi 30 | 31 | local cache= 32 | for f in "$root/cache/rakudo-moar-$version"-*; do 33 | cache="$f" 34 | done 35 | if [[ -z $cache ]]; then 36 | die "Missing cache tarball for $version" 37 | fi 38 | rm -rf "$target" 39 | mkdir -p "$target" 40 | tar xf "$cache" -C "$target" --strip-components 1 41 | if [[ -e "$target/bin/rakudo" ]]; then 42 | echo "Successfully reset $version" 43 | else 44 | die "Failed to reset $version" 45 | fi 46 | } 47 | 48 | main() { 49 | local option_help= 50 | local option_complete= 51 | local option_debug= 52 | local argv=() 53 | local _argv=("$@") 54 | local _v 55 | while [[ ${#_argv[@]} -gt 0 ]]; do 56 | case "${_argv[0]}" in 57 | --help | -h) 58 | option_help=1 59 | _argv=("${_argv[@]:1}") 60 | ;; 61 | --complete) 62 | option_complete=1 63 | _argv=("${_argv[@]:1}") 64 | ;; 65 | --debug) 66 | option_debug=1 67 | _argv=("${_argv[@]:1}") 68 | ;; 69 | -[a-zA-Z0-9][a-zA-Z0-9]*) 70 | _v="${_argv[0]:1}" 71 | _argv=($(echo "$_v" | \grep -o . | \sed -e 's/^/-/') "${_argv[@]:1}") 72 | ;; 73 | -?*) 74 | echo "Unknown option ${_argv[0]}" >&2 75 | return 1 76 | ;; 77 | *) 78 | argv+=("${_argv[0]}") 79 | _argv=("${_argv[@]:1}") 80 | ;; 81 | esac 82 | done 83 | if [[ -n $option_help ]]; then 84 | exec rakuenv-help reset 85 | fi 86 | if [[ -n $option_complete ]]; then 87 | exec rakuenv-versions --bare 88 | fi 89 | if [[ -n $option_debug ]]; then 90 | set -x 91 | fi 92 | if [[ ${#argv[@]} -eq 0 ]]; then 93 | die "Need VERSION argument" 94 | fi 95 | local version="${argv[0]}" 96 | if [[ $version = "-" ]]; then 97 | version=$(rakuenv-version-name) 98 | if [[ $version = system ]]; then 99 | die "Cannot reset system raku" 100 | fi 101 | fi 102 | run "$version" 103 | } 104 | 105 | main "$@" 106 | -------------------------------------------------------------------------------- /libexec/rakuenv-root: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Display the root directory where versions and shims are kept 3 | echo "$RAKUENV_ROOT" 4 | -------------------------------------------------------------------------------- /libexec/rakuenv-sh-rehash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | [ -n "$RAKUENV_DEBUG" ] && set -x 4 | 5 | # Provide rakuenv completions 6 | if [ "$1" = "--complete" ]; then 7 | exec rakuenv-rehash --complete 8 | fi 9 | 10 | shell="$(basename "${RAKUENV_SHELL:-$SHELL}")" 11 | 12 | # When rakuenv shell integration is enabled, delegate to rakuenv-rehash, 13 | # then tell the shell to empty its command lookup cache. 14 | rakuenv-rehash 15 | 16 | case "$shell" in 17 | fish ) 18 | # no rehash support 19 | ;; 20 | * ) 21 | echo "hash -r 2>/dev/null || true" 22 | ;; 23 | esac 24 | -------------------------------------------------------------------------------- /libexec/rakuenv-sh-shell: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Set or show the shell-specific Raku version 4 | # 5 | # Usage: rakuenv shell 6 | # rakuenv shell - 7 | # rakuenv shell --unset 8 | # 9 | # Sets a shell-specific Raku version by setting the `RAKUENV_VERSION' 10 | # environment variable in your shell. This version overrides local 11 | # application-specific versions and the global version. 12 | # 13 | # should be a string matching a Raku version known to rakuenv. 14 | # The special version string `system' will use your default system Raku. 15 | # Run `rakuenv versions' for a list of available Raku versions. 16 | # 17 | # When `-` is passed instead of the version string, the previously set 18 | # version will be restored. With `--unset`, the `RAKUENV_VERSION` 19 | # environment variable gets unset, restoring the environment to the 20 | # state before the first `rakuenv shell` call. 21 | 22 | set -e 23 | [ -n "$RAKUENV_DEBUG" ] && set -x 24 | 25 | # Provide rakuenv completions 26 | if [ "$1" = "--complete" ]; then 27 | echo --unset 28 | echo system 29 | exec rakuenv-versions --bare 30 | fi 31 | 32 | version="$1" 33 | shell="$(basename "${RAKUENV_SHELL:-$SHELL}")" 34 | 35 | if [ -z "$version" ]; then 36 | if [ -z "$RAKUENV_VERSION" ]; then 37 | echo "rakuenv: no shell-specific version configured" >&2 38 | exit 1 39 | else 40 | echo 'echo "$RAKUENV_VERSION"' 41 | exit 42 | fi 43 | fi 44 | 45 | if [ "$version" = "--unset" ]; then 46 | case "$shell" in 47 | fish ) 48 | echo 'set -gu RAKUENV_VERSION_OLD "$RAKUENV_VERSION"' 49 | echo "set -e RAKUENV_VERSION" 50 | ;; 51 | * ) 52 | echo 'RAKUENV_VERSION_OLD="$RAKUENV_VERSION"' 53 | echo "unset RAKUENV_VERSION" 54 | ;; 55 | esac 56 | exit 57 | fi 58 | 59 | if [ "$version" = "-" ]; then 60 | case "$shell" in 61 | fish ) 62 | cat <&2 75 | false 76 | end 77 | EOS 78 | ;; 79 | * ) 80 | cat <&2 93 | false 94 | fi 95 | EOS 96 | ;; 97 | esac 98 | exit 99 | fi 100 | 101 | # Make sure the specified version is installed. 102 | if rakuenv-prefix "$version" >/dev/null; then 103 | if [ "$version" != "$RAKUENV_VERSION" ]; then 104 | case "$shell" in 105 | fish ) 106 | echo 'set -gu RAKUENV_VERSION_OLD "$RAKUENV_VERSION"' 107 | echo "set -gx RAKUENV_VERSION \"$version\"" 108 | ;; 109 | * ) 110 | echo 'RAKUENV_VERSION_OLD="$RAKUENV_VERSION"' 111 | echo "export RAKUENV_VERSION=\"$version\"" 112 | ;; 113 | esac 114 | fi 115 | else 116 | echo "false" 117 | exit 1 118 | fi 119 | -------------------------------------------------------------------------------- /libexec/rakuenv-shims: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: List existing rakuenv shims 3 | # Usage: rakuenv shims [--short] 4 | 5 | set -e 6 | [ -n "$RAKUENV_DEBUG" ] && set -x 7 | 8 | # Provide rakuenv completions 9 | if [ "$1" = "--complete" ]; then 10 | echo --short 11 | exit 12 | fi 13 | 14 | shopt -s nullglob 15 | 16 | for command in "${RAKUENV_ROOT}/shims/"*; do 17 | if [ "$1" = "--short" ]; then 18 | echo "${command##*/}" 19 | else 20 | echo "$command" 21 | fi 22 | done | sort 23 | -------------------------------------------------------------------------------- /libexec/rakuenv-uninstall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Uninstall rakudo installation 4 | # 5 | # Usage: rakuenv uninstall 6 | # 7 | set -e 8 | [ -n "$RAKUENV_DEBUG" ] && set -x 9 | 10 | if [[ $# -eq 0 ]] || [[ $1 = "-h" ]]; then 11 | echo "Usage: rakuenv uninstall " 12 | exit 1 13 | fi 14 | 15 | # Provide rakuenv completions 16 | if [[ $1 = "--complete" ]]; then 17 | exec rakuenv-versions --bare 18 | fi 19 | 20 | RAKUENV_ROOT=${RAKUENV_ROOT-$HOME/.rakuenv} 21 | 22 | RAKUENV_VERSION="$1" 23 | RAKUENV_VERSION_ABS="$RAKUENV_ROOT/versions/$RAKUENV_VERSION" 24 | 25 | if [[ -d $RAKUENV_VERSION_ABS ]]; then 26 | rm -rf $RAKUENV_VERSION_ABS 27 | else 28 | echo "version '$RAKUENV_VERSION' not installed" >&2 29 | exit 1 30 | fi 31 | -------------------------------------------------------------------------------- /libexec/rakuenv-version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Show the current Raku version and its origin 3 | # 4 | # Shows the currently selected Raku version and how it was 5 | # selected. To obtain only the version string, use `rakuenv 6 | # version-name'. 7 | 8 | set -e 9 | [ -n "$RAKUENV_DEBUG" ] && set -x 10 | 11 | echo "$(rakuenv-version-name) (set by $(rakuenv-version-origin))" 12 | -------------------------------------------------------------------------------- /libexec/rakuenv-version-file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage: rakuenv version-file [] 3 | # Summary: Detect the file that sets the current rakuenv version 4 | set -e 5 | [ -n "$RAKUENV_DEBUG" ] && set -x 6 | 7 | target_dir="$1" 8 | 9 | find_local_version_file() { 10 | local root="$1" 11 | while ! [[ "$root" =~ ^//[^/]*$ ]]; do 12 | if [ -s "${root}/.raku-version" ]; then 13 | echo "${root}/.raku-version" 14 | return 0 15 | fi 16 | [ -n "$root" ] || break 17 | root="${root%/*}" 18 | done 19 | return 1 20 | } 21 | 22 | if [ -n "$target_dir" ]; then 23 | find_local_version_file "$target_dir" 24 | else 25 | find_local_version_file "$RAKUENV_DIR" || { 26 | [ "$RAKUENV_DIR" != "$PWD" ] && find_local_version_file "$PWD" 27 | } || echo "${RAKUENV_ROOT}/version" 28 | fi 29 | -------------------------------------------------------------------------------- /libexec/rakuenv-version-file-read: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage: rakuenv version-file-read 3 | set -e 4 | [ -n "$RAKUENV_DEBUG" ] && set -x 5 | 6 | VERSION_FILE="$1" 7 | 8 | if [ -e "$VERSION_FILE" ]; then 9 | # Read the first word from the specified version file. Avoid reading it whole. 10 | IFS="${IFS}"$'\r' 11 | words=( $(cut -b 1-1024 "$VERSION_FILE") ) 12 | version="${words[0]}" 13 | 14 | if [ -n "$version" ]; then 15 | echo "$version" 16 | exit 17 | fi 18 | fi 19 | 20 | exit 1 21 | -------------------------------------------------------------------------------- /libexec/rakuenv-version-file-write: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage: rakuenv version-file-write 3 | 4 | set -e 5 | [ -n "$RAKUENV_DEBUG" ] && set -x 6 | 7 | RAKUENV_VERSION_FILE="$1" 8 | RAKUENV_VERSION="$2" 9 | 10 | if [ -z "$RAKUENV_VERSION" ] || [ -z "$RAKUENV_VERSION_FILE" ]; then 11 | rakuenv-help --usage version-file-write >&2 12 | exit 1 13 | fi 14 | 15 | # Make sure the specified version is installed. 16 | rakuenv-prefix "$RAKUENV_VERSION" >/dev/null 17 | 18 | # Write the version out to disk. 19 | echo "$RAKUENV_VERSION" > "$RAKUENV_VERSION_FILE" 20 | -------------------------------------------------------------------------------- /libexec/rakuenv-version-name: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Show the current Raku version 3 | set -e 4 | [ -n "$RAKUENV_DEBUG" ] && set -x 5 | 6 | if [ -z "$RAKUENV_VERSION" ]; then 7 | RAKUENV_VERSION_FILE="$(rakuenv-version-file)" 8 | RAKUENV_VERSION="$(rakuenv-version-file-read "$RAKUENV_VERSION_FILE" || true)" 9 | fi 10 | 11 | OLDIFS="$IFS" 12 | IFS=$'\n' scripts=(`rakuenv-hooks version-name`) 13 | IFS="$OLDIFS" 14 | for script in "${scripts[@]}"; do 15 | source "$script" 16 | done 17 | 18 | if [ -z "$RAKUENV_VERSION" ] || [ "$RAKUENV_VERSION" = "system" ]; then 19 | echo "system" 20 | exit 21 | fi 22 | 23 | version_exists() { 24 | local version="$1" 25 | [ -d "${RAKUENV_ROOT}/versions/${version}" ] 26 | } 27 | 28 | if version_exists "$RAKUENV_VERSION"; then 29 | echo "$RAKUENV_VERSION" 30 | elif version_exists "${RAKUENV_VERSION#raku-}"; then 31 | echo "${RAKUENV_VERSION#raku-}" 32 | else 33 | echo "rakuenv: version \`$RAKUENV_VERSION' is not installed (set by $(rakuenv-version-origin))" >&2 34 | exit 1 35 | fi 36 | -------------------------------------------------------------------------------- /libexec/rakuenv-version-origin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: Explain how the current Raku version is set 3 | set -e 4 | [ -n "$RAKUENV_DEBUG" ] && set -x 5 | 6 | unset RAKUENV_VERSION_ORIGIN 7 | 8 | OLDIFS="$IFS" 9 | IFS=$'\n' scripts=(`rakuenv-hooks version-origin`) 10 | IFS="$OLDIFS" 11 | for script in "${scripts[@]}"; do 12 | source "$script" 13 | done 14 | 15 | if [ -n "$RAKUENV_VERSION_ORIGIN" ]; then 16 | echo "$RAKUENV_VERSION_ORIGIN" 17 | elif [ -n "$RAKUENV_VERSION" ]; then 18 | echo "RAKUENV_VERSION environment variable" 19 | else 20 | rakuenv-version-file 21 | fi 22 | -------------------------------------------------------------------------------- /libexec/rakuenv-versions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: List all Raku versions available to rakuenv 3 | # Usage: rakuenv versions [--bare] [--skip-aliases] 4 | # 5 | # Lists all Raku versions found in `$RAKUENV_ROOT/versions/*'. 6 | 7 | set -e 8 | [ -n "$RAKUENV_DEBUG" ] && set -x 9 | 10 | unset bare 11 | unset skip_aliases 12 | # Provide rakuenv completions 13 | for arg; do 14 | case "$arg" in 15 | --complete ) 16 | echo --bare 17 | echo --skip-aliases 18 | exit ;; 19 | --bare ) bare=1 ;; 20 | --skip-aliases ) skip_aliases=1 ;; 21 | * ) 22 | rakuenv-help --usage versions >&2 23 | exit 1 24 | ;; 25 | esac 26 | done 27 | 28 | versions_dir="${RAKUENV_ROOT}/versions" 29 | 30 | if ! enable -f "${BASH_SOURCE%/*}"/rakuenv-realpath.dylib realpath 2>/dev/null; then 31 | if [ -n "$RAKUENV_NATIVE_EXT" ]; then 32 | echo "rakuenv: failed to load \`realpath' builtin" >&2 33 | exit 1 34 | fi 35 | 36 | READLINK=$(type -p greadlink readlink | head -1) 37 | if [ -z "$READLINK" ]; then 38 | echo "rakuenv: cannot find readlink - are you missing GNU coreutils?" >&2 39 | exit 1 40 | fi 41 | 42 | resolve_link() { 43 | $READLINK "$1" 44 | } 45 | 46 | realpath() { 47 | local cwd="$PWD" 48 | local path="$1" 49 | local name 50 | 51 | while [ -n "$path" ]; do 52 | name="${path##*/}" 53 | [ "$name" = "$path" ] || cd "${path%/*}" 54 | path="$(resolve_link "$name" || true)" 55 | done 56 | 57 | echo "${PWD}/$name" 58 | cd "$cwd" 59 | } 60 | fi 61 | 62 | if [ -d "$versions_dir" ]; then 63 | versions_dir="$(realpath "$versions_dir")" 64 | fi 65 | 66 | if [ -n "$bare" ]; then 67 | hit_prefix="" 68 | miss_prefix="" 69 | current_version="" 70 | include_system="" 71 | else 72 | hit_prefix="* " 73 | miss_prefix=" " 74 | current_version="$(rakuenv-version-name || true)" 75 | include_system="1" 76 | fi 77 | 78 | num_versions=0 79 | 80 | print_version() { 81 | if [ "$1" == "$current_version" ]; then 82 | echo "${hit_prefix}$(rakuenv-version 2>/dev/null)" 83 | else 84 | echo "${miss_prefix}$1" 85 | fi 86 | num_versions=$((num_versions + 1)) 87 | } 88 | 89 | # Include "system" in the non-bare output, if it exists 90 | if [ -n "$include_system" ] && RAKUENV_VERSION=system rakuenv-which raku >/dev/null 2>&1; then 91 | print_version system 92 | fi 93 | 94 | shopt -s nullglob 95 | for path in "$versions_dir"/*; do 96 | if [ -d "$path" ]; then 97 | if [ -n "$skip_aliases" ] && [ -L "$path" ]; then 98 | target="$(realpath "$path")" 99 | [ "${target%/*}" != "$versions_dir" ] || continue 100 | fi 101 | print_version "${path##*/}" 102 | fi 103 | done 104 | shopt -u nullglob 105 | 106 | if [ "$num_versions" -eq 0 ] && [ -n "$include_system" ]; then 107 | echo "Warning: no Raku detected on the system" >&2 108 | exit 1 109 | fi 110 | -------------------------------------------------------------------------------- /libexec/rakuenv-whence: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Summary: List all Raku versions that contain the given executable 3 | # Usage: rakuenv whence [--path] 4 | 5 | set -e 6 | [ -n "$RAKUENV_DEBUG" ] && set -x 7 | 8 | # Provide rakuenv completions 9 | if [ "$1" = "--complete" ]; then 10 | echo --path 11 | exec rakuenv-shims --short 12 | fi 13 | 14 | if [ "$1" = "--path" ]; then 15 | print_paths="1" 16 | shift 17 | else 18 | print_paths="" 19 | fi 20 | 21 | whence() { 22 | local command="$1" 23 | rakuenv-versions --bare | while read -r version; do 24 | path="$(rakuenv-prefix "$version")/bin/${command}" 25 | if [ -x "$path" ]; then 26 | [ "$print_paths" ] && echo "$path" || echo "$version" 27 | fi 28 | path="$(rakuenv-prefix "$version")/share/perl6/site/bin/${command}" 29 | if [ -x "$path" ]; then 30 | [ "$print_paths" ] && echo "$path" || echo "$version" 31 | fi 32 | done 33 | } 34 | 35 | RAKUENV_COMMAND="$1" 36 | if [ -z "$RAKUENV_COMMAND" ]; then 37 | rakuenv-help --usage whence >&2 38 | exit 1 39 | fi 40 | 41 | result="$(whence "$RAKUENV_COMMAND")" 42 | [ -n "$result" ] && echo "$result" 43 | -------------------------------------------------------------------------------- /libexec/rakuenv-which: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Summary: Display the full path to an executable 4 | # 5 | # Usage: rakuenv which 6 | # 7 | # Displays the full path to the executable that rakuenv will invoke when 8 | # you run the given command. 9 | 10 | set -e 11 | [ -n "$RAKUENV_DEBUG" ] && set -x 12 | 13 | # Provide rakuenv completions 14 | if [ "$1" = "--complete" ]; then 15 | exec rakuenv-shims --short 16 | fi 17 | 18 | remove_from_path() { 19 | local path_to_remove="$1" 20 | local path_before 21 | local result=":${PATH//\~/$HOME}:" 22 | while [ "$path_before" != "$result" ]; do 23 | path_before="$result" 24 | result="${result//:$path_to_remove:/:}" 25 | done 26 | result="${result%:}" 27 | echo "${result#:}" 28 | } 29 | 30 | RAKUENV_COMMAND="$1" 31 | 32 | if [ -z "$RAKUENV_COMMAND" ]; then 33 | rakuenv-help --usage which >&2 34 | exit 1 35 | fi 36 | 37 | RAKUENV_VERSION="${RAKUENV_VERSION:-$(rakuenv-version-name)}" 38 | 39 | if [ "$RAKUENV_VERSION" = "system" ]; then 40 | PATH="$(remove_from_path "${RAKUENV_ROOT}/shims")" \ 41 | RAKUENV_COMMAND_PATH="$(command -v "$RAKUENV_COMMAND" || true)" 42 | else 43 | RAKUENV_COMMAND_PATH="${RAKUENV_ROOT}/versions/${RAKUENV_VERSION}/bin/${RAKUENV_COMMAND}" 44 | if [ ! -x "$RAKUENV_COMMAND_PATH" ]; then 45 | RAKUENV_COMMAND_PATH="${RAKUENV_ROOT}/versions/${RAKUENV_VERSION}/share/perl6/site/bin/${RAKUENV_COMMAND}" 46 | fi 47 | fi 48 | 49 | OLDIFS="$IFS" 50 | IFS=$'\n' scripts=(`rakuenv-hooks which`) 51 | IFS="$OLDIFS" 52 | for script in "${scripts[@]}"; do 53 | source "$script" 54 | done 55 | 56 | if [ -x "$RAKUENV_COMMAND_PATH" ]; then 57 | echo "$RAKUENV_COMMAND_PATH" 58 | elif [ "$RAKUENV_VERSION" != "system" ] && [ ! -d "${RAKUENV_ROOT}/versions/${RAKUENV_VERSION}" ]; then 59 | echo "rakuenv: version \`$RAKUENV_VERSION' is not installed (set by $(rakuenv-version-origin))" >&2 60 | exit 1 61 | else 62 | echo "rakuenv: $RAKUENV_COMMAND: command not found" >&2 63 | 64 | versions="$(rakuenv-whence "$RAKUENV_COMMAND" || true)" 65 | if [ -n "$versions" ]; then 66 | { echo 67 | echo "The \`$1' command exists in these Raku versions:" 68 | echo "$versions" | sed 's/^/ /g' 69 | echo 70 | } >&2 71 | fi 72 | 73 | exit 127 74 | fi 75 | -------------------------------------------------------------------------------- /rakuenv.d/rehash/rehash_zef.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | ZEF_SHIM_PATH="$SHIM_PATH/zef" 5 | 6 | command -p cat > "$ZEF_SHIM_PATH" <