├── zvm-shell-integration.zsh ├── LICENSE ├── zvm.zsh-completion ├── README.md ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md └── zvm /zvm-shell-integration.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | typeset -g ZVM_DIR=${ZVM_DIR:-"${ZDOTDIR:-$HOME}/.zvm"} 4 | 5 | path=( 6 | ${ZVM_DIR}/bin 7 | ${ZVM_DIR}/scripts 8 | $path 9 | ) 10 | 11 | fpath=( 12 | ${ZVM_DIR}/site-functions 13 | ${ZVM_DIR}/functions 14 | $fpath 15 | ) 16 | 17 | manpath=( 18 | ${ZVM_DIR}/man 19 | $manpath 20 | ) 21 | 22 | typeset -g ZVM_GLOBAL_VERSION 23 | 24 | autoload -U add-zsh-hook 25 | load-zvmrc() { 26 | if [[ $ZVM_AUTO_USE -ne 1 ]]; then 27 | return 28 | fi 29 | 30 | version=$(zvm dir --quiet 2>&1) 31 | if [[ -n $version ]]; then 32 | if [[ $version != $(zvm current) ]]; then 33 | ZVM_GLOBAL_VERSION=$(zvm current) 34 | zvm use $version 35 | fi 36 | 37 | return 38 | fi 39 | 40 | if [[ -n $ZVM_GLOBAL_VERSION ]]; then 41 | zvm use ${ZVM_GLOBAL_VERSION} 42 | ZVM_GLOBAL_VERSION='' 43 | fi 44 | } 45 | add-zsh-hook chpwd load-zvmrc 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 James Dinsdale 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /zvm.zsh-completion: -------------------------------------------------------------------------------- 1 | #compdef zvm 2 | 3 | _zvm_commands=( 4 | 'current:Output the current version' 5 | 'dir:Output the version for the current directory, or set it to the specified version' 6 | 'default:Output the default version, or set the default to the specified version' 7 | 'install:Install the specified ZSH version' 8 | 'list:List available versions' 9 | 'remove:Remove the specified ZSH version' 10 | 'use:Switch to the specified ZSH version, or the version defined in .zvmrc, or the default' 11 | ) 12 | 13 | _zvm() { 14 | typeset -A opt_args 15 | local context state line curcontext="$curcontext" 16 | 17 | _arguments -A \ 18 | '(-h --help)'{-h,--help}'[show help text and exit]' \ 19 | '(-v --version)'{-v,--version}'[show version information and exit]' 20 | 21 | _arguments \ 22 | '1: :_zvm_cmds' \ 23 | '*::arg:->args' 24 | 25 | case "$state" in 26 | args ) 27 | case "$words[1]" in 28 | list ) 29 | _arguments -A \ 30 | '(-h --help)'{-h,--help}'[show help text and exit]' \ 31 | '(-i --installed)'{-i,--installed}'[only list installed versions]' \ 32 | '(-p --prerelease)'{-p,--prerelease}'[include pre-release versions in results]' 33 | ;; 34 | current ) 35 | _arguments -A \ 36 | '(-h --help)'{-h,--help}'[show help text and exit]' \ 37 | '(-q --quiet)'{-q,--quiet}'[suppress output]' 38 | ;; 39 | default ) 40 | _arguments -A \ 41 | '(-h --help)'{-h,--help}'[show help text and exit]' \ 42 | '(-q --quiet)'{-q,--quiet}'[suppress output]' 43 | 44 | _arguments \ 45 | '*:version:_zvm_all_versions' 46 | ;; 47 | use|install ) 48 | _arguments -A \ 49 | '(-h --help)'{-h,--help}'[show help text and exit]' 50 | 51 | _arguments \ 52 | '*:version:_zvm_all_versions' 53 | ;; 54 | remove ) 55 | _arguments -A \ 56 | '(-h --help)'{-h,--help}'[show help text and exit]' 57 | 58 | _arguments \ 59 | '*:version:_zvm_installed_versions' 60 | ;; 61 | esac 62 | ;; 63 | esac 64 | } 65 | 66 | (( $+functions[_zvm_cmds] )) || _zvm_cmds() { 67 | _describe -t commands 'commands' _zvm_commands "$@" 68 | } 69 | 70 | (( $+functions[_zvm_all_versions] )) || _zvm_all_versions() { 71 | versions=($(zvm list --simple)) 72 | _describe -t versions 'versions' versions "$@" 73 | } 74 | 75 | (( $+functions[_zvm_installed_versions] )) || _zvm_installed_versions() { 76 | versions=($(zvm list --installed --simple)) 77 | _describe -t versions 'versions' versions "$@" 78 | } 79 | 80 | _zvm "$@" 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zvm 2 | 3 | [![Join the chat at https://gitter.im/molovo/zvm](https://badges.gitter.im/molovo/zvm.svg)](https://gitter.im/molovo/zvm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | The ZSH version manager 6 | 7 | ## Installation 8 | 9 | > **WARNING**: Although the majority of zvm's functionality works as expected, it is in the early stages of development, and as such bugs are likely to be present. Please continue with caution, and [report any issues](https://github.com/molovo/zvm/issues) you may have. 10 | 11 | ### Requirements 12 | 13 | * ZSH `4.3.12` or above 14 | * git `1.9.1` or above 15 | * GCC and Make (Installed by default on OSX. For Ubuntu, run `sudo apt-get install build-essential autoconf ncurses-dev yodl`) 16 | 17 | ### Installing with [zulu](https://zulu.sh) 18 | 19 | Zulu will automatically install dependencies and the shell integration for you. 20 | 21 | ```sh 22 | zulu install zvm 23 | ``` 24 | 25 | ### Manual Installation 26 | 27 | First, Install [color](https://github.com/molovo/color) and [revolver](https://github.com/molovo/revolver) 28 | 29 | ```sh 30 | git clone https://github.com/molovo/zvm zvm 31 | ln -s "$PWD/zvm/zvm" /usr/local/bin 32 | echo "source $PWD/zvm/zvm-shell-integration.zsh" >> ~/.zshrc 33 | ``` 34 | 35 | By default, zvm stores the ZSH source and compiled binaries in `~/.zvm`. If you'd like to store it somewhere else, set `$ZVM_DIR` to an absolute path in `~/.zshrc` before you run zvm for the first time. 36 | 37 | ## Usage 38 | 39 | The first time you run `zvm list`, `zvm use` or `zvm install`, zvm will check for and download the ZSH source, and set up its internal directory structure. 40 | 41 | ### Listing available versions 42 | 43 | ```sh 44 | # List all stable versions 45 | zvm list 46 | 47 | # List only installed versions 48 | zvm list --installed 49 | 50 | # Include pre-release versions in results 51 | zvm list --prerelease 52 | ``` 53 | 54 | ### Switching versions 55 | 56 | ```sh 57 | # Use the default version 58 | zvm use 59 | 60 | # Use the specified version. It will be compiled and installed if 61 | # it hasn't been already 62 | zvm use 5.3.1 63 | 64 | # Show the default 65 | zvm default 66 | 67 | # Show the current version 68 | zvm current 69 | 70 | # Set the default to a new version. It will be compiled and installed if 71 | # it hasn't been already 72 | zvm default 4.3.12 73 | 74 | # Install a new version without selecting it 75 | zvm install 5.0.2 76 | ``` 77 | 78 | ### Using different versions on a per-project basis 79 | 80 | You can set the ZSH version for a specific project by running `zvm dir ` within the project's directory, which will create a `.zvmrc` file in the current directory. If you run `zvm use` without specifying a version in a directory with a `.zvmrc` file, it will automatically choose the version specified in `.zvmrc`. 81 | 82 | #### Using per-project versions automatically. 83 | 84 | Setting `ZVM_AUTO_USE=1` adds a hook which automatically changes the version when you `cd` into a directory with a `.zvmrc` file. 85 | 86 | ## License 87 | 88 | Copyright (c) 2016 James Dinsdale (molovo.co) 89 | 90 | zvm is licensed under The MIT License (MIT) 91 | 92 | ## Team 93 | 94 | * [James Dinsdale](http://molovo.co) 95 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at hi@molovo.co. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to zvm 2 | 3 | ✨ Thanks for contributing to zvm! ✨ 4 | 5 | Please note that this project is released with a [Contributor Code of Conduct](code-of-conduct.md). By participating in this project you agree to abide by its terms. 6 | 7 | ## How can I contribute? 8 | 9 | ### Improve documentation 10 | 11 | As a user of zvm you're the perfect candidate to help us improve our documentation. Typo corrections, error fixes, better explanations, more examples, etc. Open issues for things that could be improved. Anything. Even improvements to this document. 12 | 13 | Use the [`docs` label](https://github.com/molovo/zvm/labels/docs) to find suggestions for what we'd love to see more documentation on. 14 | 15 | ### Improve issues 16 | 17 | Some issues are created with missing information, not reproducible, or plain invalid. Help make them easier to resolve. Handling issues takes a lot of time that we could rather spend on fixing bugs and adding features. 18 | 19 | ### Give feedback on issues 20 | 21 | We're always looking for more opinions on discussions in the issue tracker. It's a good opportunity to influence the future direction of zvm. 22 | 23 | The [`question` label](https://github.com/molovo/zvm/labels/question) is a good place to find ongoing discussions. 24 | 25 | ### Write code 26 | 27 | You can use issue labels to discover issues you could help out with: 28 | 29 | * [`blocked` issues](https://github.com/molovo/zvm/labels/blocked) need help getting unstuck 30 | * [`bug` issues](https://github.com/molovo/zvm/labels/bug) are known bugs we'd like to fix 31 | * [`enhancement` issues](https://github.com/molovo/zvm/labels/enhancement) are features we're open to including 32 | * [`performance` issues](https://github.com/molovo/zvm/labels/performance) track ideas on how to improve zvm’s performance 33 | 34 | The [`help wanted`](https://github.com/molovo/zvm/labels/help%20wanted) and [`good for beginner`](https://github.com/molovo/zvm/labels/good%20for%20beginner) labels are especially useful. 35 | 36 | You may find an issue is assigned, or has the [`assigned` label](https://github.com/molovo/zvm/labels/assigned). Please double-check before starting on this issue because somebody else is likely already working on it. 37 | 38 | We'd like to fix [`priority` issues](https://github.com/molovo/zvm/labels/priority) first. We'd love to see progress on [`low-priority` issues](https://github.com/molovo/zvm/labels/low%20priority) too. [`future` issues](https://github.com/molovo/zvm/labels/future) are those that we'd like to get to, but not anytime soon. Please check before working on these since we may not yet want to take on the burden of supporting those features. 39 | 40 | ### Hang out in our chat 41 | 42 | We have a [chat](https://gitter.im/molovo/zvm). Jump in there and lurk, talk to us, and help others. 43 | 44 | ## Submitting an issue 45 | 46 | - The issue tracker is for issues. Use our [chat](https://gitter.im/molovo/zvm) for support. 47 | - Search the issue tracker before opening an issue. 48 | - Ensure you're using the latest version of zvm. 49 | - Use a clear and descriptive title. 50 | - Include as much information as possible: Steps to reproduce the issue, error message, ZSH version, operating system, etc. 51 | - The more time you put into an issue, the more we will. 52 | - [The best issue report is a failing test proving it.](https://twitter.com/sindresorhus/status/579306280495357953) 53 | 54 | ## Submitting a pull request 55 | 56 | - Non-trivial changes are often best discussed in an issue first, to prevent you from doing unnecessary work. 57 | - For ambitious tasks, you should try to get your work in front of the community for feedback as soon as possible. Open a pull request as soon as you have done the minimum needed to demonstrate your idea. At this early stage, don't worry about making things perfect, or 100% complete. Add a [WIP] prefix to the title, and describe what you still need to do. This lets reviewers know not to nit-pick small details or point out improvements you already know you need to make. 58 | - New features should be accompanied with tests and documentation. 59 | - Don't include unrelated changes. 60 | - Make the pull request from a [topic branch](https://github.com/dchelimsky/rspec/wiki/Topic-Branches), not master. 61 | - Use a clear and descriptive title for the pull request and commits. 62 | - Write a convincing description of why we should land your pull request. It's your job to convince us. Answer "why" it's needed and provide use-cases. 63 | - You might be asked to do changes to your pull request. There's never a need to open another pull request. [Just update the existing one.](https://github.com/RichardLitt/docs/blob/master/amending-a-commit-guide.md) 64 | -------------------------------------------------------------------------------- /zvm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | # Set some global variables 4 | typeset -g ZVM_DIR=${ZVM_DIR:-"${ZDOTDIR:-$HOME}/.zvm"} 5 | typeset -g ZVM_SRC_DIR=${ZVM_SRC_DIR:-"${ZVM_DIR}/src"} 6 | typeset -g ZVM_LOG_DIR=${ZVM_LOG_DIR:-"${ZVM_DIR}/log"} 7 | typeset -g ZVM_COMPILE_DIR=${ZVM_COMPILE_DIR:-"${ZVM_DIR}/compiled"} 8 | 9 | ### 10 | # Output version information 11 | ### 12 | function _zvm_version() { 13 | echo '0.2.3' 14 | } 15 | 16 | ### 17 | # Output usage information 18 | ### 19 | function _zvm_usage() { 20 | echo ZVM $(_zvm_version) 21 | echo 22 | echo $(color yellow 'Usage:') 23 | echo ' zvm [options] ' 24 | echo 25 | echo $(color yellow 'Commands:') 26 | echo ' current Output the current version' 27 | echo ' dir [] Output the version for the current directory, or' 28 | echo ' set it to the specified version' 29 | echo ' default [] Output the default version, or set the default' 30 | echo ' to the specified version' 31 | echo ' install Install the specified ZSH version' 32 | echo ' list List available versions' 33 | echo ' remove Remove the specified ZSH version' 34 | echo ' use [] Switch to the specified ZSH version, or the' 35 | echo ' version defined in .zvmrc, or the default' 36 | } 37 | 38 | ### 39 | # Install the directories ZVM needs to operate 40 | ### 41 | function _zvm_self_install() { 42 | if [[ -d ${ZVM_DIR} ]]; then 43 | echo $(color red bold "${ZVM_DIR} already exists. Is ZVM already installed?") 44 | echo "Remove ${ZVM_DIR} to continue" 45 | exit 1 46 | fi 47 | 48 | revolver start 'Creating ZVM directory structure' 49 | mkdir -p ${ZVM_DIR}/{compiled,src,log} 50 | 51 | revolver update 'Cloning ZSH source' 52 | local repo='https://github.com/zsh-users/zsh' 53 | if ! git clone "$repo" "${ZVM_SRC_DIR}" >/dev/null 2>&1; then 54 | echo $(color red bold "Failed to download ZSH source") 55 | exit 1 56 | fi 57 | 58 | revolver stop 59 | } 60 | 61 | ### 62 | # Check if a ZSH version is installed 63 | ### 64 | function _zvm_is_installed() { 65 | local version="$1" 66 | 67 | _zvm_list --installed --simple | grep -E "^$version$" >/dev/null 2>&1 68 | } 69 | 70 | ### 71 | # Check if a ZSH version is valid 72 | ### 73 | function _zvm_is_valid() { 74 | local version="$1" 75 | 76 | _zvm_list --simple | grep -E "^$version$" >/dev/null 2>&1 77 | } 78 | 79 | ### 80 | # List available ZSH versions 81 | ### 82 | function _zvm_list() { 83 | local installed prerelease search current default version versions out 84 | 85 | zparseopts -D \ 86 | i=installed -installed=installed \ 87 | p=prerelease -prerelease=prerelease \ 88 | s=simple -simple=simple 89 | 90 | # If ZVM hasn't set itself up, do it now 91 | if [[ ! -d "${ZVM_DIR}" ]]; then 92 | _zvm_self_install 93 | fi 94 | 95 | [[ -f "${ZVM_DIR}/.current" ]] && current=$(cat "${ZVM_DIR}/.current") 96 | [[ -f "${ZVM_DIR}/.default" ]] && default=$(cat "${ZVM_DIR}/.default") 97 | 98 | # Our basic search command 99 | # Matches all tags in the source repository matching 'zsh-x.x.x' 100 | search="git tag | grep -E '^zsh-[0-9]+\.[0-9]+(\.[0-9]+)?$'" 101 | 102 | # If --prerelease is specified, we extend the search to match 'zsh-x.x.x-*' 103 | if [[ -n $prerelease ]]; then 104 | search="git tag | grep -E '^zsh-[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?'" 105 | fi 106 | 107 | # If --installed is specified, we filter the list of results to 108 | # the list of directories in ${ZVM_DIR}/compiled 109 | if [[ -n $installed ]]; then 110 | search="$search | grep -E '^zsh-(${(j.|.)${:-${(@f)$(ls "${ZVM_DIR}/compiled")}}//./\.})$'" 111 | fi 112 | 113 | # cd to the source directory, and ensure it's up to date 114 | cd ${ZVM_SRC_DIR} 115 | git fetch origin 116 | 117 | # Execute the search command and store the results in an array 118 | versions=($(eval "$search") 'system') 119 | 120 | # If --simple is specified, just print the list straight to screen 121 | if [[ -n $simple ]]; then 122 | echo ${(@F)^versions//zsh-/} 123 | return 124 | fi 125 | 126 | # Loop through each of the versions 127 | for version in ${^versions//zsh-/}; do 128 | flags="" 129 | 130 | if [[ $version = $current ]]; then 131 | flags+=$(color yellow '➾ ') 132 | else 133 | flags+=' ' 134 | fi 135 | 136 | if [[ $version = $default ]]; then 137 | flags+=$(color magenta '● ') 138 | else 139 | flags+=' ' 140 | fi 141 | 142 | # if _zvm_is_installed $version; then 143 | if [[ -d "${ZVM_COMPILE_DIR}/${version}" ]]; then 144 | flags+=$(color green '✔ ') 145 | else 146 | flags+=' ' 147 | fi 148 | 149 | echo "$flags $version" 150 | done 151 | 152 | echo 153 | echo "$(color yellow '➾ ') current" 154 | echo "$(color magenta '● ') default" 155 | echo "$(color green '✔ ') installed" 156 | } 157 | 158 | ### 159 | # Set the default version to use 160 | # If no version is passed, return the current default 161 | ### 162 | function _zvm_default() { 163 | local version quiet 164 | 165 | zparseopts -D q=quiet -quiet=quiet 166 | 167 | version="$1" 168 | 169 | if [[ -z $version ]]; then 170 | if [[ -f "${ZVM_DIR}/.default" ]]; then 171 | echo $(cat "${ZVM_DIR}/.default") 172 | return 173 | fi 174 | 175 | [[ -z $quiet ]] && echo $(color yellow 'No default set. Run `zvm default `') 176 | return 1 177 | fi 178 | 179 | if ! _zvm_is_installed $version; then 180 | _zvm_install $version 181 | fi 182 | 183 | echo $version >! "${ZVM_DIR}/.default" 184 | 185 | echo "$(color green '✔') Default set to ZSH version $version" 186 | } 187 | 188 | ### 189 | # Output the current version 190 | ### 191 | function _zvm_current() { 192 | local quiet 193 | 194 | zparseopts -D q=quiet -quiet=quiet 195 | 196 | if [[ -f "${ZVM_DIR}/.current" ]]; then 197 | echo $(cat "${ZVM_DIR}/.current") 198 | return 199 | fi 200 | 201 | [[ -z $quiet ]] && echo $(color yellow 'No version set. Run `zvm use`') 202 | return 1 203 | } 204 | 205 | ### 206 | # Remove an installed ZSH version 207 | function _zvm_remove() { 208 | local version="$1" 209 | 210 | if ! _zvm_is_installed $version; then 211 | echo $(color red bold "ZSH version $version is not installed") 212 | exit 1 213 | fi 214 | 215 | if [[ "$(_zvm_current --quiet)" = "$version" ]]; then 216 | _zvm_unuse $version 217 | fi 218 | 219 | if [[ "$(_zvm_default --quiet)" = "$version" ]]; then 220 | rm "${ZVM_DIR}/.default" 221 | fi 222 | 223 | [[ -d "${ZVM_COMPILE_DIR}/${version}" ]] && rm -rf "${ZVM_COMPILE_DIR}/${version}" 224 | 225 | echo "$(color green '✔') ZSH version $version removed" 226 | } 227 | 228 | ### 229 | # Set the version to use within the current directory 230 | # If no version is passed, return the current version for this directory 231 | ### 232 | function _zvm_dir() { 233 | local version quiet 234 | 235 | zparseopts -D q=quiet -quiet=quiet 236 | 237 | version="$1" 238 | 239 | if [[ -z $version ]]; then 240 | local filename=".zvmrc" filepath="$PWD" 241 | while [[ "$filepath" != '/' ]]; do 242 | if [[ -f "$filepath/$filename" && -r "$filepath/$filename" ]]; then 243 | echo $(cat "$filepath/$filename") 244 | return 245 | fi 246 | 247 | filepath=$(dirname $filepath) 248 | done 249 | 250 | [[ -z $quiet ]] && echo $(color yellow "No version set for $PWD. Run \`zvm use \`") 251 | return 1 252 | fi 253 | 254 | if ! _zvm_is_installed $version; then 255 | _zvm_install $version 256 | fi 257 | 258 | echo $version >! "${PWD}/.zvmrc" 259 | echo "$(color green '✔') ZSH version $version set for directory $PWD" 260 | } 261 | 262 | ### 263 | # Unset the currently selected version 264 | ### 265 | function _zvm_unuse() { 266 | # Remove links to the current version 267 | [[ -L "${ZVM_DIR}/bin" ]] && rm "${ZVM_DIR}/bin" 268 | [[ -L "${ZVM_DIR}/scripts" ]] && rm "${ZVM_DIR}/scripts" 269 | [[ -L "${ZVM_DIR}/site-functions" ]] && rm "${ZVM_DIR}/site-functions" 270 | [[ -L "${ZVM_DIR}/functions" ]] && rm "${ZVM_DIR}/functions" 271 | [[ -L "${ZVM_DIR}/lib" ]] && rm "${ZVM_DIR}/lib" 272 | [[ -L "${ZVM_DIR}/man" ]] && rm "${ZVM_DIR}/man" 273 | 274 | # Remove the current defined version 275 | [[ -f "${ZVM_DIR}/.current" ]] && rm "${ZVM_DIR}/.current" 276 | } 277 | 278 | ### 279 | # Use a specific ZSH version. 280 | # If no version is specified, the default is used. 281 | # If the chosen version is not installed, it is done now. 282 | ### 283 | function _zvm_use() { 284 | local version="$1" 285 | 286 | # If no version is provided, check for a .zvmrc 287 | if [[ -z $version ]]; then 288 | version=$(_zvm_dir --quiet) 289 | fi 290 | 291 | # If no version is provided, try and find the default 292 | if [[ -z $version || $version = "default" ]]; then 293 | version=$(_zvm_default --quiet) 294 | fi 295 | 296 | # If we still don't have a version, exit with an error 297 | if [[ -z $version ]]; then 298 | echo $(color red bold 'You must specify a version, or set a default first using `zvm default `') 299 | exit 1 300 | fi 301 | 302 | if [[ $version = $(_zvm_current --quiet) ]]; then 303 | echo "$(color green '✔') ZSH version $version is already the current version" 304 | return 305 | fi 306 | 307 | if [[ $version = 'system' ]]; then 308 | _zvm_unuse 309 | echo $version > "${ZVM_DIR}/.current" 310 | echo "$(color green '✔') Reverted to system ZSH version" 311 | return 312 | fi 313 | 314 | # If ZVM hasn't set itself up, do it now 315 | if [[ ! -d "${ZVM_DIR}" ]]; then 316 | _zvm_self_install 317 | fi 318 | 319 | # If the requested version is not installed, do it now 320 | if [[ ! -d "${ZVM_COMPILE_DIR}/$version" ]]; then 321 | _zvm_install $version 322 | fi 323 | 324 | # Remove existing links first 325 | _zvm_unuse $version 326 | 327 | # Store the current version 328 | echo $version > "${ZVM_DIR}/.current" 329 | 330 | # Create new symlinks 331 | local share="${ZVM_COMPILE_DIR}/${version}/share" 332 | ln -s "${ZVM_COMPILE_DIR}/${version}/bin" "${ZVM_DIR}/bin" 333 | ln -s "${share}/zsh/${version}/scripts" "${ZVM_DIR}/scripts" 334 | ln -s "${share}/zsh/${version}/functions" "${ZVM_DIR}/functions" 335 | ln -s "${share}/zsh/site-functions" "${ZVM_DIR}/site-functions" 336 | ln -s "${share}/man" "${ZVM_DIR}/man" 337 | ln -s "${ZVM_COMPILE_DIR}/${version}/lib" "${ZVM_DIR}/lib" 338 | 339 | echo "$(color green '✔') Switched to ZSH version $version" 340 | } 341 | 342 | ### 343 | # Install a ZSH version 344 | ### 345 | function _zvm_install() { 346 | local version="$1" logfile 347 | 348 | # If ZVM hasn't set itself up, do it now 349 | if [[ ! -d "${ZVM_DIR}" ]]; then 350 | _zvm_self_install 351 | fi 352 | 353 | # Set up the logfile path 354 | logfile="${ZVM_LOG_DIR}/$(date '+%Y%m%d-%H%M%S')-${version}-installation.log" 355 | 356 | if [[ ! -d "${ZVM_DIR}" ]]; then 357 | _zvm_self_install 358 | fi 359 | 360 | # Check if the requested version is already installed 361 | if _zvm_is_installed $version; then 362 | echo $(color red bold "ZSH version $version already installed. Remove it first") 363 | exit 1 364 | fi 365 | 366 | if ! _zvm_is_valid $version; then 367 | echo $(color red bold "ZSH version $version is not recognised. See \`zvm list\`") 368 | exit 1 369 | fi 370 | 371 | # Make sure we exit if we hit an error 372 | setopt localoptions ERR_EXIT 373 | 374 | # Clear the logfile 375 | cat /dev/null >! $logfile 376 | 377 | revolver start "Installing ZSH $version" 378 | cd ${ZVM_SRC_DIR} 379 | 380 | # Remove any local changes if they exist 381 | revolver update 'Removing artefacts from previous build...' 382 | if ! git reset --hard >>$logfile 2>&1; then 383 | echo $(color red bold "Failed to remove artefacts from previous build") 384 | echo "See $logfile for details" 385 | exit 1 386 | fi 387 | echo "$(color green '✔') Removed artefacts from previous build" 388 | 389 | # Checkout the correct branch 390 | revolver update "Checking out $version..." 391 | if ! git checkout zsh-${version} >>$logfile 2>&1; then 392 | echo $(color red bold "Failed to checkout zsh-$version tag") 393 | echo "See $logfile for details" 394 | exit 1 395 | fi 396 | echo "$(color green '✔') Checked out zsh-$version" 397 | 398 | # Create and cd to the compilation directory 399 | revolver update "Creating compilation directory..." 400 | if ! mkdir -p "${ZVM_COMPILE_DIR}/$version" >>$logfile 2>&1; then 401 | echo $(color red bold "Failed to create compilation directory") 402 | echo "See $logfile for details" 403 | exit 1 404 | fi 405 | echo "$(color green '✔') Created compilation directory at ${ZVM_COMPILE_DIR}/$version" 406 | 407 | # Run configuration scripts 408 | revolver update 'Running configuration scripts...' 409 | if ! ./Util/preconfig >>$logfile 2>&1; then 410 | echo $(color red bold "Failed at preconfigure step") 411 | echo "See $logfile for details" 412 | exit 1 413 | fi 414 | echo "$(color green '✔') Preconfigure scripts completed successfully" 415 | 416 | if ! ./configure --prefix="${ZVM_COMPILE_DIR}/$version" >>$logfile 2>&1; then 417 | echo $(color red bold "Failed at configure step") 418 | echo "See $logfile for details" 419 | exit 1 420 | fi 421 | echo "$(color green '✔') Configure scripts completed successfully" 422 | 423 | # Run compile script 424 | revolver update "Compiling..." 425 | if ! make >>$logfile 2>&1; then 426 | echo $(color red bold "Failed at compilation step") 427 | echo "See $logfile for details" 428 | exit 1 429 | fi 430 | echo "$(color green '✔') Build complete" 431 | 432 | # Check build 433 | revolver update "Checking build..." 434 | if ! make check >>$logfile 2>&1; then 435 | echo $(color red bold "Post build checks failed") 436 | echo "See $logfile for details" 437 | exit 1 438 | fi 439 | echo "$(color green '✔') Post-build checks passed" 440 | 441 | # Install 442 | revolver update "Installing binaries..." 443 | if ! make install.bin >>$logfile 2>&1; then 444 | echo $(color red bold "Installation of binaries failed") 445 | echo "See $logfile for details" 446 | exit 1 447 | fi 448 | echo "$(color green '✔') Installed binaries" 449 | 450 | # Install 451 | revolver update "Installing modules..." 452 | if ! make install.modules >>$logfile 2>&1; then 453 | echo $(color red bold "Installation of modules failed") 454 | echo "See $logfile for details" 455 | exit 1 456 | fi 457 | echo "$(color green '✔') Installed modules" 458 | 459 | # Install 460 | revolver update "Installing functions..." 461 | if ! make install.fns >>$logfile 2>&1; then 462 | echo $(color red bold "Installation of functions failed") 463 | echo "See $logfile for details" 464 | exit 1 465 | fi 466 | echo "$(color green '✔') Installed functions" 467 | 468 | # if ! builtin type yodl >/dev/null 2>&1; then 469 | # echo "$(color yellow '‼') yodl not installed. Skipping installation of man pages" 470 | # else 471 | # # Install 472 | # revolver update "Installing man pages..." 473 | # if ! make install.man >>$logfile 2>&1; then 474 | # echo $(color red bold "Installation of man pages failed") 475 | # echo "See $logfile for details" 476 | # exit 1 477 | # fi 478 | # echo "$(color green '✔') Installed man pages" 479 | # fi 480 | 481 | revolver stop 482 | echo "$(color green '✔') Successfully installed ZSH $version" 483 | } 484 | 485 | ### 486 | # The main zvm function 487 | ### 488 | function _zvm() { 489 | local help version ctx="$1" 490 | 491 | zparseopts -D \ 492 | h=help -help=help \ 493 | v=version -version=version 494 | 495 | # If --help is specified, output usage information and exit 496 | if [[ -n $help ]]; then 497 | _zvm_usage 498 | exit 499 | fi 500 | 501 | # If --version is specified, output version information and exit 502 | if [[ -n $version ]]; then 503 | _zvm_version 504 | exit 505 | fi 506 | 507 | case $ctx in 508 | use ) 509 | shift 510 | _zvm_use "$@" 511 | ;; 512 | default ) 513 | shift 514 | _zvm_default "$@" 515 | ;; 516 | current ) 517 | shift 518 | _zvm_current "$@" 519 | ;; 520 | install ) 521 | shift 522 | _zvm_install "$@" 523 | ;; 524 | list ) 525 | shift 526 | _zvm_list "$@" 527 | ;; 528 | remove ) 529 | shift 530 | _zvm_remove "$@" 531 | ;; 532 | dir ) 533 | shift 534 | _zvm_dir "$@" 535 | ;; 536 | remove ) 537 | shift 538 | _zvm_remove "$@" 539 | ;; 540 | * ) 541 | echo "\033[0;31mUnrecognised command $ctx\033[0;m" 542 | exit 1 543 | esac 544 | } 545 | 546 | _zvm "$@" 547 | --------------------------------------------------------------------------------