├── .gitignore ├── .github ├── workflows │ ├── lint.yaml │ └── test.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── SECURITY.md ├── test ├── test_alias.sh ├── test_ls_remote.sh ├── test_dvmrc_file.sh ├── test_install_version_by_prefix.sh ├── test_uninstall_version.sh ├── test_install_from_source.sh └── test_install_version.sh ├── legacy-versions ├── LICENSE ├── install.sh ├── bash_completion ├── CODE_OF_CONDUCT.md ├── README-CN.md ├── README.md └── dvm.sh /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | aliases/ 3 | versions/ 4 | coverage/ 5 | download/ 6 | deno_code/ 7 | cache/ 8 | 9 | # Editors 10 | .vscode 11 | 12 | # Misc 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | 12 | - name: Run shellcheck 13 | uses: ludeeus/action-shellcheck@master 14 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | v0.10.x | :white_check_mark: | 8 | | < 0.10.0 | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | Please create an issue at [this repo](#https://github.com/ghosind/dvm/issues) or email [@ghosind](mailto:ghosind@gmail.com) to report a potential security vulnerability. 13 | -------------------------------------------------------------------------------- /test/test_alias.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | # shellcheck disable=SC1091 9 | \. ./dvm.sh 10 | 11 | # set active version to other. 12 | dvm use v1.45.0 13 | dvm ls | grep "\-> v1.45.0" || dvm_test_error "active version should be v1.45.0" 14 | 15 | # set alias 16 | dvm alias default v1.40.0 || dvm_test_error "run 'dvm alias default v1.40.0' failed" 17 | 18 | # activate with alias name 19 | dvm use default || dvm_test_error "run 'dvm use default' failed" 20 | 21 | dvm ls | grep "\-> v1.40.0" || dvm_test_error "active version should be v1.40.0" 22 | -------------------------------------------------------------------------------- /test/test_ls_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | if [ "$(uname -s)" != "Linux" ] 9 | then 10 | # Just run this test case on Linux. 11 | exit 0 12 | fi 13 | 14 | # shellcheck disable=SC1091 15 | \. ./dvm.sh || dvm_test_error "failed to install dvm" 16 | 17 | versions=$(dvm ls-remote) 18 | 19 | [ "$(echo "$versions" | grep v0.1.0)" != "" ] || dvm_test_error "Deno v0.1.0 should in the remote versions list" 20 | 21 | # Not same page 22 | [ "$(echo "$versions" | grep v1.33.0)" != "" ] || dvm_test_error "Deno v1.33.0 should in the remote versions list" 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /test/test_dvmrc_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | # shellcheck disable=SC1091 9 | \. ./dvm.sh || dvm_test_error "failed to install dvm" 10 | 11 | echo "v1.45.0" > .dvmrc 12 | dvm use || dvm_test_error "run 'dvm use' failed" 13 | dvm ls | grep "\-> v1.45.0" || dvm_test_error "run 'dvm ls' failed" 14 | rm .dvmrc 15 | 16 | echo "v1.40.0" > .deno-version 17 | dvm use || dvm_test_error "run 'dvm use' failed" 18 | dvm ls | grep "\-> v1.40.0" || dvm_test_error "run 'dvm ls' failed" 19 | rm .deno-version 20 | 21 | echo "v1.44.4" > "$HOME/.dvmrc" 22 | dvm use || dvm_test_error "run 'dvm use' failed" 23 | dvm ls | grep "\-> v1.44.4" || dvm_test_error "run 'dvm ls' failed" 24 | rm "$HOME/.dvmrc" 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Use command '...' 16 | 2. See error 17 | 18 | **Expected behavior** 19 | A clear and concise description of what you expected to happen. 20 | 21 | **Screenshots** 22 | If applicable, add screenshots to help explain your problem. 23 | 24 | **Desktop (please complete the following information):** 25 | - OS: [e.g. Linux] 26 | - Architecture: [e.g. x86, ARM] 27 | - Version [e.g. v0.7.1] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /test/test_install_version_by_prefix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | # shellcheck disable=SC1091 9 | \. ./dvm.sh || dvm_test_error "failed to install dvm" 10 | 11 | # Install deno by prefix 12 | dvm install 1.44 || dvm_test_error "run 'dvm install 1.44' failed" 13 | dvm ls | grep "v1.44.4" || dvm_test_error "run 'dvm ls' failed" 14 | 15 | # Skip if run on MacOS with m-chip 16 | if [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "arm64" ] 17 | then 18 | if dvm install 1.2 19 | then 20 | dvm_test_error "Deno v1.2 should not be installed on MacOS with m-chip" 21 | fi 22 | else 23 | dvm install 1.2 || dvm_test_error "run 'dvm install 1.2' failed" 24 | dvm ls | grep "v1.2.3" || dvm_test_error "run 'dvm ls' failed" 25 | fi 26 | -------------------------------------------------------------------------------- /test/test_uninstall_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | # shellcheck disable=SC1091 9 | \. ./dvm.sh 10 | 11 | # Set alias name 'default' to v1.14.0 12 | dvm alias default v1.45.0 || dvm_test_error "run 'dvm alias default v1.45.0' failed" 13 | 14 | # Uninstall by alias name 15 | dvm uninstall default || dvm_test_error "run 'dvm uninstall default' failed" 16 | [ ! -f "$DVM_DIR/versions/v1.45.0/deno" ] || dvm_test_error "deno v1.45.0 should be uninstalled" 17 | 18 | # Install deno v1.14.0 again 19 | dvm install v1.45.0 20 | 21 | dvm deactivate 22 | 23 | # Uninstall by version 24 | dvm uninstall v1.45.0 || dvm_test_error "run 'dvm uninstall v1.45.0' failed" 25 | [ ! -f "$DVM_DIR/versions/v1.45.0/deno" ] || dvm_test_error "deno v1.45.0 should be uninstalled" 26 | -------------------------------------------------------------------------------- /test/test_install_from_source.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | # shellcheck disable=SC1091 9 | \. ./dvm.sh || dvm_test_error "failed to install dvm" 10 | 11 | # Install deno v1.36.0 12 | TARGET_VERSION="1.36.0" 13 | dvm install "v$TARGET_VERSION" --from-source || dvm_test_error "run 'dvm install v$TARGET_VERSION' failed" 14 | 15 | # Check installed version directory 16 | [ -d "$DVM_DIR/versions/v$TARGET_VERSION" ] || dvm_test_error "'$DVM_DIR/versions/v$TARGET_VERSION' is not a directory" 17 | 18 | # Check deno version 19 | dvm run "v$TARGET_VERSION" --version | grep "deno $TARGET_VERSION" || dvm_test_error "deno is invalid" 20 | 21 | # Set active version 22 | dvm use "v$TARGET_VERSION" || dvm_test_error "run 'dvm use v$TARGET_VERSION' failed" 23 | 24 | # Check with ls command 25 | dvm ls | grep "\-> v$TARGET_VERSION" || dvm_test_error "run 'dvm ls' failed" 26 | -------------------------------------------------------------------------------- /legacy-versions: -------------------------------------------------------------------------------- 1 | v0.1.0 2 | v0.1.1 3 | v0.1.2 4 | v0.1.3 5 | v0.1.4 6 | v0.1.5 7 | v0.1.6 8 | v0.1.7 9 | v0.1.8 10 | v0.1.9 11 | v0.1.10 12 | v0.1.11 13 | v0.1.12 14 | v0.2.0 15 | v0.2.1 16 | v0.2.2 17 | v0.2.3 18 | v0.2.4 19 | v0.2.5 20 | v0.2.6 21 | v0.2.7 22 | v0.2.8 23 | v0.2.9 24 | v0.2.10 25 | v0.2.11 26 | v0.3.0 27 | v0.3.1 28 | v0.3.2 29 | v0.3.3 30 | v0.3.4 31 | v0.3.5 32 | v0.3.6 33 | v0.3.7 34 | v0.3.8 35 | v0.3.9 36 | v0.3.10 37 | v0.3.11 38 | v0.4.0 39 | v0.5.0 40 | v0.6.0 41 | v0.7.0 42 | v0.8.0 43 | v0.9.0 44 | v0.10.0 45 | v0.11.0 46 | v0.12.0 47 | v0.13.0 48 | v0.14.0 49 | v0.15.0 50 | v0.16.0 51 | v0.17.0 52 | v0.18.0 53 | v0.19.0 54 | v0.20.0 55 | v0.21.0 56 | v0.22.0 57 | v0.23.0 58 | v0.24.0 59 | v0.25.0 60 | v0.26.0 61 | v0.27.0 62 | v0.28.0 63 | v0.28.1 64 | v0.29.0 65 | v0.30.0 66 | v0.31.0 67 | v0.32.0 68 | v0.33.0 69 | v0.34.0 70 | v0.35.0 71 | v0.36.0 72 | v0.37.0 73 | v0.37.1 74 | v0.38.0 75 | v0.39.0 76 | v0.40.0 77 | v0.41.0 78 | v0.42.0 79 | v1.0.0-rc1 80 | v1.0.0-rc2 81 | v1.0.0-rc3 -------------------------------------------------------------------------------- /test/test_install_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dvm_test_error() { 4 | echo "[ERR]" "$@" 5 | exit 1 6 | } 7 | 8 | # shellcheck disable=SC1091 9 | \. ./dvm.sh || dvm_test_error "failed to install dvm" 10 | 11 | # Install deno v2.2.0 12 | TARGET_VERSION="2.2.0" 13 | dvm install "v$TARGET_VERSION" --skip-validation --sha256sum || dvm_test_error "run 'dvm install v$TARGET_VERSION' failed" 14 | 15 | # Check installed version directory 16 | [ -d "$DVM_DIR/versions/v$TARGET_VERSION" ] || dvm_test_error "'$DVM_DIR/versions/v$TARGET_VERSION' is not a directory" 17 | 18 | # Install latest version 19 | dvm install --skip-validation 20 | 21 | # Install another deno 22 | dvm install v1.40.0 --skip-validation 23 | 24 | # Install deno by shortcut 25 | dvm i v1.45.0 --skip-validation 26 | 27 | # Check deno version 28 | dvm run "v$TARGET_VERSION" --version | grep "deno $TARGET_VERSION" || dvm_test_error "deno is invalid" 29 | 30 | # Set active version 31 | dvm use "v$TARGET_VERSION" || dvm_test_error "run 'dvm use v$TARGET_VERSION' failed" 32 | 33 | # Check with ls command 34 | dvm ls | grep "\-> v$TARGET_VERSION" || dvm_test_error "run 'dvm ls' failed" 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ~ 2025, Chen Su and all contributors. 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 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest, macos-latest, windows-latest] 11 | 12 | defaults: 13 | run: 14 | shell: bash 15 | 16 | env: 17 | GITHUB_API_TOKEN: ${{ secrets.TEST_API_TOKEN }} 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - name: Create dvm directory 23 | run: mkdir -p ~/.dvm 24 | 25 | - name: Read version caches 26 | id: read_version_caches 27 | uses: actions/cache@v4 28 | with: 29 | key: ${{ runner.os }}-version-caches 30 | path: ~/.dvm/cache 31 | 32 | - name: Run test cases 33 | run: | 34 | ./test/test_install_version.sh 35 | ./test/test_install_version_by_prefix.sh 36 | ./test/test_dvmrc_file.sh 37 | ./test/test_alias.sh 38 | ./test/test_uninstall_version.sh 39 | ./test/test_ls_remote.sh 40 | 41 | - name: Save version caches 42 | id: store_version_caches 43 | uses: actions/cache@v4 44 | with: 45 | key: ${{ runner.os }}-version-caches 46 | path: ~/.dvm/cache 47 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # DVM Installation Script (Deno Version Manager) 4 | # Copyright (C) 2020 ~ 2025, Chen Su and all contributors. 5 | 6 | ## Ensure the script is fully downloaded before running 7 | { 8 | 9 | dvm_add_into_profile_file() { 10 | local is_dvm_defined 11 | 12 | dvm_get_profile_file 13 | 14 | is_dvm_defined=$(grep DVM_DIR < "$DVM_PROFILE_FILE") 15 | 16 | if [ -n "$is_dvm_defined" ] 17 | then 18 | return 19 | fi 20 | 21 | echo " 22 | # Deno Version Manager 23 | export DVM_DIR=\"\$HOME/.dvm\" 24 | [ -f \"\$DVM_DIR/dvm.sh\" ] && . \"\$DVM_DIR/dvm.sh\" 25 | [ -f \"\$DVM_DIR/bash_completion\" ] && . \"\$DVM_DIR/bash_completion\" 26 | " >> "$DVM_PROFILE_FILE" 27 | } 28 | 29 | dvm_check_dir() { 30 | if [ ! -d "$DVM_DIR" ] 31 | then 32 | mkdir -p "$DVM_DIR" 33 | else 34 | echo "Directory $DVM_DIR already exists." 35 | exit 1 36 | fi 37 | } 38 | 39 | dvm_compare_version() { 40 | test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$2" 41 | } 42 | 43 | dvm_get_latest_version() { 44 | local request_url 45 | local response 46 | 47 | case "$DVM_SOURCE" in 48 | "gitee") 49 | request_url="https://gitee.com/api/v5/repos/ghosind/dvm/releases/latest" 50 | ;; 51 | "github"|*) 52 | request_url="https://api.github.com/repos/ghosind/dvm/releases/latest" 53 | ;; 54 | esac 55 | 56 | if ! dvm_has curl 57 | then 58 | echo "Error: curl is required." 59 | exit 1 60 | fi 61 | 62 | if ! response=$(curl -s "$request_url") 63 | then 64 | echo "Error: Failed to retrieve the latest DVM version." 65 | exit 1 66 | fi 67 | 68 | DVM_LATEST_VERSION=$(echo "$response" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 69 | } 70 | 71 | dvm_get_profile_file() { 72 | case "${SHELL##*/}" in 73 | "bash") 74 | DVM_PROFILE_FILE="$HOME/.bashrc" 75 | ;; 76 | "zsh") 77 | DVM_PROFILE_FILE="$HOME/.zshrc" 78 | ;; 79 | *) 80 | DVM_PROFILE_FILE="$HOME/.profile" 81 | ;; 82 | esac 83 | } 84 | 85 | dvm_has() { 86 | command -v "$1" > /dev/null 87 | } 88 | 89 | dvm_install() { 90 | dvm_check_dir 91 | 92 | DVM_SCRIPT_DIR=${0%/*} 93 | 94 | if [ -f "$DVM_SCRIPT_DIR/dvm.sh" ] && 95 | [ -d "$DVM_SCRIPT_DIR/.git" ] && 96 | [ -f "$DVM_SCRIPT_DIR/bash_completion" ] 97 | then 98 | # Copy all files to DVM_DIR 99 | cp -R "$DVM_SCRIPT_DIR/". "$DVM_DIR" 100 | else 101 | dvm_get_latest_version 102 | dvm_install_latest_version 103 | fi 104 | 105 | dvm_add_into_profile_file 106 | 107 | echo "DVM has been installed. Please restart your terminal or run \`source $DVM_PROFILE_FILE\` to apply the changes." 108 | } 109 | 110 | dvm_install_latest_version() { 111 | local git_url 112 | local cmd 113 | 114 | case "$DVM_SOURCE" in 115 | "gitee") 116 | git_url="https://gitee.com/ghosind/dvm.git" 117 | ;; 118 | "github"|*) 119 | git_url="https://github.com/ghosind/dvm.git" 120 | ;; 121 | esac 122 | 123 | if ! dvm_has git 124 | then 125 | echo "Error: git is required." 126 | exit 1 127 | fi 128 | 129 | cmd="git clone -b $DVM_LATEST_VERSION $git_url $DVM_DIR --depth=1" 130 | 131 | if ! ${cmd} 132 | then 133 | echo "Error: Failed to download DVM." 134 | exit 1 135 | fi 136 | } 137 | 138 | dvm_print_help() { 139 | echo "DVM Installation Script" 140 | echo 141 | echo "Usage: install.sh [-r ] [-d ]" 142 | echo 143 | echo "Options:" 144 | echo " -r Specify the repository server (default: github)." 145 | echo " -d Specify the DVM installation directory (default: ~/.dvm)." 146 | echo " -h Show this help message." 147 | echo 148 | echo "Example:" 149 | echo " install.sh -r github -d ~/.dvm" 150 | } 151 | 152 | dvm_set_default() { 153 | DVM_DIR=${DVM_DIR:-$HOME/.dvm} 154 | DVM_SOURCE=${DVM_SOURCE:-github} 155 | } 156 | 157 | dvm_set_default 158 | 159 | while getopts "hr:d:" opt 160 | do 161 | case "$opt" in 162 | "h") 163 | dvm_print_help 164 | exit 0 165 | ;; 166 | "r") 167 | if [ "$OPTARG" != "github" ] && [ "$OPTARG" != "gitee" ] 168 | then 169 | dvm_print_help 170 | exit 1 171 | fi 172 | DVM_SOURCE="$OPTARG" 173 | ;; 174 | "d") 175 | if [ -z "$OPTARG" ] 176 | then 177 | dvm_print_help 178 | exit 1 179 | fi 180 | 181 | DVM_DIR="$OPTARG" 182 | ;; 183 | *) 184 | ;; 185 | esac 186 | done 187 | 188 | if [ "$DVM_SOURCE" != "github" ] && [ "$DVM_SOURCE" != "gitee" ] 189 | then 190 | dvm_print_help 191 | exit 1 192 | fi 193 | 194 | dvm_install 195 | 196 | } 197 | -------------------------------------------------------------------------------- /bash_completion: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Bash completion for Deno Version Manager 4 | # Copyright (C) 2020 ~ 2025, Chen Su and all contributors. 5 | 6 | if ! type dvm &> /dev/null 7 | then 8 | return 9 | fi 10 | 11 | # Add available aliases to the auto-completion options list. 12 | _dvm_add_aliases_to_opts() { 13 | if [ ! -d "$DVM_DIR/aliases" ] 14 | then 15 | return 16 | fi 17 | 18 | if [ -z "$(ls -A "$DVM_DIR/aliases")" ] 19 | then 20 | return 0 21 | fi 22 | 23 | for path in "$DVM_DIR/aliases"/* 24 | do 25 | alias_name=${path##*/} 26 | version=$(cat "$path") 27 | 28 | if [ -f "$DVM_DIR/versions/$version/deno" ] 29 | then 30 | opts="$opts $alias_name" 31 | fi 32 | done 33 | } 34 | 35 | # Add commands and top-level options (--help and --version) to the options list. 36 | _dvm_add_command_and_top_option() { 37 | if [[ ${cur} == -* ]] 38 | then 39 | opts="-h --help --version" 40 | else 41 | opts="alias clean current deactivate doctor help install list list-remote 42 | ls ls-remote run upgrade unalias uninstall use which" 43 | fi 44 | } 45 | 46 | # Add the specified options to the options list if none have been input yet. 47 | _dvm_add_exclusive_option() { 48 | if _dvm_no_option_input "${@}" 49 | then 50 | opts="$opts $*" 51 | fi 52 | } 53 | 54 | # Add options for the install command. 55 | _dvm_add_install_option() { 56 | _dvm_add_exclusive_option "--from-binary" "--from-source" 57 | _dvm_add_options "--registry=" "--skip-validation" "--skip-download-cache" 58 | _dvm_add_options "--sha256sum" "--no-sha256sum" 59 | } 60 | 61 | # Add the specified options to the options list. 62 | _dvm_add_options() { 63 | for opt in "${@}" 64 | do 65 | if ! [[ ${COMP_WORDS[*]} =~ $opt ]] 66 | then 67 | opts="$opts $opt" 68 | fi 69 | done 70 | } 71 | 72 | # Add common options to the auto-completion options list. 73 | _dvm_add_options_to_opts() { 74 | local prev 75 | 76 | prev="$1" 77 | 78 | if [ "$prev" == "run" ] 79 | then 80 | return 81 | fi 82 | 83 | if [[ ${cur} != -* ]] 84 | then 85 | return 86 | fi 87 | 88 | _dvm_add_exclusive_option "-q" "--quiet" 89 | _dvm_add_exclusive_option "--color" "--no-color" 90 | _dvm_add_options "--verbose" 91 | } 92 | 93 | # Add available installed versions to the auto-completion options list. 94 | _dvm_add_versions_to_opts() { 95 | if [ ! -d "$DVM_DIR/versions" ] 96 | then 97 | return 98 | fi 99 | 100 | if [ -z "$(ls -A "$DVM_DIR/versions")" ] 101 | then 102 | return 0 103 | fi 104 | 105 | for path in "$DVM_DIR/versions"/* 106 | do 107 | if [ -f "$path/deno" ] 108 | then 109 | version=${path##*/} 110 | 111 | opts="$opts $version" 112 | fi 113 | done 114 | } 115 | 116 | # Set auto-completion for a specific command. 117 | _dvm_completion() { 118 | local command 119 | local cur 120 | 121 | COMPREPLY=() 122 | cur="${COMP_WORDS[COMP_CWORD]}" 123 | 124 | if [ "$COMP_CWORD" = "1" ] 125 | then 126 | _dvm_add_command_and_top_option 127 | else 128 | command="${COMP_WORDS[1]}" 129 | 130 | case "$command" in 131 | "doctor") 132 | _dvm_add_exclusive_option "--fix" 133 | ;; 134 | "install") 135 | if [[ ${cur} == -* ]] 136 | then 137 | _dvm_add_install_option 138 | fi 139 | ;; 140 | "use"|"uninstall"|"which") 141 | if ! _dvm_has_non_option_parameter "$cur" 142 | then 143 | if [ "$command" = "which" ] && _dvm_has_active_version 144 | then 145 | opts="current" 146 | fi 147 | 148 | _dvm_add_versions_to_opts 149 | _dvm_add_aliases_to_opts 150 | fi 151 | ;; 152 | "run") 153 | if _dvm_has_non_option_parameter "$cur" 154 | then 155 | COMPREPLY=( "$(compgen -W "${opts}" -- "${cur}")" ) 156 | return 157 | fi 158 | 159 | _dvm_add_versions_to_opts 160 | _dvm_add_aliases_to_opts 161 | ;; 162 | "unalias") 163 | if [ "$COMP_CWORD" == "2" ] || ! _dvm_has_non_option_parameter "$cur" 164 | then 165 | _dvm_add_aliases_to_opts 166 | fi 167 | ;; 168 | *) 169 | opts="" 170 | ;; 171 | esac 172 | 173 | _dvm_add_options_to_opts "$prev" 174 | fi 175 | 176 | COMPREPLY=( "$(compgen -W "${opts}" -- "${cur}")" ) 177 | } 178 | 179 | # Check if any Deno version installed by DVM is currently active. 180 | _dvm_has_active_version() { 181 | echo "$PATH" | grep -q "$DVM_DIR/versions" 182 | } 183 | 184 | # Check whether the parameter list contains any non-option parameters. 185 | _dvm_has_non_option_parameter() { 186 | local cur 187 | cur="$1" 188 | 189 | for word in "${COMP_WORDS[@]:2}" 190 | do 191 | if [ "$word" == "" ] || [ "$word" == "$cur" ] 192 | then 193 | continue 194 | fi 195 | 196 | if [[ "$word" != -* ]] 197 | then 198 | true 199 | return 200 | fi 201 | done 202 | 203 | false 204 | } 205 | 206 | # Check whether the specified options have been input. 207 | _dvm_no_option_input() { 208 | for opt in "${@}" 209 | do 210 | if [[ ${COMP_WORDS[*]} =~ $opt ]] 211 | then 212 | false 213 | return 214 | fi 215 | done 216 | 217 | true 218 | } 219 | 220 | if [ -n "$ZSH_NAME" ] 221 | then 222 | autoload -U +X compinit && compinit 223 | autoload -U +X bashcompinit && bashcompinit 224 | fi 225 | 226 | complete -F _dvm_completion dvm 227 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | [@ghosind](https://github.com/ghosind). 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /README-CN.md: -------------------------------------------------------------------------------- 1 | # DVM - Deno Version Manager 2 | 3 | ![test](https://github.com/ghosind/dvm/workflows/test/badge.svg) 4 | ![lint](https://github.com/ghosind/dvm/workflows/lint/badge.svg) 5 | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e11bedd87a194dd6a67140ec447ab51f)](https://www.codacy.com/manual/ghosind/dvm?utm_source=github.com&utm_medium=referral&utm_content=ghosind/dvm&utm_campaign=Badge_Grade) 6 | ![Version Badge](https://img.shields.io/github/v/release/ghosind/dvm) 7 | ![License Badge](https://img.shields.io/github/license/ghosind/dvm) 8 | 9 | 简体中文 | [English](./README.md) 10 | 11 | DVM是一个强大的轻量级[Deno](https://deno.land/)版本管理工具,可在MacOS、Linux、WSL以及装有Bash的Windows上使用。 12 | 13 | DVM仅在v0.7.0及之后的版本支持Windows。对于Windows用户,使用DVM前需要安装Bash Shell。例如,可以在安装WSL后在PowerShell中执行`bash`命令。 14 | 15 | ***在使用DVM管理你的多版本环境时,请避免使用`deno upgrade`命令进行升级deno版本。*** 16 | 17 | - [安装与升级](#安装与升级) 18 | - [安装DVM](#安装DVM) 19 | - [升级DVM](#升级DVM) 20 | - [依赖需求](#依赖需求) 21 | - [DVM入门](#DVM入门) 22 | - [列出可安装版本](#列出可安装版本) 23 | - [列出已安装的版本](#列出已安装的版本) 24 | - [安装版本](#安装版本) 25 | - [删除版本](#删除版本) 26 | - [切换版本](#切换版本) 27 | - [当前版本信息](#当前版本信息) 28 | - [设置别名](#设置别名) 29 | - [运行指定版本](#运行指定版本) 30 | - [DVM命令](#DVM命令) 31 | - [如何卸载DVM](#如何卸载DVM) 32 | - [使用`purge`命令](#使用purge命令) 33 | - [手工卸载](#手工卸载) 34 | - [许可](#许可) 35 | 36 | ## 安装与升级 37 | 38 | ### 安装DVM 39 | 40 | 我们提供了以下两种方式以安装DVM: 41 | 42 | 1. 运行下列命令从网络安装DVM: 43 | 44 | ```sh 45 | curl -o- https://raw.githubusercontent.com/ghosind/dvm/master/install.sh | bash 46 | ``` 47 | 48 | 对于国内的用户,可使用DVM的Gitee镜像以提高下载速度: 49 | 50 | ```sh 51 | curl -o- https://gitee.com/ghosind/dvm/raw/master/install.sh | DVM_SOURCE=gitee bash 52 | ``` 53 | 54 | 2. Clone远程git仓库至本地,并运行`install.sh`脚本: 55 | 56 | ```sh 57 | git clone "https://github.com/ghosind/dvm.git" 58 | # 同样,可以从我们的gitee项目上clone 59 | # git clone "https://gitee.com/ghosind/dvm.git" 60 | cd dvm 61 | ./install.sh 62 | ``` 63 | 64 | 在完成DVM的安装后,请重启终端或运行`source `以应用更改,安装程序将会提醒具体的操作步骤。 65 | 66 | 默认情况下,DVM将安装在`~/.dvm`目录下,可使用`-d `参数(仅限于本地安装使用)或`$DVM_DIR`环境变量指定一个不存在的目录作为DVM的安装目录。 67 | 68 | ```sh 69 | curl -o- "https://raw.githubusercontent.com/ghosind/dvm/master/install.sh" | DVM_DIR=~/deno/dvm bash 70 | ./install.sh -d ~/deno/dvm 71 | ``` 72 | 73 | ### 升级DVM 74 | 75 | 若您使用DVM `v0.3.0`及以上版本,可通过DVM本身提供的`upgrade`命令将本地DVM升级至最新的稳定版本。 76 | 77 | ```sh 78 | dvm upgrade 79 | ``` 80 | 81 | 若您使用DVM `v0.3.0`以下的版本时,需要卸载现有版本并重新安装的方法进行升级。您可通过[手工卸载](#手工卸载)章节提供的卸载方式卸载DVM,再重新进行安装。 82 | 83 | ## 依赖需求 84 | 85 | 请确保下列依赖软件已经安装: 86 | 87 | - curl 88 | - git 89 | - unzip (Deno v0.36.0及更新的版本) 90 | - gunzip (Deno v0.35.0及更旧的版本) 91 | 92 | 若需要从源码安装Deno,请确保以下依赖软件已经安装: 93 | 94 | - rustc 95 | - cargo 96 | - cc 97 | - cmake 98 | 99 | ## DVM入门 100 | 101 | ### 列出已安装的版本 102 | 103 | 使用`dvm ls`命令列出所有已安装的版本(及别名): 104 | 105 | ```sh 106 | # 列除所有当前已安装的版本 107 | dvm ls 108 | ``` 109 | 110 | ### 列出可安装版本 111 | 112 | 使用`dvm ls-remote`脚本列出所有可安装的版本: 113 | 114 | ```sh 115 | # 列出所有可安装的版本 116 | dvm ls-remote 117 | ``` 118 | 119 | ### 安装版本 120 | 121 | 使用`dvm install `下载并安装指定版本: 122 | 123 | ```sh 124 | dvm install v1.0.0 125 | dvn install v0.42.0 126 | ``` 127 | 128 | ### 源码安装 129 | 130 | DVM v0.8.0及以上版本支持从源码安装Deno: 131 | 132 | ```sh 133 | dvm install --from-source v1.35.0 134 | ``` 135 | 136 | ### 删除版本 137 | 138 | 使用`dvm uninstall `卸载指定版本: 139 | 140 | ``` 141 | dvm uninstall v0.39.0 142 | dvm uninstall v1.0.0-rc 143 | ``` 144 | 145 | ### 切换版本 146 | 147 | 使用`dvm use [version]`命令将指定的版本设置为当前使用的版本,若未指定则将从当前目录下的`.dvmrc`文件中读取: 148 | 149 | ```sh 150 | # 使用Deno v1.0.0 151 | dvm use v1.0.0 152 | 153 | # 使用通过.dvmrc文件指定的版本 154 | # cat .dvmrc 155 | # # v1.0.0 156 | dvm use 157 | ``` 158 | 159 | 通过`use`命令设置的版本仅适用于当前终端会话中,若希望为所有的终端会话设置使用的版本,请为版本设置`default`别名,可参考[设置别名](#设置别名)章节为指定版本设置别名。 160 | 161 | ### 当前版本信息 162 | 163 | 使用`dvm current`命令输出当前使用的Deno版本信息: 164 | 165 | ```sh 166 | dvm current 167 | # v1.0.0 168 | ``` 169 | 170 | ### 设置别名 171 | 172 | 使用`dvm alias`命令可为已安装的版本设置别名: 173 | 174 | ```sh 175 | dvm alias default v1.0.0 176 | ``` 177 | 178 | ### 运行指定版本 179 | 180 | 通过`dvm run`命令运行指定版本Deno,在有参数指定的情况下通过对应的参数执行对应的脚本: 181 | 182 | ```sh 183 | # 使用Deno v1.0.0运行app.ts 184 | dvm run v1.0.0 app.ts 185 | ``` 186 | 187 | ## DVM命令 188 | 189 | DVM支持的命令包括有: 190 | 191 | | 命令 | 使用方法 | 描述 | 192 | |:-------:|:-----:|:------------| 193 | | `install` | `dvm install` | 下载并安装从`.dvmrc`读取的指定版本或最新deno版本 | 194 | | | `dvm install ` | 下载并安装指定的版本,或安装满足指定前缀的最新版本 | 195 | | | `dvm install --registry=` | 通过指定的镜像下载deno | 196 | | | `dvm install --skip-validation` | 下载deno前不对版本进行校验 | 197 | | | `dvm install --from-source` | 编译源码并安装Deno | 198 | | | `dvm install --skip-download-cache` | 不使用已下载的文件,重新下载并安装 | 199 | | | `dvm install --sha256sum` | 下载安装Deno,并进行sha256校验 | 200 | | `uninstall` | `dvm uninstall ` | 卸载指定的版本 | 201 | | `use` | `dvm use` | 将指定的版本设置为当前使用的版本,未指定版本将从当前目录下的`.dvmrc`文件中读取 | 202 | | | `dvm use ` | 将指定的版本设置为当前使用的版本 | 203 | | | `dvm use ` | 将指定的别名对应的版本设置为当前使用的版本 | 204 | | `run` | `dvm run [args]` | 运行指定版本Deno,并传递对应的参数 | 205 | | `alias` | `dvm alias ` | 为指定版本设置别名 | 206 | | `unalias` | `dvm unalias ` | 删除指定的别名 | 207 | | `current` | `dvm current` | 显示当前使用的Deno版本 | 208 | | `ls` | `dvm ls` | 显示所有当前已安装的版本及别名 | 209 | | `list` | `dvm list` | 与`ls`相同 | 210 | | `ls-remote` | `dvm ls-remote` | 显示所有可安装的版本 | 211 | | `list-remote` | `dvm list-remote` | 与`ls-remote`相同 | 212 | | `which` | `dvm which` | 显示指定版本Deno安装的目录,未指定版本将从当前目录下的`.dvmrc`文件中读取 | 213 | | | `dvm which current` | 显示当前使用的版本Deno安装的目录 | 214 | | | `dvm which ` | 显示指定版本Deno安装的目录 | 215 | | `clean` | `dvm clean` | 清除下载及版本信息缓存 | 216 | | `deactivate` | `dvm deactivate` | 取消当前shell中活跃的Deno | 217 | | `doctor` | `dvm doctor` | 列出存在问题的版本(未安装成功/版本号错误) | 218 | | | `dvm doctor --fix` | 扫描并修复存在问题的版本 | 219 | | `upgrade` | `dvm upgrade` | 更新DVM | 220 | | `purge` | `dvm purge` | 卸载DVM | 221 | | `help` | `dvm help` | 打印帮助信息 | 222 | 223 | 更多信息请参考[dvm wiki](https://github.com/ghosind/dvm/wiki)。 224 | 225 | ### 可选参数 226 | 227 | | 参数 | 描述 | 228 | |:------:|:------------| 229 | | `-q`, `--quiet` | 安静模式,大大减少输出的数量,只保留了少数必要的输出 | 230 | | `--color` | 以色彩模式运行,输出的文本不再单调 | 231 | | `--no-color` | 以默认颜色输出 | 232 | | `--verbose` | 打印debug信息 | 233 | 234 | ## 如何卸载DVM 235 | 236 | ### 使用`purge`命令 237 | 238 | DVM `v0.3.2`及以上版本提供了`purge`命令,该命令可被用于卸载DVM本身,它将移除DVM所在的目录以及Shell环境配置文件中的相关内容。若您的DVM版本低于`v0.3.2`,请通过下面手工卸载的方法卸载。 239 | 240 | ### 手工卸载 241 | 242 | DVM所有的文件都保存在`$DVM_DIR`变量指定的目录下,若需要卸载DVM,只需删除`$DVM_DIR`指定的目录即可。 243 | 244 | ```sh 245 | rm -rf "$DVM_DIR" 246 | ``` 247 | 248 | 除文件目录外,DVM将配置信息写入了Shell环境配置文件中(如`.bashrc`或`.zshrc`,根据具体使用的Shell种类决定),您可编辑对应的文件删除下列几行代码: 249 | 250 | ```sh 251 | # Deno Version Manager 252 | export DVM_DIR="$HOME/.dvm" 253 | [ -f "$DVM_DIR/dvm.sh" ] && . "$DVM_DIR/dvm.sh" 254 | [ -f "$DVM_DIR/bash_completion" ] && . "$DVM_DIR/bash_completion" 255 | ``` 256 | 257 | ## 许可 258 | 259 | 本项目通过MIT许可发布,查看LICENSE文件获取更多信息。 260 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DVM - Deno Version Manager 2 | 3 | ![test](https://github.com/ghosind/dvm/workflows/test/badge.svg) 4 | ![lint](https://github.com/ghosind/dvm/workflows/lint/badge.svg) 5 | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e11bedd87a194dd6a67140ec447ab51f)](https://www.codacy.com/manual/ghosind/dvm?utm_source=github.com&utm_medium=referral&utm_content=ghosind/dvm&utm_campaign=Badge_Grade) 6 | ![Version Badge](https://img.shields.io/github/v/release/ghosind/dvm) 7 | ![License Badge](https://img.shields.io/github/license/ghosind/dvm) 8 | 9 | English | [简体中文](./README-CN.md) 10 | 11 | DVM is a lightweight and powerful [Deno](https://deno.land/) version manager for macOS, Linux, WSL, and Windows with Bash. 12 | 13 | **Note for Windows users:** You must install DVM v0.7.0 or later, and you also need a Bash shell to use this tool. For example, you can install WSL and run the `bash` command in PowerShell. 14 | 15 | > [!Warning] 16 | > Do not use the `deno upgrade` command to upgrade Deno after you have installed Deno with DVM. 17 | 18 | - [Installing and Updating](#installing-and-updating) 19 | - [Installation](#installation) 20 | - [Upgrade DVM](#upgrade-dvm) 21 | - [Prerequirement](#prerequirement) 22 | - [Getting Started](#getting-started) 23 | - [List available versions](#list-available-versions) 24 | - [List installed versions](#list-installed-versions) 25 | - [Install Deno](#install-deno) 26 | - [Uninstall Deno](#uninstall-deno) 27 | - [Set active version](#set-active-version) 28 | - [Get current version](#get-current-version) 29 | - [Set an alias](#set-an-alias) 30 | - [Run with a version](#run-with-a-version) 31 | - [Commands](#commands) 32 | - [Uninstalling DVM](#uninstalling-dvm) 33 | - [Use `purge` command](#use-purge-command) 34 | - [Manual uninstall](#manual-uninstall) 35 | - [License](#license) 36 | 37 | ## Installing and Updating 38 | 39 | ### Installation 40 | 41 | There are two ways to install DVM. 42 | 43 | 1. Install DVM from the network using the following command: 44 | 45 | ```sh 46 | curl -o- "https://raw.githubusercontent.com/ghosind/dvm/master/install.sh" | bash 47 | ``` 48 | 49 | For users in China, you can install DVM from Gitee using the following command: 50 | 51 | ```sh 52 | curl -o- "https://gitee.com/ghosind/dvm/raw/master/install.sh" | DVM_SOURCE=gitee bash 53 | ``` 54 | 55 | 2. Clone this project and execute the `install.sh` script: 56 | 57 | ```sh 58 | git clone "https://github.com/ghosind/dvm.git" 59 | # you can also clone it from gitee 60 | # git clone "https://gitee.com/ghosind/dvm.git" 61 | cd dvm 62 | ./install.sh 63 | ``` 64 | 65 | After installing DVM, restart your terminal or run `source ` to apply the changes. 66 | 67 | The default installation location is `~/.dvm`. You can use the `-d ` option (for local installs only) or the `$DVM_DIR` environment variable to specify a different directory. 68 | 69 | ```sh 70 | curl -o- "https://raw.githubusercontent.com/ghosind/dvm/master/install.sh" | DVM_DIR=~/deno/dvm bash 71 | ./install.sh -d ~/deno/dvm 72 | ``` 73 | 74 | ### Upgrade DVM 75 | 76 | Since DVM `v0.3.0`, the `upgrade` command is available to update DVM to the latest version. 77 | 78 | ```sh 79 | dvm upgrade 80 | ``` 81 | 82 | If you are using a DVM version older than `v0.3.0`, you may need to uninstall the current version and reinstall the latest one. See the [Manual uninstall](#manual-uninstall) section for instructions. 83 | 84 | ## Prerequisites 85 | 86 | Please ensure you have the following dependencies installed: 87 | 88 | - curl 89 | - git 90 | - unzip (for Deno v0.36.0 and newer versions) 91 | - gunzip (for Deno v0.35.0 and lower versions) 92 | 93 | To install Deno from source, you will also need: 94 | 95 | - rustc 96 | - cargo 97 | - cc 98 | - cmake 99 | 100 | ## Getting Started 101 | 102 | After installing DVM, you can use it to manage multiple Deno versions and environments. 103 | 104 | ### List available versions 105 | 106 | Use `dvm list-remote` or `dvm ls-remote` to list all available Deno versions from the remote server. 107 | 108 | ```sh 109 | # list all available versions 110 | dvm list-remote 111 | # ls-remote is an alias for list-remote command 112 | dvm ls-remote 113 | ``` 114 | 115 | ### List installed versions 116 | 117 | Use `dvm list` or `dvm ls` to list all installed Deno versions. 118 | 119 | ```sh 120 | # list all installed versions 121 | dvm list 122 | # ls command is an alias for list command 123 | dvm ls 124 | ``` 125 | 126 | ### Install Deno 127 | 128 | Use the `dvm install ` command to download and install a specific Deno version. 129 | 130 | ```sh 131 | dvm install v1.0.0 132 | # Deno v1.0.0 has been installed. 133 | # Using Deno v1.0.0 now. 134 | dvm install v0.42.0 135 | # Deno v0.42.0 has been installed. 136 | # Using Deno v1.0.0 now. 137 | ``` 138 | 139 | ### Install Deno from source 140 | 141 | Since DVM v0.8.0, you can install Deno from source using the `--from-source` option. 142 | 143 | ```sh 144 | dvm install --from-source v1.35.0 145 | ``` 146 | 147 | ### Uninstall Deno 148 | 149 | Use the `dvm uninstall ` command to uninstall a specific version or alias. 150 | 151 | ```sh 152 | dvm uninstall v0.39.0 153 | # Uninstalled Deno v0.39.0. 154 | # default is an alias name 155 | dvm uninstall default 156 | # Uninstalled Deno default. 157 | ``` 158 | 159 | ### Set active version 160 | 161 | Use the `dvm use [version]` command to link `deno` to the specified installed version, either by parameter or from a `.dvmrc` file. 162 | 163 | ```sh 164 | # Use v1.0.0 165 | dvm use v1.0.0 166 | # Using Deno v1.0.0 now. 167 | ``` 168 | 169 | If you do not specify a version, DVM will try to read the `.dvmrc` file from the current working directory. 170 | 171 | ```sh 172 | # cat .dvmrc 173 | # # v1.4.0 174 | dvm use 175 | # Found './dvmrc' with version v1.4.0 176 | # Using Deno v1.4.0 now. 177 | ``` 178 | 179 | Setting the active version with the `use` command only affects the current terminal session. To set a default version for all terminal sessions, create a `default` alias. See the [Set an alias](#set-active-version) section for more details. 180 | 181 | ### Get current version 182 | 183 | Use the `dvm current` command to display the currently active Deno version. 184 | 185 | ```sh 186 | dvm current 187 | # v1.0.0 188 | ``` 189 | 190 | ### Set an alias 191 | 192 | Use the `dvm alias` command to set an alias for an installed Deno version. 193 | 194 | ```sh 195 | dvm ls 196 | # v1.0.0 197 | # Set the default alias 198 | dvm alias default v1.0.0 199 | # default -> v1.0.0 200 | dvm ls 201 | # v1.0.0 202 | # default -> v1.0.0 203 | ``` 204 | 205 | ### Run with a version 206 | 207 | Use the `dvm run` command to run Deno with the specified version and arguments. 208 | 209 | ```sh 210 | dvm run v1.0.0 211 | # Running with deno v1.0.0 212 | # Deno 1.0.0 213 | # exit using ctrl+d or close() 214 | # > 215 | ``` 216 | 217 | You can also run a script file with the specified Deno version. 218 | 219 | ```sh 220 | # Run app.ts with Deno v1.0.0 221 | dvm run v1.0.0 app.ts 222 | ``` 223 | 224 | ## Commands 225 | 226 | DVM supports the following commands: 227 | 228 | | Command | Usage | Description | 229 | |:-------:|:-----:|:------------| 230 | | `install` | `dvm install` | Download and install the latest version or the version reading from `.dvmrc` file. | 231 | | | `dvm install ` | Download and install the specified version, or the latest version with the specified prefix. | 232 | | | `dvm install --registry=` | Download and install deno with the specified registry. | 233 | | | `dvm install --skip-validation` | Do not validate deno version before trying to download it. | 234 | | | `dvm install --from-source` | Build and install Deno from source code. | 235 | | | `dvm install --skip-download-cache` | Download and install Deno without using downloaded cache. | 236 | | | `dvm install --sha256sum` | Download and install Deno with sha256sum check. | 237 | | `uninstall` | `dvm uninstall ` | Uninstall the specified version. | 238 | | `use` | `dvm use` | Use the specified version read from .dvmrc. | 239 | | | `dvm use ` | Use the specified version that passed by argument. | 240 | | | `dvm use ` | Use the specified version of the alias name that passed by argument. | 241 | | `run` | `dvm run [args]` | Run deno on the specified version with arguments. | 242 | | `alias` | `dvm alias ` | Set an alias name to specified version. | 243 | | `unalias` | `dvm unalias ` | Delete the specified alias name. | 244 | | `current` | `dvm current` | Display the current version of Deno. | 245 | | `ls` | `dvm ls` | List all installed versions. | 246 | | `list` | `dvm list` | Same as `ls` command. | 247 | | `ls-remote` | `dvm ls-remote` | List all remote versions. | 248 | | `list-remote` | `dvm list-remote` | Same as `ls-remote` command. | 249 | | `which` | `dvm which` | Display the path of the version that specified in .dvmrc. | 250 | | | `dvm which current` | Display the path of the current version. | 251 | | | `dvm which ` | Display the path of specified version. | 252 | | `clean` | `dvm clean` | Remove all downloaded packages and the cached versions. | 253 | | `deactivate` | `dvm deactivate` | Deactivate Deno on current shell. | 254 | | `doctor` | `dvm doctor` | Find invalid / corrupted versions. | 255 | | | `dvm doctor --fix` | Find and fix invalid / corrupted versions. | 256 | | `upgrade` | `dvm upgrade` | Update dvm itself. | 257 | | `purge` | `dvm purge` | Remove dvm from your computer. | 258 | | `help` | `dvm help` | Show dvm help message. | 259 | 260 | For more details, please visit the [DVM Wiki](https://github.com/ghosind/dvm/wiki). 261 | 262 | ### Options 263 | 264 | | Option | Description | 265 | |:------:|:------------| 266 | | `-q`, `--quiet` | Run DVM with quiet mode, it'll hide most of the outputs. | 267 | | `--color` | Print messages with color mode. | 268 | | `--no-color` | Print messages with no color mode. | 269 | | `--verbose` | Print debug messages. | 270 | 271 | ## Uninstalling DVM 272 | 273 | You can remove DVM from your computer in two ways: 274 | 275 | ### Use `purge` command 276 | 277 | You can run `dvm purge` to remove DVM from your computer if your DVM version is `v0.3.2` or above. This will remove the `$DVM_DIR` and DVM configuration from your shell config file. 278 | 279 | If your DVM version is older than `v0.3.2`, please follow the next section ([Manual uninstall](#manual-uninstall)) to remove DVM. 280 | 281 | ### Manual uninstall 282 | 283 | Alternatively, you can run the following command to uninstall DVM: 284 | 285 | ```sh 286 | rm -rf "$DVM_DIR" 287 | ``` 288 | 289 | Edit your shell config file (such as `.bashrc` or `.zshrc`) and remove the following lines: 290 | 291 | ```sh 292 | # Deno Version Manager 293 | export DVM_DIR="$HOME/.dvm" 294 | [ -f "$DVM_DIR/dvm.sh" ] && . "$DVM_DIR/dvm.sh" 295 | [ -f "$DVM_DIR/bash_completion" ] && . "$DVM_DIR/bash_completion" 296 | ``` 297 | 298 | ## License 299 | 300 | Distributed under the MIT License. See the LICENSE file for more information. 301 | -------------------------------------------------------------------------------- /dvm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Deno Version Manager 4 | # Copyright (C) 2020 ~ 2025, Chen Su and all contributors. 5 | # A lightweight and powerful Deno version manager for macOS, Linux, WSL, and Windows with Bash. 6 | 7 | { # Ensure the integrality of this script 8 | 9 | export DVM_VERSION="v0.10.1" 10 | 11 | ###################### 12 | ## Helper Functions ## 13 | ###################### 14 | { 15 | ################# 16 | ## Environment ## 17 | ################# 18 | { 19 | # Check if the aliases directory exists, and create it if it does not. 20 | dvm_check_alias_dir() { 21 | if [ ! -d "$DVM_DIR/aliases" ] 22 | then 23 | mkdir -p "$DVM_DIR/aliases" 24 | fi 25 | } 26 | 27 | # Get the user profile file path based on the current shell. 28 | dvm_get_profile_file() { 29 | case "${SHELL##*/}" in 30 | "bash") 31 | DVM_PROFILE_FILE="$HOME/.bashrc" 32 | ;; 33 | "zsh") 34 | DVM_PROFILE_FILE="$HOME/.zshrc" 35 | ;; 36 | *) 37 | DVM_PROFILE_FILE="$HOME/.profile" 38 | ;; 39 | esac 40 | 41 | dvm_debug "profile file: $DVM_PROFILE_FILE" 42 | } 43 | 44 | # Check whether a command exists. 45 | # Parameters: 46 | # $1: The command to check. 47 | dvm_has() { 48 | command -v "$1" > /dev/null 49 | } 50 | 51 | # Set environment variables to their default values. 52 | dvm_set_default_env() { 53 | # set default dvm directory 54 | DVM_DIR=${DVM_DIR:-$HOME/.dvm} 55 | 56 | # Set modes 57 | DVM_COLOR_MODE=true 58 | DVM_QUIET_MODE=false 59 | DVM_VERBOSE_MODE=false 60 | 61 | # Set global variables to default values 62 | DVM_DENO_VERSION="" 63 | DVM_INSTALL_MODE="binary" 64 | DVM_INSTALL_REGISTRY="" 65 | DVM_INSTALL_SKIP_VALIDATION=false 66 | DVM_INSTALL_SKIP_CACHE=false 67 | DVM_INSTALL_SHA256SUM=false 68 | DVM_LATEST_VERSION="" 69 | DVM_PROFILE_FILE="" 70 | DVM_REMOTE_VERSIONS="" 71 | DVM_REQUEST_RESPONSE="" 72 | DVM_SOURCE="" 73 | DVM_TARGET_NAME="" 74 | DVM_TARGET_TYPE="" 75 | DVM_TARGET_VERSION="" 76 | } 77 | 78 | # Remove the Deno path added by DVM from the global PATH environment variable. 79 | dvm_strip_path() { 80 | echo "$PATH" | tr ":" "\n" | grep -v "$DVM_DIR" | tr "\n" ":" 81 | } 82 | } 83 | 84 | ####################### 85 | ## Handle Parameters ## 86 | ####################### 87 | { 88 | # Check all parameters and match available options. 89 | dvm_parse_options() { 90 | while [ "$#" -gt "0" ] 91 | do 92 | case "$1" in 93 | "-q"|"--quiet") 94 | DVM_QUIET_MODE=true 95 | ;; 96 | "--color") 97 | DVM_COLOR_MODE=true 98 | ;; 99 | "--no-color") 100 | DVM_COLOR_MODE=false 101 | ;; 102 | "--verbose") 103 | DVM_VERBOSE_MODE=true 104 | ;; 105 | *) 106 | ;; 107 | esac 108 | 109 | shift 110 | done 111 | } 112 | } 113 | 114 | ################ 115 | ## User Input ## 116 | ################ 117 | { 118 | # Print a prompt message and get confirmation (yes or no) from the user. 119 | # Parameters: 120 | # $1: The prompt message. 121 | dvm_confirm_with_prompt() { 122 | local confirm 123 | local prompt 124 | 125 | if [ "$#" = 0 ] 126 | then 127 | return 128 | fi 129 | 130 | prompt="$1" 131 | echo -n "$prompt (y/n): " 132 | 133 | while true 134 | do 135 | read -r confirm 136 | 137 | case "$confirm" in 138 | [yY]*) 139 | return 0 140 | ;; 141 | [nN]*) 142 | return 1 143 | ;; 144 | *) 145 | ;; 146 | esac 147 | 148 | echo -n "Please enter 'y' or 'n': " 149 | done 150 | } 151 | } 152 | 153 | ####################### 154 | ## Network Utilities ## 155 | ####################### 156 | { 157 | # Download a file from a specific URL and save it to the specified path. 158 | # Parameters: 159 | # - $1: The URL to download from. 160 | # - $2: The path to save the downloaded file. 161 | dvm_download_file() { 162 | local url 163 | local file 164 | local cmd 165 | local downloading_file 166 | 167 | url="$1" 168 | file="$2" 169 | downloading_file="$file.downloading" 170 | 171 | dvm_debug "downloading url: $url" 172 | dvm_debug "download destination file: $file" 173 | 174 | if dvm_has curl 175 | then 176 | cmd="curl -LJ $url -o $downloading_file" 177 | if [ "$DVM_QUIET_MODE" = true ] 178 | then 179 | cmd="$cmd -s" 180 | elif [ "$DVM_VERBOSE_MODE" = true ] 181 | then 182 | cmd="$cmd -v" 183 | fi 184 | else 185 | dvm_print_error "curl is required." 186 | dvm_failure 187 | return 188 | fi 189 | 190 | dvm_debug "download file command: $cmd" 191 | 192 | if ! eval "$cmd" 193 | then 194 | # remove failed download file 195 | rm -f "$downloading_file" 196 | dvm_failure 197 | return 198 | fi 199 | 200 | # rename the downloading file to the target file 201 | mv "$downloading_file" "$file" 202 | } 203 | 204 | # Send a GET request to a specific URL and save the response to the 205 | # `DVM_REQUEST_RESPONSE` variable. 206 | # Parameters: 207 | # - $1: The request URL. 208 | # - $2...: Additional options for curl. 209 | dvm_request() { 210 | local url 211 | 212 | # Clear response content. 213 | DVM_REQUEST_RESPONSE="" 214 | 215 | if ! dvm_has curl 216 | then 217 | dvm_print_error "curl is required" 218 | dvm_failure 219 | return 220 | fi 221 | 222 | url="$1" 223 | shift 224 | 225 | cmd="curl -s '$url' $*" 226 | 227 | if [ "$DVM_VERBOSE_MODE" = true ] 228 | then 229 | cmd="$cmd -v" 230 | fi 231 | 232 | if [ -n "$GITHUB_API_TOKEN" ] && [[ "$url" = "https://api.github.com/"* ]] 233 | then 234 | cmd="$cmd -H \"Authorization: Bearer $GITHUB_API_TOKEN\"" 235 | fi 236 | 237 | dvm_debug "request url: $url" 238 | dvm_debug "request command: $cmd" 239 | 240 | if ! DVM_REQUEST_RESPONSE=$(eval "$cmd") 241 | then 242 | dvm_failure 243 | return 244 | fi 245 | 246 | dvm_debug "request response: $DVM_REQUEST_RESPONSE" 247 | } 248 | } 249 | 250 | ############ 251 | ## Output ## 252 | ############ 253 | { 254 | # Print debug messages in verbose mode. 255 | # Parameters: 256 | # - $1...: The message(s) to print. 257 | dvm_debug() { 258 | if [ "$DVM_VERBOSE_MODE" = true ] 259 | then 260 | echo -e "[DEBUG]" "$@" 261 | fi 262 | } 263 | 264 | # Print messages unless in quiet mode. 265 | # Parameters: 266 | # - $1...: The message(s) to print. 267 | dvm_print() { 268 | if [ "$DVM_QUIET_MODE" = true ] 269 | then 270 | return 271 | fi 272 | 273 | echo -e "$@" 274 | } 275 | 276 | # Print error messages in red text. 277 | # Parameters: 278 | # - $1...: The error message(s) to print. 279 | dvm_print_error() { 280 | dvm_print_with_color "31" "[ERR]" "$@" 281 | } 282 | 283 | # Print warning messages in yellow text. 284 | # Parameters: 285 | # - $1...: The warning message(s) to print. 286 | dvm_print_warning() { 287 | dvm_print_with_color "33" "[WARN]" "$@" 288 | } 289 | 290 | # Print a message with a specific color. 291 | # Parameters: 292 | # - $1: The color code. 293 | # - $2...: The message(s) to print. 294 | dvm_print_with_color() { 295 | local color="$1" 296 | 297 | shift 298 | 299 | if [ "$DVM_COLOR_MODE" = true ] && [ -n "$color" ] 300 | then 301 | dvm_print "\x1b[${color}m$*\x1b[0m" 302 | else 303 | dvm_print "$@" 304 | fi 305 | } 306 | } 307 | 308 | ################### 309 | ## Return Status ## 310 | ################### 311 | { 312 | # Set return status to true. 313 | dvm_success() { 314 | # execute true to set as success 315 | true 316 | } 317 | 318 | # Set return status to false. 319 | dvm_failure() { 320 | # execute false to set as fail 321 | false 322 | } 323 | } 324 | 325 | #################### 326 | ## Version Handle ## 327 | #################### 328 | { 329 | # Compare two version number. 330 | # Parameters: 331 | # $1, $2: the version number to compare. 332 | dvm_compare_version() { 333 | test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$2" 334 | } 335 | 336 | # Try to getting the active Deno version, and set it to `DVM_DENO_VERSION` 337 | # variable. 338 | dvm_get_current_version() { 339 | local deno_path 340 | local deno_dir 341 | 342 | if ! deno_path=$(which deno 2>/dev/null) 343 | then 344 | return 345 | fi 346 | 347 | if [[ "$deno_path" != "$DVM_DIR/versions/"* ]] 348 | then 349 | return 350 | fi 351 | 352 | deno_dir=${deno_path%/deno} 353 | 354 | DVM_DENO_VERSION=${deno_dir##*/} 355 | 356 | dvm_debug "active deno version: $DVM_DENO_VERSION" 357 | } 358 | 359 | # Try to get a Deno version from the parameters or the .dvmrc file (the 360 | # current directory or the user home directory). 361 | # Parameters: 362 | # $1...: the Deno version. 363 | dvm_get_version() { 364 | local result 365 | local prefix 366 | 367 | if ! dvm_get_version_by_param "$@" 368 | then 369 | dvm_get_version_from_dvmrc 370 | fi 371 | 372 | if [ -z "$DVM_TARGET_VERSION" ] 373 | then 374 | return 375 | fi 376 | 377 | if [[ "$DVM_TARGET_VERSION" != "v"* ]] 378 | then 379 | DVM_TARGET_VERSION="v$DVM_TARGET_VERSION" 380 | fi 381 | 382 | result=$(echo "$DVM_TARGET_VERSION" | grep -E "^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+") 383 | if [ -n "$result" ] 384 | then 385 | return 386 | fi 387 | 388 | dvm_debug "$DVM_TARGET_VERSION is a prefix" 389 | dvm_debug "try to get the latest version with the prefix $DVM_TARGET_VERSION" 390 | 391 | prefix="$DVM_TARGET_VERSION"\. 392 | DVM_TARGET_VERSION="" 393 | 394 | for version in "$DVM_DIR/versions"/* 395 | do 396 | if [[ "$version" == *"$prefix"* ]] 397 | then 398 | result=${version##*/} 399 | dvm_debug "version $result matched to the prefix $DVM_TARGET_VERSION" 400 | fi 401 | done 402 | 403 | if [ -z "$result" ] 404 | then 405 | dvm_print_error "no version found with the prefix $DVM_TARGET_VERSION" 406 | dvm_failure 407 | else 408 | dvm_debug "found the latest version $result with the prefix $DVM_TARGET_VERSION" 409 | DVM_TARGET_VERSION="$result" 410 | fi 411 | } 412 | 413 | # Try to get a valid and installed Deno version from the parameters. 414 | # Parameters: 415 | # $1...: the Deno version. 416 | dvm_get_version_by_param() { 417 | DVM_TARGET_VERSION="" 418 | 419 | while [[ "$1" == "-"* ]] 420 | do 421 | shift 422 | done 423 | 424 | if [ "$#" = "0" ] 425 | then 426 | return 1 427 | fi 428 | 429 | dvm_debug "try to get version by param: $1" 430 | 431 | if [ -f "$DVM_DIR/aliases/$1" ] 432 | then 433 | DVM_TARGET_VERSION=$(head -n 1 "$DVM_DIR/aliases/$1") 434 | 435 | if [ ! -f "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" ] 436 | then 437 | DVM_TARGET_VERSION="$1" 438 | fi 439 | else 440 | DVM_TARGET_VERSION="$1" 441 | fi 442 | } 443 | 444 | # Try to read version from .dvmrc file in the current working directory or 445 | # the user home directory. 446 | dvm_get_version_from_dvmrc() { 447 | if dvm_read_dvmrc_file "$PWD" ".dvmrc" || dvm_read_dvmrc_file "$PWD" ".deno-version" 448 | then 449 | return 0 450 | fi 451 | 452 | if [ "$PWD" != "$HOME" ] 453 | then 454 | if dvm_read_dvmrc_file "$HOME" ".dvmrc" || dvm_read_dvmrc_file "$HOME" ".deno-version" 455 | then 456 | return 0 457 | fi 458 | fi 459 | 460 | return 1 461 | } 462 | 463 | # Read .dvmrc or .deno-version file from the specified path, and set it to 464 | # `DVM_TARGET_VERSION` variable if the file is not empty. 465 | # Parameters: 466 | # - $1: path directory 467 | # - $2: file name 468 | dvm_read_dvmrc_file() { 469 | local version 470 | local file_dir="$1" 471 | local filename="$2" 472 | local file="$file_dir/$filename" 473 | 474 | if [ -f "$file" ] 475 | then 476 | dvm_debug "$file found" 477 | version=$(head -n 1 "$file") 478 | else 479 | dvm_debug "no $filename found in $file_dir" 480 | return 1 481 | fi 482 | 483 | if [ -n "$version" ] 484 | then 485 | dvm_print "Found '$file' with version $version" 486 | DVM_TARGET_VERSION="$version" 487 | return 0 488 | else 489 | dvm_debug "empty $filename file $file_dir" 490 | return 1 491 | fi 492 | } 493 | } 494 | } 495 | 496 | ################### 497 | ## Command alias ## 498 | ################### 499 | { 500 | # Set an alias for a specific Deno version. If the alias already exists, it will be overwritten. 501 | # Parameters: 502 | # $1: The alias name to set. 503 | # $2: The Deno version to alias. 504 | dvm_set_alias() { 505 | local alias_name 506 | local version 507 | 508 | dvm_check_alias_dir 509 | 510 | while [ "$#" -gt "0" ] 511 | do 512 | case "$1" in 513 | "-"*) 514 | ;; 515 | *) 516 | if [ -z "$alias_name" ] 517 | then 518 | alias_name="$1" 519 | elif [ -z "$version" ] 520 | then 521 | version="$1" 522 | fi 523 | esac 524 | 525 | shift 526 | done 527 | 528 | if [ -z "$alias_name" ] || [ -z "$version" ] 529 | then 530 | dvm_print_help 531 | dvm_failure 532 | return 533 | fi 534 | 535 | if [ ! -f "$DVM_DIR/versions/$version/deno" ] 536 | then 537 | dvm_print_error "Deno $version is not installed." 538 | dvm_failure 539 | return 540 | fi 541 | 542 | echo "$version" > "$DVM_DIR/aliases/$alias_name" 543 | 544 | dvm_print "$alias_name -> $version" 545 | } 546 | } 547 | 548 | ################### 549 | ## Command clean ## 550 | ################### 551 | { 552 | # Remove version and download caches. 553 | dvm_clean_caches() { 554 | if [ -d "$DVM_DIR/cache" ] 555 | then 556 | rm -rf "$DVM_DIR/cache" 557 | fi 558 | 559 | dvm_clean_download_cache 560 | } 561 | 562 | # Remove download caches from disk. 563 | dvm_clean_download_cache() { 564 | if [ ! -d "$DVM_DIR/download" ] 565 | then 566 | return 567 | fi 568 | 569 | if [ -z "$(ls -A "$DVM_DIR/download")" ] 570 | then 571 | return 572 | fi 573 | 574 | for cache_path in "$DVM_DIR/download"/* 575 | do 576 | if [ ! -d "$cache_path" ] 577 | then 578 | continue 579 | fi 580 | 581 | rm -rf "$cache_path" 582 | done 583 | } 584 | } 585 | 586 | ##################### 587 | ## Command current ## 588 | ##################### 589 | { 590 | # Get and print the current Deno version. If Deno was not installed by DVM, prints 591 | # `system (vX.X.X)`. 592 | dvm_print_current_version() { 593 | local deno_version 594 | 595 | if ! dvm_has deno 596 | then 597 | dvm_print "none" 598 | return 599 | fi 600 | 601 | dvm_get_current_version 602 | 603 | if [ -n "$DVM_DENO_VERSION" ] 604 | then 605 | dvm_print "$DVM_DENO_VERSION" 606 | else 607 | deno_version=$(deno --version | grep "deno" | cut -d " " -f 2) 608 | dvm_print "system (v$deno_version)" 609 | fi 610 | } 611 | } 612 | 613 | ######################## 614 | ## Command deactivate ## 615 | ######################## 616 | { 617 | # Deactivate the active Deno version that was added to the global PATH by DVM. 618 | dvm_deactivate() { 619 | local path_without_dvm 620 | 621 | dvm_get_current_version 622 | 623 | if [ -z "$DVM_DENO_VERSION" ] 624 | then 625 | dvm_success 626 | return 627 | fi 628 | 629 | path_without_dvm=$(dvm_strip_path) 630 | export PATH="$path_without_dvm" 631 | 632 | dvm_print "Deno has been deactivated. You can run \"dvm use $DVM_DENO_VERSION\" to reactivate it." 633 | 634 | unset DVM_DENO_VERSION 635 | } 636 | } 637 | 638 | #################### 639 | ## Command doctor ## 640 | #################### 641 | { 642 | # Scan installed versions and try to find invalid versions (where the version in the path and 643 | # the Deno `-v` output do not match). Attempts to fix invalid versions if run in `fix` mode. 644 | # Parameters: 645 | # $1: The mode of the doctor command. 646 | dvm_scan_and_fix_versions() { 647 | local mode 648 | local raw_output 649 | local invalid_message 650 | local corrupted_message 651 | local version 652 | local deno_version 653 | 654 | mode="$1" 655 | 656 | if [ ! -d "$DVM_DIR/versions" ] 657 | then 658 | return 659 | fi 660 | 661 | if [ -z "$(ls -A "$DVM_DIR/versions")" ] 662 | then 663 | return 664 | fi 665 | 666 | for version_path in "$DVM_DIR/versions/"* 667 | do 668 | if [ ! -f "$version_path/deno" ] 669 | then 670 | continue 671 | fi 672 | 673 | version=${version_path##*/} 674 | 675 | raw_output=$("$version_path/deno" --version 2>/dev/null) 676 | 677 | if [ -z "$raw_output" ] 678 | then 679 | corrupted_message="$corrupted_message$version\n" 680 | 681 | if [ "$mode" = "fix" ] 682 | then 683 | rm -rf "$version_path" 684 | fi 685 | else 686 | deno_version=$(echo "$raw_output" | grep deno | cut -d " " -f 2) 687 | 688 | if [ "$version" != "v$deno_version" ] 689 | then 690 | invalid_message="$invalid_message$version -> v$deno_version\n" 691 | 692 | if [ "$mode" = "fix" ] 693 | then 694 | mkdir -p "$DVM_DIR/doctor_temp" 695 | mv -f "$version_path" "$DVM_DIR/doctor_temp/v$deno_version" 696 | fi 697 | fi 698 | fi 699 | done 700 | 701 | if [ "$mode" = "fix" ] 702 | then 703 | dvm_fix_invalid_versions 704 | else 705 | dvm_print_doctor_message "$invalid_message" "$corrupted_message" 706 | fi 707 | } 708 | 709 | # Move Deno files to the correct path, and remove them if the version already exists. 710 | dvm_fix_invalid_versions() { 711 | local version 712 | 713 | if [ ! -d "$DVM_DIR/doctor_temp" ] 714 | then 715 | return 716 | fi 717 | 718 | for version_path in "$DVM_DIR/doctor_temp/"* 719 | do 720 | version=${version_path##*/} 721 | 722 | if [ -d "$DVM_DIR/versions/$version" ] 723 | then 724 | rm -rf "$version_path" 725 | else 726 | mv "$version_path" "$DVM_DIR/versions/$version" 727 | fi 728 | done 729 | 730 | rmdir "$DVM_DIR/doctor_temp" 731 | 732 | dvm_print "Invalid version(s) have been fixed." 733 | } 734 | 735 | # Print invalid versions (where the version in the file and path do not match) and corrupted 736 | # versions (unable to run). 737 | # Parameters: 738 | # $1: List of invalid versions. 739 | # $2: List of corrupted versions. 740 | dvm_print_doctor_message() { 741 | local invalid_message 742 | local corrupted_message 743 | 744 | invalid_message="$1" 745 | corrupted_message="$2" 746 | 747 | if [ -z "$invalid_message" ] && [ -z "$corrupted_message" ] 748 | then 749 | dvm_print "All versions are valid." 750 | return 751 | fi 752 | 753 | if [ -n "$invalid_message" ] 754 | then 755 | dvm_print "Invalid versions:" 756 | dvm_print "$invalid_message" 757 | fi 758 | 759 | if [ -n "$corrupted_message" ] 760 | then 761 | dvm_print "Corrupted versions:" 762 | dvm_print "$corrupted_message" 763 | fi 764 | 765 | dvm_print "You can run \"dvm doctor --fix\" to attempt to fix these errors." 766 | } 767 | } 768 | 769 | ################## 770 | ## Command help ## 771 | ################## 772 | { 773 | # Print help messages. 774 | dvm_print_help() { 775 | dvm_print 776 | dvm_print "Deno Version Manager" 777 | dvm_print 778 | dvm_print "Usage:" 779 | dvm_print " dvm install [version | prefix] Download and install by version or the prefix. Install latest or use .dvmrc file if version is omitted." 780 | dvm_print " --registry= Download and install deno with the specified registry." 781 | dvm_print " --skip-validation Skip version validation before download." 782 | dvm_print " --skip-download-cache Don't use downloaded cache file." 783 | dvm_print " dvm uninstall [name|version] Uninstall a specified version." 784 | dvm_print " dvm use [name|version] Use the specified version that passed by argument or read from .dvmrc." 785 | dvm_print " dvm run [args] Run deno on the specified version with arguments." 786 | dvm_print " dvm alias Set an alias name to specified version." 787 | dvm_print " dvm unalias Delete the specified alias name." 788 | dvm_print " dvm current Display the current version of Deno." 789 | dvm_print " dvm ls List all installed versions." 790 | dvm_print " dvm ls-remote List all remote versions." 791 | dvm_print " dvm which [current|name|version] Display the path of installed version." 792 | dvm_print " dvm clean Remove all downloaded packages and cached versions." 793 | dvm_print " dvm deactivate Deactivate Deno on current shell." 794 | dvm_print " dvm doctor Scan installed versions and find invalid / corrupted versions." 795 | dvm_print " --fix Scan and fix all invalid / corrupted versions." 796 | dvm_print " dvm upgrade Upgrade dvm itself." 797 | dvm_print " dvm purge Remove dvm from your computer." 798 | dvm_print " dvm help Show this message." 799 | dvm_print 800 | dvm_print "Options:" 801 | dvm_print " -q, --quiet Make outputs more quiet." 802 | dvm_print " --color Print colorful messages." 803 | dvm_print " --no-color Print messages without color." 804 | dvm_print " --verbose Run in verbose mode, it'll print debug messages." 805 | dvm_print 806 | dvm_print "Note:" 807 | dvm_print " is required parameter, [param] is optional parameter." 808 | dvm_print 809 | dvm_print "Examples:" 810 | dvm_print " dvm install v1.0.0" 811 | dvm_print " dvm uninstall v0.42.0" 812 | dvm_print " dvm use v1.0.0" 813 | dvm_print " dvm alias default v1.0.0" 814 | dvm_print " dvm run v1.0.0 app.ts" 815 | dvm_print 816 | } 817 | } 818 | 819 | ##################### 820 | ## Command install ## 821 | ##################### 822 | { 823 | # Build the Deno binary for the specified version and move the build output to the versions 824 | # directory. 825 | # Parameters: 826 | # - $1: The Deno version to build. 827 | dvm_build_deno() { 828 | local version 829 | version="$1" 830 | 831 | old_dir=$(pwd) 832 | cd "$DVM_DIR/deno_code" || return 833 | 834 | git reset --hard HEAD 835 | if ! git checkout "$version" --recurse-submodules 836 | then 837 | dvm_failure 838 | return 839 | fi 840 | 841 | cargo clean 842 | 843 | if ! cargo build --release 844 | then 845 | dvm_print_error "failed to build deno" 846 | cd "$old_dir" || return 847 | dvm_failure 848 | return 849 | fi 850 | 851 | if ! dvm_validate_build_target "$version" 852 | then 853 | cd "$old_dir" || return 854 | dvm_failure 855 | return 856 | elif ! dvm_copy_build_target_to_versions_dir "$version" 857 | then 858 | cd "$old_dir" || return 859 | dvm_failure 860 | return 861 | else 862 | cargo clean 863 | cd "$old_dir" || return 864 | fi 865 | } 866 | 867 | # Check dependencies required for building Deno from source. 868 | dvm_check_build_dependencies() { 869 | for command in git rustc cargo cc cmake 870 | do 871 | if ! dvm_has "$command" 872 | then 873 | dvm_print_error "$command is required" 874 | dvm_failure 875 | return 876 | fi 877 | done 878 | } 879 | 880 | # Check the local clone of the Deno source code and fetch the latest data if valid. If the 881 | # directory is not a valid Deno repo, it will be deleted and re-cloned later. 882 | dvm_check_local_deno_clone() { 883 | local old_dir 884 | 885 | old_dir=$(pwd) 886 | cd "$DVM_DIR/deno_code" || return 887 | 888 | ret=$(git remote -v | grep "deno.git") 889 | if [ -z "$ret" ] 890 | then 891 | dvm_print_warning "The local clone of Deno source is invalid, trying to re-clone..." 892 | rm -rf "$DVM_DIR/deno_code" 893 | 894 | cd "$old_dir" || return 895 | dvm_failure 896 | else 897 | # update repo 898 | git fetch 899 | 900 | cd "$old_dir" || return 901 | fi 902 | } 903 | 904 | # Clone the source code of Deno into the local directory, and update the 905 | # local clone if it was cloned. 906 | dvm_clone_deno_source() { 907 | if [ -d "$DVM_DIR/deno_code" ] 908 | then 909 | if dvm_check_local_deno_clone 910 | then 911 | return 912 | fi 913 | fi 914 | 915 | git clone --recurse-submodules https://github.com/denoland/deno.git "$DVM_DIR/deno_code" 916 | } 917 | 918 | # Move the build output file to the versions directory. 919 | # Parameters: 920 | # - $1: The Deno version to install. 921 | dvm_copy_build_target_to_versions_dir() { 922 | local version 923 | 924 | version="$1" 925 | 926 | if ! [ -d "$DVM_DIR/versions/$version" ] 927 | then 928 | mkdir -p "$DVM_DIR/versions/$version" 929 | fi 930 | 931 | cp "$DVM_DIR/deno_code/target/release/deno" "$DVM_DIR/versions/$version" 932 | } 933 | 934 | # Download Deno for the specified version from GitHub or a custom registry (specified by 935 | # `DVM_INSTALL_REGISTRY`). 936 | # Downloads Deno to the cache directory, then moves it to the versions directory after 937 | # completion. 938 | # Parameters: 939 | # - $1: The Deno version to download. 940 | dvm_download_deno() { 941 | local version 942 | local url 943 | local temp_file 944 | local registry 945 | 946 | version="$1" 947 | 948 | if [ ! -d "$DVM_DIR/download/$version" ] 949 | then 950 | mkdir -p "$DVM_DIR/download/$version" 951 | fi 952 | 953 | if [ -z "$DVM_INSTALL_REGISTRY" ] 954 | then 955 | if ! [[ "$version" < "v1.0.1" ]] || [[ "$version" = "v1.0.0" ]] 956 | then 957 | registry="https://dl.deno.land/release" 958 | else 959 | registry="https://github.com/denoland/deno/releases/download" 960 | fi 961 | else 962 | registry="$DVM_INSTALL_REGISTRY" 963 | fi 964 | 965 | dvm_debug "registry url: $registry" 966 | 967 | url="$registry/$version/$DVM_TARGET_NAME" 968 | temp_file="$DVM_DIR/download/$version/$DVM_TARGET_NAME" 969 | 970 | if dvm_download_file "$url" "$temp_file" 971 | then 972 | if dvm_validate_download_file "$version" "$url" 973 | then 974 | return 975 | fi 976 | fi 977 | 978 | if [ -f "$temp_file" ] 979 | then 980 | rm "$temp_file" 981 | fi 982 | 983 | dvm_print_error "Failed to download Deno $version." 984 | dvm_failure 985 | } 986 | 987 | # Extract the Deno compressed file and add execute permission to the binary. 988 | dvm_extract_file() { 989 | local target_dir 990 | 991 | target_dir="$DVM_DIR/versions/$1" 992 | 993 | dvm_debug "extracting source file: $DVM_DIR/download/$1/deno.$DVM_TARGET_TYPE" 994 | dvm_debug "extracting target path: $target_dir" 995 | 996 | if [ ! -d "$target_dir" ] 997 | then 998 | mkdir -p "$target_dir" 999 | fi 1000 | 1001 | case $DVM_TARGET_TYPE in 1002 | "zip") 1003 | if dvm_has unzip 1004 | then 1005 | unzip "$DVM_DIR/download/$1/deno.zip" -d "$target_dir" > /dev/null 1006 | elif [ "$DVM_TARGET_OS" = "Linux" ] && dvm_has gunzip 1007 | then 1008 | gunzip -c "$DVM_DIR/download/$1/deno.zip" > "$target_dir/deno" 1009 | chmod +x "$target_dir/deno" 1010 | else 1011 | dvm_print_error "unzip is required." 1012 | dvm_failure 1013 | fi 1014 | ;; 1015 | "gz") 1016 | if dvm_has gunzip 1017 | then 1018 | gunzip -c "$DVM_DIR/download/$1/deno.gz" > "$target_dir/deno" 1019 | chmod +x "$target_dir/deno" 1020 | else 1021 | dvm_print_error "gunzip is required." 1022 | dvm_failure 1023 | fi 1024 | ;; 1025 | *) 1026 | ;; 1027 | esac 1028 | } 1029 | 1030 | # Call the GitHub API to get the latest Deno release tag name. 1031 | dvm_get_latest_version() { 1032 | # the url of github api 1033 | local latest_url 1034 | # the latest release tag name 1035 | local tag_name 1036 | 1037 | dvm_print "\nTrying to get the latest Deno version ..." 1038 | 1039 | latest_url="https://dl.deno.land/release-latest.txt" 1040 | 1041 | if ! dvm_request "$latest_url" 1042 | then 1043 | dvm_print_error "Failed to get the latest Deno version." 1044 | dvm_failure 1045 | return 1046 | fi 1047 | 1048 | tag_name="$DVM_REQUEST_RESPONSE" 1049 | 1050 | if [ -z "$tag_name" ] 1051 | then 1052 | dvm_print_error "Failed to get the latest Deno version." 1053 | dvm_failure 1054 | return 1055 | fi 1056 | 1057 | dvm_print "Found latest Deno version: $tag_name" 1058 | 1059 | DVM_TARGET_VERSION="$tag_name" 1060 | DVM_INSTALL_SKIP_VALIDATION=true 1061 | } 1062 | 1063 | # Get the remote package name based on host OS and architecture. 1064 | # Parameters: 1065 | # - $1: The Deno version to install. 1066 | dvm_get_package_data() { 1067 | local target_version 1068 | 1069 | DVM_TARGET_OS=$(uname -s) 1070 | DVM_TARGET_ARCH=$(uname -m) 1071 | target_version="$1" 1072 | 1073 | dvm_debug "target os: $DVM_TARGET_OS" 1074 | dvm_debug "target arch: $DVM_TARGET_ARCH" 1075 | dvm_debug "target deno version: $target_version" 1076 | 1077 | if [ "$DVM_TARGET_OS" = "Darwin" ] && 1078 | [ "$DVM_TARGET_ARCH" = 'arm64' ] && 1079 | dvm_compare_version "$target_version" "v1.6.0" 1080 | then 1081 | dvm_print_error "Macs with M-series chips (aarch64-darwin) support Deno v1.6.0 and above only." 1082 | dvm_failure 1083 | return 1084 | fi 1085 | 1086 | if [ "$DVM_TARGET_OS" = "Linux" ] && 1087 | [ "$DVM_TARGET_ARCH" = 'arm64' ] && 1088 | dvm_compare_version "$target_version" "v1.40.3" 1089 | then 1090 | dvm_print_error "Linux with ARM64 chips (aarch64-linux) support Deno v1.40.3 and above only." 1091 | dvm_failure 1092 | return 1093 | fi 1094 | 1095 | if dvm_compare_version "$target_version" "v0.36.0" 1096 | then 1097 | DVM_TARGET_TYPE="gz" 1098 | else 1099 | DVM_TARGET_TYPE="zip" 1100 | fi 1101 | 1102 | dvm_debug "target file type: $DVM_TARGET_TYPE" 1103 | 1104 | case "$DVM_TARGET_OS:$DVM_TARGET_ARCH:$DVM_TARGET_TYPE" in 1105 | "Darwin:x86_64:gz") 1106 | DVM_TARGET_NAME='deno_osx_x64.gz' 1107 | ;; 1108 | "Linux:x86_64:gz") 1109 | DVM_TARGET_NAME='deno_linux_x64.gz' 1110 | ;; 1111 | "Darwin:x86_64:zip") 1112 | DVM_TARGET_NAME='deno-x86_64-apple-darwin.zip' 1113 | ;; 1114 | "Darwin:arm64:zip") 1115 | DVM_TARGET_NAME='deno-aarch64-apple-darwin.zip' 1116 | ;; 1117 | "Linux:x86_64:zip") 1118 | DVM_TARGET_NAME='deno-x86_64-unknown-linux-gnu.zip' 1119 | ;; 1120 | "Linux:aarch64:zip") 1121 | DVM_TARGET_NAME='deno-aarch64-unknown-linux-gnu.zip' 1122 | ;; 1123 | *"NT"*":x86_64:zip") 1124 | DVM_TARGET_NAME='deno-x86_64-pc-windows-msvc.zip' 1125 | ;; 1126 | *) 1127 | dvm_print_error "Unsupported operating system: $DVM_TARGET_OS ($DVM_TARGET_ARCH)." 1128 | dvm_failure 1129 | return 1130 | ;; 1131 | esac 1132 | 1133 | dvm_debug "target file name: $DVM_TARGET_NAME" 1134 | } 1135 | 1136 | # Gets the latest version with the prefix. 1137 | # Parameters: 1138 | # - $1: the version prefix to search. 1139 | dvm_get_remote_version_by_prefix() { 1140 | local search_text 1141 | local version_prefix 1142 | local tmp_versions 1143 | 1144 | search_text="$1" 1145 | version_prefix="$search_text" 1146 | 1147 | dvm_debug "searching version starts with $version_prefix" 1148 | 1149 | if [[ "$version_prefix" == *"." ]] 1150 | then 1151 | version_prefix="${version_prefix%%.}" 1152 | fi 1153 | version_prefix="$version_prefix\." 1154 | 1155 | dvm_debug "searching version prefix: $version_prefix" 1156 | 1157 | if ! dvm_get_remote_versions 1158 | then 1159 | dvm_failure 1160 | return 1161 | fi 1162 | 1163 | tmp_versions=$(echo "$DVM_REMOTE_VERSIONS" | grep -E "$version_prefix" | tail -n 1) 1164 | if [ -z "$tmp_versions" ] 1165 | then 1166 | dvm_print_error "no version found by $search_text" 1167 | dvm_failure 1168 | return 1169 | fi 1170 | 1171 | dvm_debug "matched version found $tmp_versions" 1172 | DVM_TARGET_VERSION="$tmp_versions" 1173 | DVM_INSTALL_SKIP_VALIDATION=true 1174 | } 1175 | 1176 | # Install Deno for the specified version. Tries to get the version from the 1177 | # parameter, .dvmrc file (current directory or home directory), or the 1178 | # latest Deno version. 1179 | # Parameters: 1180 | # - $1: The Deno version to install. (Optional) 1181 | dvm_install_version() { 1182 | local version 1183 | 1184 | version="$1" 1185 | 1186 | if [ -z "$version" ] 1187 | then 1188 | if ! dvm_get_version_from_dvmrc && ! dvm_get_latest_version 1189 | then 1190 | return 1191 | fi 1192 | else 1193 | if ! dvm_is_version_prefix "$version" 1194 | then 1195 | return 1196 | fi 1197 | fi 1198 | version="$DVM_TARGET_VERSION" 1199 | 1200 | if [ -f "$DVM_DIR/versions/$version/deno" ] 1201 | then 1202 | dvm_print "Deno $version is already installed." 1203 | dvm_success 1204 | return 1205 | fi 1206 | 1207 | if [ "$DVM_INSTALL_SKIP_VALIDATION" = false ] 1208 | then 1209 | if ! dvm_validate_remote_version "$version" 1210 | then 1211 | return 1212 | fi 1213 | fi 1214 | 1215 | if [[ "$version" != "v"* ]] 1216 | then 1217 | version="v$version" 1218 | fi 1219 | 1220 | if ! dvm_install_deno "$version" 1221 | then 1222 | dvm_failure 1223 | return 1224 | fi 1225 | 1226 | dvm_print "Deno $version has been installed." 1227 | 1228 | dvm_use_version "$version" 1229 | dvm_set_default_alias_after_install "$version" 1230 | } 1231 | 1232 | # Try to install Deno from the network using the binary file, or build Deno from source code. 1233 | # Parameters: 1234 | # - $1: The Deno version to install. 1235 | dvm_install_deno() { 1236 | local version 1237 | 1238 | version="$1" 1239 | 1240 | case "$DVM_INSTALL_MODE" in 1241 | "binary") 1242 | if ! dvm_install_deno_by_binary "$version" 1243 | then 1244 | dvm_failure 1245 | return 1246 | fi 1247 | ;; 1248 | "source") 1249 | if ! dvm_install_deno_by_source "$version" 1250 | then 1251 | dvm_failure 1252 | return 1253 | fi 1254 | ;; 1255 | *) 1256 | dvm_print_error "Unknown install mode: $DVM_INSTALL_MODE" 1257 | dvm_failure 1258 | ;; 1259 | esac 1260 | } 1261 | 1262 | # Download and install the pre-compiled Deno binary from the network. 1263 | # Parameters: 1264 | # - $1: The Deno version to install. 1265 | dvm_install_deno_by_binary() { 1266 | local version 1267 | 1268 | version="$1" 1269 | 1270 | if ! dvm_get_package_data "$version" 1271 | then 1272 | dvm_failure 1273 | return 1274 | fi 1275 | 1276 | if [ "$DVM_INSTALL_SKIP_CACHE" = true ] || [ ! -f "$DVM_DIR/download/$version/deno.$DVM_TARGET_TYPE" ] 1277 | then 1278 | dvm_print "Downloading and installing Deno $version..." 1279 | if ! dvm_download_deno "$version" 1280 | then 1281 | dvm_failure 1282 | return 1283 | fi 1284 | else 1285 | dvm_print "Installing Deno $version from cache..." 1286 | fi 1287 | 1288 | dvm_extract_file "$version" 1289 | } 1290 | 1291 | # Download the Deno source code from the network and build the binary file. 1292 | # Parameters: 1293 | # - $1: The Deno version to install. 1294 | dvm_install_deno_by_source() { 1295 | local version 1296 | version="$1" 1297 | 1298 | if ! dvm_check_build_dependencies 1299 | then 1300 | dvm_failure 1301 | return 1302 | fi 1303 | 1304 | if ! dvm_clone_deno_source 1305 | then 1306 | dvm_failure 1307 | return 1308 | fi 1309 | 1310 | dvm_build_deno "$version" 1311 | } 1312 | 1313 | # Check whether the version string is a prefix or a full version. 1314 | # Parameters: 1315 | # - $1: The string to check. 1316 | dvm_is_version_prefix() { 1317 | local result 1318 | local version 1319 | 1320 | version="$1" 1321 | if [[ "$version" != "v"* ]] 1322 | then 1323 | version="v$version" 1324 | fi 1325 | 1326 | result=$(echo "$version" | grep -E "^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+") 1327 | if [ -z "$result" ] 1328 | then 1329 | dvm_debug "$version is a version prefix" 1330 | if ! dvm_get_remote_version_by_prefix "$version" 1331 | then 1332 | dvm_failure 1333 | return 1334 | fi 1335 | else 1336 | dvm_debug "$version is not a version prefix" 1337 | DVM_TARGET_VERSION="$version" 1338 | fi 1339 | } 1340 | 1341 | # Set the installed version as the 'default' alias if no default is set. 1342 | # Parameters: 1343 | # - $1: The Deno version to set as default. 1344 | dvm_set_default_alias_after_install() { 1345 | local version="$1" 1346 | 1347 | dvm_check_alias_dir 1348 | 1349 | if [ -f "$DVM_DIR/aliases/default" ] 1350 | then 1351 | return 1352 | fi 1353 | 1354 | echo "$version" > "$DVM_DIR/aliases/default" 1355 | dvm_print "Created default alias: default -> $version" 1356 | } 1357 | 1358 | # Validate the build output file. 1359 | # Parameters: 1360 | # - $1: The Deno version to install. 1361 | dvm_validate_build_target() { 1362 | local version 1363 | local target_version 1364 | 1365 | target_version="$1" 1366 | 1367 | if ! [ -f "$DVM_DIR/deno_code/target/release/deno" ] 1368 | then 1369 | dvm_print_error "No build output found." 1370 | dvm_failure 1371 | return 1372 | fi 1373 | 1374 | version=$("$DVM_DIR/deno_code/target/release/deno" --version | grep deno | cut -d " " -f 2) 1375 | if [ "v$version" != "$target_version" ] 1376 | then 1377 | dvm_print_error "Build target version mismatch: v$version" 1378 | dvm_debug "build file version: v$version" 1379 | dvm_debug "target version: $version" 1380 | dvm_failure 1381 | return 1382 | fi 1383 | } 1384 | 1385 | # Validate the downloaded file, and move it to the versions directory if the 1386 | # file is valid. 1387 | # Parameters: 1388 | # - $1: The Deno version to install. 1389 | dvm_validate_download_file() { 1390 | local version 1391 | local download_url 1392 | local download_file 1393 | local sha256sum_url 1394 | local sha256sum_file 1395 | local checksum 1396 | local checksum_expected 1397 | 1398 | version="$1" 1399 | download_url="$2" 1400 | 1401 | download_file="$DVM_DIR/download/$version/$DVM_TARGET_NAME" 1402 | sha256sum_url="$download_url.sha256sum" 1403 | sha256sum_file="$download_file.sha256sum" 1404 | 1405 | if [ "$DVM_INSTALL_SHA256SUM" = true ] && 1406 | dvm_has shasum && 1407 | ! dvm_compare_version "$version" "v2.0.1" 1408 | then 1409 | dvm_debug "downloading sha256sum file: $sha256sum_url" 1410 | 1411 | if ! dvm_download_file "$sha256sum_url" "$sha256sum_file" 1412 | then 1413 | dvm_print_error "Failed to download SHA256 file." 1414 | dvm_failure 1415 | return 1416 | fi 1417 | 1418 | dvm_print "Computing checksum with sha256sum ..." 1419 | checksum=$(shasum -a 256 "$download_file" | cut -d " " -f 1) 1420 | checksum_expected=$(cut -d " " -f 1 < "$sha256sum_file" ) 1421 | dvm_debug "checksum: $checksum, expected checksum: $checksum_expected" 1422 | 1423 | if [ "$checksum" != "$checksum_expected" ] 1424 | then 1425 | dvm_print_error "Checksum verification failed." 1426 | dvm_failure 1427 | return 1428 | fi 1429 | 1430 | dvm_print "Checksum matched!" 1431 | rm "$sha256sum_file" 1432 | fi 1433 | 1434 | mv "$download_file" "$DVM_DIR/download/$version/deno.$DVM_TARGET_TYPE" 1435 | } 1436 | 1437 | # Get remote data from the GitHub API (get a release by tag name) to validate the version from 1438 | # the parameter. 1439 | # Parameters: 1440 | # - $1: The version to validate. 1441 | dvm_validate_remote_version() { 1442 | local version 1443 | local target_version 1444 | # GitHub get release by tag name api url 1445 | local tag_url 1446 | 1447 | version="$1" 1448 | 1449 | if [[ "$version" != "v"* ]] 1450 | then 1451 | target_version="v$version" 1452 | else 1453 | target_version="$version" 1454 | fi 1455 | 1456 | dvm_debug "validation target deno version: $version" 1457 | 1458 | if [ -f "$DVM_DIR/cache/remote-versions" ] 1459 | then 1460 | dvm_debug "remote versions cache found, try to validate version $version" 1461 | if grep "$target_version" < "$DVM_DIR/cache/remote-versions" > /dev/null 1462 | then 1463 | dvm_debug "version $version found in cache" 1464 | return 1465 | fi 1466 | dvm_debug "no version $version found in cache, try to validate from network" 1467 | fi 1468 | 1469 | tag_url="https://api.github.com/repos/denoland/deno/releases/tags/$target_version" 1470 | 1471 | if ! dvm_request "$tag_url" 1472 | then 1473 | dvm_print_warning "Failed to validate Deno version." 1474 | fi 1475 | 1476 | tag_name=$(echo "$DVM_REQUEST_RESPONSE" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 1477 | 1478 | if [ -z "$tag_name" ] 1479 | then 1480 | if echo "$DVM_REQUEST_RESPONSE" | grep "Not Found" > /dev/null 1481 | then 1482 | dvm_print_error "Deno '$version' not found. Use the 'ls-remote' command to list available versions." 1483 | dvm_failure 1484 | else 1485 | dvm_print_warning "Failed to validate Deno version." 1486 | dvm_debug "validation response: $DVM_REQUEST_RESPONSE" 1487 | fi 1488 | fi 1489 | } 1490 | } 1491 | 1492 | ################## 1493 | ## Command list ## 1494 | ################## 1495 | { 1496 | # List all aliases and their corresponding Deno versions. 1497 | dvm_list_aliases() { 1498 | local aliased_version 1499 | 1500 | if [ ! -d "$DVM_DIR/aliases" ] 1501 | then 1502 | return 1503 | fi 1504 | 1505 | if [ -z "$(ls -A "$DVM_DIR/aliases")" ] 1506 | then 1507 | return 1508 | fi 1509 | 1510 | for alias_path in "$DVM_DIR/aliases"/* 1511 | do 1512 | if [ ! -f "$alias_path" ] 1513 | then 1514 | continue; 1515 | fi 1516 | 1517 | alias_name=${alias_path##*/} 1518 | aliased_version=$(head -n 1 "$alias_path") 1519 | 1520 | if [ -z "$aliased_version" ] || 1521 | [ ! -f "$DVM_DIR/versions/$aliased_version/deno" ] 1522 | then 1523 | dvm_print "$alias_name -> N/A" 1524 | else 1525 | dvm_print "$alias_name -> $aliased_version" 1526 | fi 1527 | done 1528 | } 1529 | 1530 | # List all installed Deno versions. 1531 | dvm_list_local_versions() { 1532 | local version 1533 | 1534 | if [ ! -d "$DVM_DIR/versions" ] 1535 | then 1536 | return 1537 | fi 1538 | 1539 | if [ -z "$(ls -A "$DVM_DIR/versions")" ] 1540 | then 1541 | return 1542 | fi 1543 | 1544 | for dir in "$DVM_DIR/versions"/* 1545 | do 1546 | if [ ! -f "$dir/deno" ] 1547 | then 1548 | continue 1549 | fi 1550 | 1551 | version=${dir##*/} 1552 | 1553 | if [ "$version" = "$DVM_DENO_VERSION" ] 1554 | then 1555 | dvm_print_with_color "32" "-> $version" 1556 | else 1557 | dvm_print " $version" 1558 | fi 1559 | done 1560 | } 1561 | } 1562 | 1563 | ####################### 1564 | ## Command ls-remote ## 1565 | ####################### 1566 | { 1567 | # Try to get all remote versions from the local cache or the remote server. 1568 | dvm_get_remote_versions() { 1569 | local last_version 1570 | local cache_file 1571 | local legacy_versions 1572 | 1573 | # deno.com/versions.json does not provide the versions before v1.0.0, so we put these version 1574 | # into the static legacy versions file. 1575 | if [ -f "$DVM_DIR/legacy-versions" ] && dvm_get_versions_from_deno_versions_json 1576 | then 1577 | legacy_versions=$(cat "$DVM_DIR/legacy-versions") 1578 | DVM_REMOTE_VERSIONS=$(echo -e "$legacy_versions\n$DVM_REMOTE_VERSIONS") 1579 | return 1580 | fi 1581 | 1582 | dvm_debug "Failed to get Deno versions from deno.com/versions.json, fallback to GitHub API" 1583 | 1584 | cache_file="$DVM_DIR/cache/remote-versions" 1585 | 1586 | if [ ! -d "$DVM_DIR/cache" ] 1587 | then 1588 | mkdir "$DVM_DIR/cache" 1589 | fi 1590 | 1591 | if [ -f "$cache_file" ] && [ "$(head -n 1 "$cache_file")" = "v0.1.0" ] 1592 | then 1593 | if [ "$(find "$cache_file" -mmin -15 2>/dev/null)" ] 1594 | then 1595 | DVM_REMOTE_VERSIONS="$(cat "$cache_file")" 1596 | dvm_debug "remote versions cache found" 1597 | return 1598 | else 1599 | last_version="$(tail -n 1 "$cache_file")" 1600 | if [ -n "$last_version" ] 1601 | then 1602 | if ! dvm_get_latest_version 1603 | then 1604 | return 1605 | fi 1606 | 1607 | dvm_debug "last version in cache: $last_version" 1608 | dvm_debug "latest version from network: $DVM_TARGET_VERSION" 1609 | 1610 | if [ "$last_version" = "$DVM_TARGET_VERSION" ] 1611 | then 1612 | DVM_REMOTE_VERSIONS="$(cat "$cache_file")" 1613 | return 1614 | fi 1615 | fi 1616 | fi 1617 | else 1618 | dvm_debug "remote versions cache not found or it's invalid" 1619 | rm -rf "$cache_file" 1620 | fi 1621 | 1622 | if ! dvm_get_versions_from_network "$last_version" 1623 | then 1624 | dvm_failure 1625 | return 1626 | fi 1627 | 1628 | echo "$DVM_REMOTE_VERSIONS" >> "$cache_file" 1629 | 1630 | # re-read the full remote versions 1631 | DVM_REMOTE_VERSIONS=$(cat "$cache_file") 1632 | } 1633 | 1634 | # Call https://deno.com/versions.json to get all stable versions. 1635 | dvm_get_versions_from_deno_versions_json() { 1636 | local versions 1637 | 1638 | dvm_debug "getting versions from deno.com/versions.json" 1639 | 1640 | if ! dvm_request "https://deno.com/versions.json" 1641 | then 1642 | dvm_print_error "Failed to list remote versions from deno.com." 1643 | dvm_failure 1644 | return 1645 | fi 1646 | 1647 | versions=${DVM_REQUEST_RESPONSE#*cli} 1648 | DVM_REMOTE_VERSIONS=$(echo "$versions" | sed 's/"/\n/g' | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$" | sort -V) 1649 | } 1650 | 1651 | # Call the GitHub API to get all versions (release tag names) from the Deno repo. 1652 | # Parameters: 1653 | # - $1: The last version that was already fetched (optional). 1654 | dvm_get_versions_from_network() { 1655 | local request_url 1656 | local all_versions 1657 | local size 1658 | local tmp_versions 1659 | local expect_version 1660 | 1661 | if [ "$#" != "0" ] && [ -n "$1" ] 1662 | then 1663 | expect_version="$1" 1664 | fi 1665 | 1666 | size=100 1667 | request_url="https://api.github.com/repos/denoland/deno/releases?per_page=$size&page=1" 1668 | 1669 | while [ "$request_url" != "" ] 1670 | do 1671 | if ! dvm_request "$request_url" "--include" 1672 | then 1673 | dvm_print_error "Failed to list remote versions." 1674 | dvm_failure 1675 | return 1676 | fi 1677 | 1678 | tmp_versions=$(echo "$DVM_REQUEST_RESPONSE" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 1679 | all_versions="$all_versions\n$tmp_versions" 1680 | 1681 | if [ -n "$expect_version" ] && echo "$tmp_versions" | grep "$expect_version" > /dev/null 1682 | then 1683 | all_versions=${all_versions%"${expect_version}"*} 1684 | break 1685 | fi 1686 | 1687 | request_url=$(echo "$DVM_REQUEST_RESPONSE" | grep -i "link:" | sed 's/,/\n/g' | grep "rel=\"next\"" \ 1688 | | sed 's/[<>]/\n/g' | grep "http") 1689 | dvm_debug "list releases next page url: $request_url" 1690 | done 1691 | 1692 | DVM_REMOTE_VERSIONS=$(echo -e "$all_versions" | sed '/^$/d' | sed 'x;1!H;$!d;x') 1693 | } 1694 | 1695 | # Get all available versions from the network and list them with installation status. 1696 | dvm_list_remote_versions() { 1697 | if ! dvm_get_remote_versions 1698 | then 1699 | return 1700 | fi 1701 | 1702 | dvm_get_current_version 1703 | 1704 | while read -r version 1705 | do 1706 | if [ "$DVM_DENO_VERSION" = "$version" ] 1707 | then 1708 | dvm_print_with_color "32" "-> $version *" 1709 | elif [ -f "$DVM_DIR/versions/$version/deno" ] 1710 | then 1711 | dvm_print_with_color "34" " $version *" 1712 | else 1713 | dvm_print " $version" 1714 | fi 1715 | done <<< "$DVM_REMOTE_VERSIONS" 1716 | } 1717 | } 1718 | 1719 | ################### 1720 | ## Command purge ## 1721 | ################### 1722 | { 1723 | # Remove all components of DVM from the system. 1724 | dvm_purge_dvm() { 1725 | local content 1726 | 1727 | # Remove DVM directory; all installed versions will also be removed. 1728 | rm -rf "$DVM_DIR" 1729 | 1730 | # Get profile file and remove DVM configuration lines. 1731 | dvm_get_profile_file 1732 | 1733 | content=$(sed "/Deno Version Manager/d;/DVM_DIR/d;/DVM_BIN/d" "$DVM_PROFILE_FILE") 1734 | echo "$content" > "$DVM_PROFILE_FILE" 1735 | 1736 | # unset global variables 1737 | unset -v DVM_COLOR_MODE DVM_DENO_VERSION DVM_DIR DVM_INSTALL_MODE \ 1738 | DVM_INSTALL_REGISTRY DVM_INSTALL_SHA256SUM DVM_INSTALL_SKIP_CACHE \ 1739 | DVM_INSTALL_SKIP_VALIDATION DVM_LATEST_VERSION DVM_PROFILE_FILE DVM_QUIET_MODE \ 1740 | DVM_REMOTE_VERSIONS DVM_REQUEST_RESPONSE DVM_SOURCE DVM_TARGET_ARCH \ 1741 | DVM_TARGET_NAME DVM_TARGET_OS DVM_TARGET_TYPE DVM_TARGET_VERSION \ 1742 | DVM_VERBOSE_MODE DVM_VERSION 1743 | # unset dvm itself 1744 | unset -f dvm 1745 | # unset dvm functions 1746 | unset -f dvm_build_deno dvm_check_alias_dir dvm_check_build_dependencies \ 1747 | dvm_check_local_deno_clone dvm_clean_caches dvm_clean_download_cache \ 1748 | dvm_clone_deno_source dvm_compare_version dvm_confirm_with_prompt \ 1749 | dvm_copy_build_target_to_versions_dir dvm_deactivate dvm_debug \ 1750 | dvm_download_deno dvm_download_file dvm_extract_file dvm_failure \ 1751 | dvm_fix_invalid_versions dvm_get_current_version \ 1752 | dvm_get_dvm_latest_version dvm_get_latest_version dvm_get_package_data \ 1753 | dvm_get_profile_file dvm_get_remote_version_by_prefix dvm_get_remote_versions \ 1754 | dvm_get_version dvm_get_version_from_dvmrc dvm_get_version_by_param \ 1755 | dvm_get_versions_from_deno_versions_json dvm_get_versions_from_network dvm_has \ 1756 | dvm_install_deno dvm_install_deno_by_binary \ 1757 | dvm_install_deno_by_source dvm_install_version dvm_is_version_prefix dvm_list_aliases \ 1758 | dvm_list_local_versions dvm_list_remote_versions dvm_locate_version dvm_parse_options \ 1759 | dvm_print dvm_print_doctor_message dvm_print_current_version dvm_print_error \ 1760 | dvm_print_help dvm_print_warning dvm_print_with_color dvm_purge_dvm \ 1761 | dvm_read_dvmrc_file dvm_request dvm_rm_alias dvm_run_with_version \ 1762 | dvm_scan_and_fix_versions dvm_set_alias \ 1763 | dvm_set_default_alias_after_install dvm_set_default_env dvm_strip_path \ 1764 | dvm_success dvm_uninstall_version dvm_update_dvm dvm_use_version \ 1765 | dvm_validate_build_target dvm_validate_download_file dvm_validate_remote_version 1766 | # unset dvm shell completion functions 1767 | unset -f _dvm_add_aliases_to_opts _dvm_add_versions_to_opts \ 1768 | _dvm_has_active_version _dvm_add_options_to_opts _dvm_completion 1769 | 1770 | echo "DVM has been removed from your computer." 1771 | } 1772 | } 1773 | 1774 | ################# 1775 | ## Command run ## 1776 | ################# 1777 | { 1778 | # Run the specified Deno version without activating it. 1779 | # Parameters: 1780 | # $1: The version of Deno to run. 1781 | # $2...: The parameters to pass to Deno. 1782 | dvm_run_with_version() { 1783 | if [ ! -f "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" ] 1784 | then 1785 | dvm_print_error "Deno $DVM_TARGET_VERSION is not installed." 1786 | dvm_failure 1787 | return 1788 | fi 1789 | 1790 | dvm_print "Running with Deno $DVM_TARGET_VERSION." 1791 | 1792 | dvm_debug "target deno version: $DVM_TARGET_VERSION" 1793 | dvm_debug "run deno with parameters:" "$@" 1794 | 1795 | "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" "$@" 1796 | } 1797 | } 1798 | 1799 | ################### 1800 | ## Command which ## 1801 | ################### 1802 | { 1803 | # Get the path of the active Deno version or a specific version. 1804 | # Parameters: 1805 | # $1: The version of Deno, or 'current'. 1806 | dvm_locate_version() { 1807 | local target_version 1808 | 1809 | target_version="$DVM_TARGET_VERSION" 1810 | 1811 | if [ "$1" = "current" ] 1812 | then 1813 | dvm_get_current_version 1814 | if [ -n "$DVM_DENO_VERSION" ] 1815 | then 1816 | target_version="$DVM_DENO_VERSION" 1817 | fi 1818 | fi 1819 | 1820 | if [ -f "$DVM_DIR/versions/$target_version/deno" ] 1821 | then 1822 | dvm_print "$DVM_DIR/versions/$target_version/deno" 1823 | else 1824 | dvm_print "Deno $target_version is not installed." 1825 | fi 1826 | } 1827 | } 1828 | 1829 | ##################### 1830 | ## Command unalias ## 1831 | ##################### 1832 | { 1833 | # Remove an alias for a Deno version. 1834 | # Parameters: 1835 | # $1: The alias name to remove. 1836 | dvm_rm_alias() { 1837 | local alias_name 1838 | local aliased_version 1839 | 1840 | dvm_check_alias_dir 1841 | 1842 | while [ "$#" -gt "0" ] 1843 | do 1844 | case "$1" in 1845 | "-"*) 1846 | ;; 1847 | *) 1848 | if [ -z "$alias_name" ] 1849 | then 1850 | alias_name="$1" 1851 | fi 1852 | esac 1853 | 1854 | shift 1855 | done 1856 | 1857 | if [ ! -f "$DVM_DIR/aliases/$alias_name" ] 1858 | then 1859 | dvm_print_error "Alias $alias_name does not exist." 1860 | dvm_failure 1861 | return 1862 | fi 1863 | 1864 | aliased_version=$(head -n 1 "$DVM_DIR/aliases/$alias_name") 1865 | 1866 | rm "$DVM_DIR/aliases/$alias_name" 1867 | 1868 | dvm_print "Alias $alias_name has been deleted." 1869 | dvm_print "Restore it with 'dvm alias $alias_name $aliased_version'." 1870 | } 1871 | } 1872 | 1873 | ####################### 1874 | ## Command uninstall ## 1875 | ####################### 1876 | { 1877 | # Uninstall the specified version of Deno from the computer. Cannot uninstall the active Deno 1878 | # version or versions installed from another source. 1879 | # Parameters: 1880 | # - $1: The Deno version to uninstall. 1881 | dvm_uninstall_version() { 1882 | local input_version 1883 | 1884 | input_version="$1" 1885 | 1886 | dvm_get_current_version 1887 | 1888 | if [ "$DVM_DENO_VERSION" = "$DVM_TARGET_VERSION" ] 1889 | then 1890 | dvm_print "Cannot uninstall the active Deno version ($DVM_DENO_VERSION)." 1891 | dvm_failure 1892 | return 1893 | fi 1894 | 1895 | if [ -f "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" ] 1896 | then 1897 | rm -rf "$DVM_DIR/versions/$DVM_TARGET_VERSION" 1898 | 1899 | dvm_print "Uninstalled Deno $DVM_TARGET_VERSION." 1900 | else 1901 | dvm_print "Deno $DVM_TARGET_VERSION is not installed." 1902 | fi 1903 | 1904 | if [ -n "$input_version" ] && [ "$input_version" != "$DVM_TARGET_VERSION" ] && [ -f "$DVM_DIR/aliases/$input_version" ] 1905 | then 1906 | rm "$DVM_DIR/aliases/$input_version" 1907 | fi 1908 | } 1909 | } 1910 | 1911 | ##################### 1912 | ## Command upgrade ## 1913 | ##################### 1914 | { 1915 | # Get the latest version of DVM from the GitHub or Gitee repo. 1916 | dvm_get_dvm_latest_version() { 1917 | local request_url 1918 | 1919 | case "$DVM_SOURCE" in 1920 | "gitee") 1921 | request_url="https://gitee.com/api/v5/repos/ghosind/dvm/releases/latest" 1922 | ;; 1923 | "github"|*) 1924 | request_url="https://api.github.com/repos/ghosind/dvm/releases/latest" 1925 | ;; 1926 | esac 1927 | 1928 | dvm_debug "dvm source url: $request_url" 1929 | 1930 | if ! dvm_request "$request_url" 1931 | then 1932 | dvm_print_error "failed to get the latest DVM version." 1933 | dvm_failure 1934 | return 1935 | fi 1936 | 1937 | DVM_LATEST_VERSION=$(echo "$DVM_REQUEST_RESPONSE" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 1938 | if [ -n "$DVM_LATEST_VERSION" ] 1939 | then 1940 | dvm_debug "dvm latest version: $DVM_LATEST_VERSION" 1941 | else 1942 | dvm_debug "getting dvm latest response: $DVM_REQUEST_RESPONSE" 1943 | dvm_failure 1944 | fi 1945 | } 1946 | 1947 | # Upgrade DVM itself to the specified version. 1948 | dvm_update_dvm() { 1949 | local cwd 1950 | 1951 | cwd=$(pwd) 1952 | 1953 | dvm_get_profile_file 1954 | 1955 | if ! cd "$DVM_DIR" 2>/dev/null 1956 | then 1957 | dvm_print_error "failed to update dvm." 1958 | dvm_failure 1959 | return 1960 | fi 1961 | 1962 | # reset changes if exists 1963 | if git reset --hard HEAD && git fetch --all && git pull origin master --tags && git checkout "$DVM_LATEST_VERSION" 1964 | then 1965 | dvm_print "DVM has been upgraded to the latest version. Please restart your terminal or run \`source $DVM_PROFILE_FILE\` to apply the changes." 1966 | 1967 | cd "$cwd" || dvm_failure 1968 | else 1969 | dvm_print_error "failed to update dvm." 1970 | cd "$cwd" && dvm_failure 1971 | fi 1972 | } 1973 | } 1974 | 1975 | ################# 1976 | ## Command use ## 1977 | ################# 1978 | { 1979 | # Set the specified Deno version or alias as the active version by updating PATH. 1980 | # Parameters: 1981 | # - $1: Deno version or alias name to use. 1982 | dvm_use_version() { 1983 | # deno executable file version 1984 | local deno_version 1985 | # target deno executable file path 1986 | local target_path 1987 | local path_without_dvm 1988 | 1989 | dvm_get_version "$@" 1990 | 1991 | if [ -z "$DVM_TARGET_VERSION" ] 1992 | then 1993 | dvm_print_help 1994 | dvm_failure 1995 | return 1996 | fi 1997 | 1998 | target_dir="$DVM_DIR/versions/$DVM_TARGET_VERSION" 1999 | target_path="$target_dir/deno" 2000 | 2001 | if [ -f "$target_path" ] 2002 | then 2003 | # get target deno executable file version 2004 | deno_version=$("$target_path" --version 2>/dev/null | grep deno | cut -d " " -f 2) 2005 | 2006 | if [ -n "$deno_version" ] && [ "$DVM_TARGET_VERSION" != "v$deno_version" ] 2007 | then 2008 | # print warning message when deno version is different with parameter. 2009 | dvm_print_warning "This version may have been upgraded; it is now v$deno_version." 2010 | fi 2011 | 2012 | # export PATH with the target dir in front 2013 | path_without_dvm=$(dvm_strip_path) 2014 | export PATH="$target_dir":${path_without_dvm} 2015 | 2016 | dvm_print "Now using Deno $DVM_TARGET_VERSION." 2017 | else 2018 | dvm_print "Deno $DVM_TARGET_VERSION is not installed. You can run 'dvm install $DVM_TARGET_VERSION' to install it." 2019 | dvm_failure 2020 | fi 2021 | } 2022 | } 2023 | 2024 | # The entry of DVM, it will handle options and try to execute commands. 2025 | dvm() { 2026 | local version="" 2027 | 2028 | dvm_set_default_env 2029 | 2030 | if [ "$#" = "0" ] 2031 | then 2032 | dvm_print_help 2033 | dvm_success 2034 | return 2035 | fi 2036 | 2037 | dvm_parse_options "$@" 2038 | 2039 | case "$1" in 2040 | "alias") 2041 | shift 2042 | 2043 | dvm_set_alias "$@" 2044 | 2045 | ;; 2046 | "clean") 2047 | dvm_clean_caches 2048 | 2049 | ;; 2050 | "current") 2051 | # get the current version 2052 | dvm_print_current_version 2053 | 2054 | ;; 2055 | "deactivate") 2056 | dvm_deactivate 2057 | 2058 | ;; 2059 | "doctor") 2060 | local mode 2061 | 2062 | shift 2063 | 2064 | mode="scan" 2065 | 2066 | while [ "$#" -gt "0" ] 2067 | do 2068 | case "$1" in 2069 | "--fix") 2070 | mode="fix" 2071 | ;; 2072 | *) 2073 | ;; 2074 | esac 2075 | 2076 | shift 2077 | done 2078 | 2079 | if [ "$mode" = "fix" ] && 2080 | ! dvm_confirm_with_prompt "Doctor fix command will remove all duplicated / corrupted versions, do you want to continue?" 2081 | then 2082 | return 2083 | fi 2084 | 2085 | dvm_scan_and_fix_versions "$mode" 2086 | 2087 | ;; 2088 | "install"|"i") 2089 | # install the specified version 2090 | shift 2091 | 2092 | while [ "$#" -gt "0" ] 2093 | do 2094 | case "$1" in 2095 | "--registry="*) 2096 | DVM_INSTALL_REGISTRY=${1#--registry=} 2097 | ;; 2098 | "--skip-validation") 2099 | DVM_INSTALL_SKIP_VALIDATION=true 2100 | ;; 2101 | "--skip-download-cache") 2102 | DVM_INSTALL_SKIP_CACHE=true 2103 | ;; 2104 | "--from-binary") 2105 | DVM_INSTALL_MODE="binary" 2106 | ;; 2107 | "--from-source") 2108 | DVM_INSTALL_MODE="source" 2109 | ;; 2110 | "--sha256sum") 2111 | DVM_INSTALL_SHA256SUM=true 2112 | ;; 2113 | "--no-sha256sum") 2114 | DVM_INSTALL_SHA256SUM=false 2115 | ;; 2116 | "-"*) 2117 | ;; 2118 | *) 2119 | version="$1" 2120 | ;; 2121 | esac 2122 | 2123 | shift 2124 | done 2125 | 2126 | dvm_install_version "$version" 2127 | 2128 | ;; 2129 | "list"|"ls") 2130 | # list all local versions 2131 | dvm_get_current_version 2132 | 2133 | dvm_list_local_versions 2134 | 2135 | dvm_list_aliases 2136 | 2137 | ;; 2138 | "list-remote"|"ls-remote") 2139 | # list all remote versions 2140 | dvm_list_remote_versions 2141 | 2142 | ;; 2143 | "purge") 2144 | if ! dvm_confirm_with_prompt "Do you want to remove DVM from your computer?" 2145 | then 2146 | return 2147 | fi 2148 | 2149 | if ! dvm_confirm_with_prompt "Remove dvm will also remove installed deno(s), do you want to continue?" 2150 | then 2151 | return 2152 | fi 2153 | 2154 | dvm_purge_dvm 2155 | 2156 | ;; 2157 | "run") 2158 | shift 2159 | 2160 | dvm_get_version "$@" 2161 | 2162 | if [ "$DVM_TARGET_VERSION" = "" ] 2163 | then 2164 | dvm_print_help 2165 | dvm_failure 2166 | return 2167 | fi 2168 | 2169 | while [ "$#" != "0" ] 2170 | do 2171 | case "$1" in 2172 | "-"*) 2173 | shift 2174 | ;; 2175 | *) 2176 | shift 2177 | break 2178 | ;; 2179 | esac 2180 | done 2181 | 2182 | dvm_run_with_version "$@" 2183 | 2184 | ;; 2185 | "which") 2186 | shift 2187 | 2188 | if [ "$#" = "0" ] || [ "$1" != "current" ] 2189 | then 2190 | dvm_get_version "$@" 2191 | 2192 | if [ -z "$DVM_TARGET_VERSION" ] 2193 | then 2194 | dvm_print_help 2195 | dvm_failure 2196 | return 2197 | fi 2198 | fi 2199 | 2200 | dvm_locate_version "$@" 2201 | 2202 | ;; 2203 | "unalias") 2204 | shift 2205 | 2206 | dvm_rm_alias "$@" 2207 | 2208 | ;; 2209 | "uninstall") 2210 | # uninstall the specified version 2211 | shift 2212 | 2213 | dvm_get_version "$@" 2214 | if [ "$DVM_TARGET_VERSION" = "" ] 2215 | then 2216 | dvm_print_help 2217 | dvm_failure 2218 | return 2219 | fi 2220 | 2221 | dvm_uninstall_version "$DVM_TARGET_VERSION" 2222 | 2223 | ;; 2224 | "upgrade") 2225 | if ! dvm_get_dvm_latest_version 2226 | then 2227 | return 2228 | fi 2229 | 2230 | if [ "$DVM_LATEST_VERSION" = "$DVM_VERSION" ] 2231 | then 2232 | dvm_print "dvm is update to date." 2233 | dvm_success 2234 | return 2235 | fi 2236 | 2237 | dvm_update_dvm 2238 | 2239 | ;; 2240 | "use") 2241 | # change current version to specified version 2242 | shift 2243 | 2244 | dvm_use_version "$@" 2245 | 2246 | ;; 2247 | "help"|"--help"|"-h") 2248 | # print help 2249 | dvm_print_help 2250 | 2251 | ;; 2252 | "--version") 2253 | # print dvm version 2254 | dvm_print "$DVM_VERSION" 2255 | 2256 | ;; 2257 | *) 2258 | dvm_print_error "unknown command $1." 2259 | dvm_print_help 2260 | dvm_failure 2261 | ;; 2262 | esac 2263 | } 2264 | 2265 | # Activate the default version when a new terminal session was created. It 2266 | # need to run in the quiet mode to avoid printing any messages. 2267 | if [ -f "$DVM_DIR/aliases/default" ] 2268 | then 2269 | DVM_QUIET_MODE=true 2270 | dvm_use_version "default" 2271 | DVM_QUIET_MODE=false 2272 | fi 2273 | 2274 | } 2275 | --------------------------------------------------------------------------------