├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── lint.yaml │ └── test.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README-CN.md ├── README.md ├── SECURITY.md ├── bash_completion ├── dvm.sh ├── install.sh ├── legacy-versions └── test ├── test_alias.sh ├── test_dvmrc_file.sh ├── test_install_from_source.sh ├── test_install_version.sh ├── test_install_version_by_prefix.sh ├── test_ls_remote.sh └── test_uninstall_version.sh /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | For Windows users, you must install DVM v0.7.0 or later versions, and also need to install a bash shell if you want to use this tool. For example, you can install WSL and execute `bash` command in PowerShell. 14 | 15 | ***Please do not use `deno upgrade` command to upgrade Deno after you had installed Deno with DVM.*** 16 | 17 | - [Installing and Updating](#installing-and-updating) 18 | - [Installation](#installation) 19 | - [Upgrade DVM](#upgrade-dvm) 20 | - [Prerequirement](#prerequirement) 21 | - [Getting Started](#getting-started) 22 | - [List available versions](#list-available-versions) 23 | - [List installed versions](#list-installed-versions) 24 | - [Install Deno](#install-deno) 25 | - [Uninstall Deno](#uninstall-deno) 26 | - [Set active version](#set-active-version) 27 | - [Get current version](#get-current-version) 28 | - [Set an alias](#set-an-alias) 29 | - [Run with a version](#run-with-a-version) 30 | - [Commands](#commands) 31 | - [Uninstalling DVM](#uninstalling-dvm) 32 | - [Use `purge` command](#use-purge-command) 33 | - [Manual uninstall](#manual-uninstall) 34 | - [License](#license) 35 | 36 | ## Installing and Updating 37 | 38 | ### Installation 39 | 40 | There are two ways to install DVM. 41 | 42 | 1. Install dvm from network by the following command: 43 | 44 | ```sh 45 | curl -o- "https://raw.githubusercontent.com/ghosind/dvm/master/install.sh" | bash 46 | ``` 47 | 48 | For Chinese user, you can also install it from Gitee by the following command: 49 | 50 | ```sh 51 | curl -o- "https://gitee.com/ghosind/dvm/raw/master/install.sh" | DVM_SOURCE=gitee bash 52 | ``` 53 | 54 | 2. Clone this project and execute `install.sh` script: 55 | 56 | ```sh 57 | git clone "https://github.com/ghosind/dvm.git" 58 | # you can also clone it from gitee 59 | # git clone "https://gitee.com/ghosind/dvm.git" 60 | cd dvm 61 | ./install.sh 62 | ``` 63 | 64 | After installed dvm, please restart your terminal or use `source ` to apply changes. 65 | 66 | The default install location is `~/.dvm`, you can use `-d ` option (for local install only) or `$DVM_DIR` environment variable to specify an inexistent directory as the install location. 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 | ### Upgrade DVM 74 | 75 | Since DVM `v0.3.0`, we provided `upgrade` command to update your DVM to the latest version. 76 | 77 | ```sh 78 | dvm upgrade 79 | ``` 80 | 81 | If you want to update the DVM that less than `v0.3.0`, you may need to uninstall the current version and re-install the latest version. You can get the uninstall steps from [Manual uninstall](#manual-uninstall) section. 82 | 83 | ## Prerequirement 84 | 85 | Please make sure you have required dependencies installed: 86 | 87 | - curl 88 | - git 89 | - unzip (for Deno v0.36.0 and newer versions) 90 | - gunzip (for Deno v0.35.0 and lower versions) 91 | 92 | For installing Deno from source, please make sure you have required dependencies installed: 93 | 94 | - rustc 95 | - cargo 96 | - cc 97 | - cmake 98 | 99 | ## Getting Started 100 | 101 | After installed dvm, you can use it to manage multiple version Deno environments. 102 | 103 | ### List available versions 104 | 105 | Use `dvm list-remote` or `dvm ls-remote` to list all available versions from remote. 106 | 107 | ```sh 108 | # list all available versions 109 | dvm list-remote 110 | # ls-remote is an alias for list-remote command 111 | dvm ls-remote 112 | ``` 113 | 114 | ### List installed versions 115 | 116 | Use `dvm list` or `dvm ls` to list all installed versions. 117 | 118 | ```sh 119 | # list all installed versions 120 | dvm list 121 | # ls command is an alias for list command 122 | dvm ls 123 | ``` 124 | 125 | ### Install Deno 126 | 127 | Use `dvm install ` command to download and install a specified version from the source. 128 | 129 | ```sh 130 | dvm install v1.0.0 131 | # deno v1.0.0 has installed. 132 | # Using deno v1.0.0 now. 133 | 134 | dvm install v0.42.0 135 | # deno v0.42.0 has 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 with `--from-source` option. 142 | 143 | ```sh 144 | dvm install --from-source v1.35.0 145 | ``` 146 | 147 | ### Uninstall Deno 148 | 149 | Use `dvm uninstall ` command to uninstall a specified version. 150 | 151 | ```sh 152 | dvm uninstall v0.39.0 153 | # uninstalled deno v0.39.0. 154 | 155 | # default is an alias name 156 | dvm uninstall default 157 | # uninstalled deno default. 158 | ``` 159 | 160 | ### Set active version 161 | 162 | Use `dvm use [version]` command to link `deno` to the specified installed version by parameter or `.dvmrc` file. 163 | 164 | ```sh 165 | # use v1.0.0 166 | dvm use v1.0.0 167 | # Using deno v1.0.0 now. 168 | ``` 169 | 170 | If you do not specify the active version, DVM will try to read `.dvmrc` file from the current working directory. 171 | 172 | ```sh 173 | # cat .dvmrc 174 | # # v1.4.0 175 | dvm use 176 | # Found './dvmrc' with version v1.4.0 177 | # Using deno v1.4.0 now. 178 | ``` 179 | 180 | Set active version by `use` command is for a single terminal session only. If you want to set an active version for all terminal sessions, please set a `default` alias to a version. See [Set an alias](#set-active-version) section for more details. 181 | 182 | ### Get current version 183 | 184 | Use `dvm current` command to display the current version of Deno. 185 | 186 | ```sh 187 | dvm current 188 | # v1.0.0 189 | ``` 190 | 191 | ### Set an alias 192 | 193 | Use `dvm alias` command to set alias name for a installed version of Deno. 194 | 195 | ```sh 196 | dvm ls 197 | # v1.0.0 198 | 199 | # Set an alias 200 | dvm alias default v1.0.0 201 | # default -> v1.0.0 202 | 203 | dvm ls 204 | # v1.0.0 205 | # default -> v1.0.0 206 | ``` 207 | 208 | ### Run with a version 209 | 210 | Use `dvm run` command to run Deno on the specified version with arguments. 211 | 212 | ```sh 213 | dvm run v1.0.0 214 | # Running with deno v1.0.0 215 | # Deno 1.0.0 216 | # exit using ctrl+d or close() 217 | # > 218 | ``` 219 | 220 | You can also run a script file with the specified version. 221 | 222 | ```sh 223 | # Run app.ts with Deno v1.0.0 224 | dvm run v1.0.0 app.ts 225 | ``` 226 | 227 | ## Commands 228 | 229 | DVM supported the following commands: 230 | 231 | | Command | Usage | Description | 232 | |:-------:|:-----:|:------------| 233 | | `install` | `dvm install` | Download and install the latest version or the version reading from `.dvmrc` file. | 234 | | | `dvm install ` | Download and install the specified version, or the latest version with the specified prefix. | 235 | | | `dvm install --registry=` | Download and install deno with the specified registry. | 236 | | | `dvm install --skip-validation` | Do not validate deno version before trying to download it. | 237 | | | `dvm install --from-source` | Build and install Deno from source code. | 238 | | | `dvm install --skip-download-cache` | Download and install Deno without using downloaded cache. | 239 | | | `dvm install --sha256sum` | Download and install Deno with sha256sum check. | 240 | | `uninstall` | `dvm uninstall ` | Uninstall the specified version. | 241 | | `use` | `dvm use` | Use the specified version read from .dvmrc. | 242 | | | `dvm use ` | Use the specified version that passed by argument. | 243 | | | `dvm use ` | Use the specified version of the alias name that passed by argument. | 244 | | `run` | `dvm run [args]` | Run deno on the specified version with arguments. | 245 | | `alias` | `dvm alias ` | Set an alias name to specified version. | 246 | | `unalias` | `dvm unalias ` | Delete the specified alias name. | 247 | | `current` | `dvm current` | Display the current version of Deno. | 248 | | `ls` | `dvm ls` | List all installed versions. | 249 | | `list` | `dvm list` | Same as `ls` command. | 250 | | `ls-remote` | `dvm ls-remote` | List all remote versions. | 251 | | `list-remote` | `dvm list-remote` | Same as `ls-remote` command. | 252 | | `which` | `dvm which` | Display the path of the version that specified in .dvmrc. | 253 | | | `dvm which current` | Display the path of the current version. | 254 | | | `dvm which ` | Display the path of specified version. | 255 | | `clean` | `dvm clean` | Remove all downloaded packages and the cached versions. | 256 | | `deactivate` | `dvm deactivate` | Deactivate Deno on current shell. | 257 | | `doctor` | `dvm doctor` | Find invalid / corrupted versions. | 258 | | | `dvm doctor --fix` | Find and fix invalid / corrupted versions. | 259 | | `upgrade` | `dvm upgrade` | Update dvm itself. | 260 | | `purge` | `dvm purge` | Remove dvm from your computer. | 261 | | `help` | `dvm help` | Show dvm help message. | 262 | 263 | Please visit [dvm wiki](https://github.com/ghosind/dvm/wiki) for more details. 264 | 265 | ### Options 266 | 267 | | Option | Description | 268 | |:------:|:------------| 269 | | `-q`, `--quiet` | Run DVM with quiet mode, it'll hide most of the outputs. | 270 | | `--color` | Print messages with color mode. | 271 | | `--no-color` | Print messages with no color mode. | 272 | | `--verbose` | Print debug messages. | 273 | 274 | ## Uninstalling DVM 275 | 276 | There are two ways to remove DVM from your computer. 277 | 278 | ### Use `purge` command 279 | 280 | You can execute `dvm purge` to remove dvm from your computer if your dvm version is `v0.3.2` and above. It will remove the `$DVM_DIR` and dvm configurations in shell config file. 281 | 282 | If your dvm is less than `v0.3.2`, please following the next section ([Manual uninstall](#manual-uninstall)) to remove DVM. 283 | 284 | ### Manual uninstall 285 | 286 | You can also execute following command to uninstall dvm: 287 | 288 | ```sh 289 | rm -rf "$DVM_DIR" 290 | ``` 291 | 292 | Edit shell config file (like `.bashrc` or `.zshrc`), and remove the following lines: 293 | 294 | ```sh 295 | # Deno Version Manager 296 | export DVM_DIR="$HOME/.dvm" 297 | [ -f "$DVM_DIR/dvm.sh" ] && . "$DVM_DIR/dvm.sh" 298 | [ -f "$DVM_DIR/bash_completion" ] && . "$DVM_DIR/bash_completion" 299 | ``` 300 | 301 | ## License 302 | 303 | Distributed under the MIT License. See LICENSE file for more information. 304 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /bash_completion: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Shell completion for Deno Version Manager 3 | # Copyright (C) 2020 ~ 2025, Chen Su and all contributors. 4 | 5 | if ! type dvm &> /dev/null 6 | then 7 | return 8 | fi 9 | 10 | # Add available aliases into auto-completion options list. 11 | _dvm_add_aliases_to_opts() { 12 | if [ ! -d "$DVM_DIR/aliases" ] 13 | then 14 | return 15 | fi 16 | 17 | if [ -z "$(ls -A "$DVM_DIR/aliases")" ] 18 | then 19 | return 0 20 | fi 21 | 22 | for path in "$DVM_DIR/aliases"/* 23 | do 24 | alias_name=${path##*/} 25 | version=$(cat "$path") 26 | 27 | if [ -f "$DVM_DIR/versions/$version/deno" ] 28 | then 29 | opts="$opts $alias_name" 30 | fi 31 | done 32 | } 33 | 34 | # Add commands and top-level option (--help and --version) to options. 35 | _dvm_add_command_and_top_option() { 36 | if [[ ${cur} == -* ]] 37 | then 38 | opts="-h --help --version" 39 | else 40 | opts="alias clean current deactivate doctor help install list list-remote 41 | ls ls-remote run upgrade unalias uninstall use which" 42 | fi 43 | } 44 | 45 | # Add the specified options into the options list if no one was inputted. 46 | _dvm_add_exclusive_option() { 47 | if _dvm_no_option_input "${@}" 48 | then 49 | opts="$opts $*" 50 | fi 51 | } 52 | 53 | # Add options for command install. 54 | _dvm_add_install_option() { 55 | _dvm_add_exclusive_option "--from-binary" "--from-source" 56 | _dvm_add_options "--registry=" "--skip-validation" "--skip-download-cache" 57 | _dvm_add_options "--sha256sum" "--no-sha256sum" 58 | } 59 | 60 | # Add the specified option to the options list. 61 | _dvm_add_options() { 62 | for opt in "${@}" 63 | do 64 | if ! [[ ${COMP_WORDS[*]} =~ $opt ]] 65 | then 66 | opts="$opts $opt" 67 | fi 68 | done 69 | } 70 | 71 | # Add common options into auto-completion options list. 72 | _dvm_add_options_to_opts() { 73 | local prev 74 | 75 | prev="$1" 76 | 77 | if [ "$prev" == "run" ] 78 | then 79 | return 80 | fi 81 | 82 | if [[ ${cur} != -* ]] 83 | then 84 | return 85 | fi 86 | 87 | _dvm_add_exclusive_option "-q" "--quiet" 88 | _dvm_add_exclusive_option "--color" "--no-color" 89 | _dvm_add_options "--verbose" 90 | } 91 | 92 | # Add available installed versions into auto-completion options list. 93 | _dvm_add_versions_to_opts() { 94 | if [ ! -d "$DVM_DIR/versions" ] 95 | then 96 | return 97 | fi 98 | 99 | if [ -z "$(ls -A "$DVM_DIR/versions")" ] 100 | then 101 | return 0 102 | fi 103 | 104 | for path in "$DVM_DIR/versions"/* 105 | do 106 | if [ -f "$path/deno" ] 107 | then 108 | version=${path##*/} 109 | 110 | opts="$opts $version" 111 | fi 112 | done 113 | } 114 | 115 | # Set auto-completion with specific command. 116 | _dvm_completion() { 117 | local command 118 | local cur 119 | 120 | COMPREPLY=() 121 | cur="${COMP_WORDS[COMP_CWORD]}" 122 | 123 | if [ "$COMP_CWORD" = "1" ] 124 | then 125 | _dvm_add_command_and_top_option 126 | else 127 | command="${COMP_WORDS[1]}" 128 | 129 | case "$command" in 130 | "doctor") 131 | _dvm_add_exclusive_option "--fix" 132 | ;; 133 | "install") 134 | if [[ ${cur} == -* ]] 135 | then 136 | _dvm_add_install_option 137 | fi 138 | ;; 139 | "use"|"uninstall"|"which") 140 | if ! _dvm_has_non_option_parameter "$cur" 141 | then 142 | if [ "$command" = "which" ] && _dvm_has_active_version 143 | then 144 | opts="current" 145 | fi 146 | 147 | _dvm_add_versions_to_opts 148 | _dvm_add_aliases_to_opts 149 | fi 150 | ;; 151 | "run") 152 | if _dvm_has_non_option_parameter "$cur" 153 | then 154 | COMPREPLY=( "$(compgen -W "${opts}" -- "${cur}")" ) 155 | return 156 | fi 157 | 158 | _dvm_add_versions_to_opts 159 | _dvm_add_aliases_to_opts 160 | ;; 161 | "unalias") 162 | if [ "$COMP_CWORD" == "2" ] || ! _dvm_has_non_option_parameter "$cur" 163 | then 164 | _dvm_add_aliases_to_opts 165 | fi 166 | ;; 167 | *) 168 | opts="" 169 | ;; 170 | esac 171 | 172 | _dvm_add_options_to_opts "$prev" 173 | fi 174 | 175 | COMPREPLY=( "$(compgen -W "${opts}" -- "${cur}")" ) 176 | } 177 | 178 | # Check if any Deno version has been activated that installed by DVM. 179 | _dvm_has_active_version() { 180 | echo "$PATH" | grep -q "$DVM_DIR/versions" 181 | } 182 | 183 | # Checks whether the parameters list have non-option parameter or not. 184 | _dvm_has_non_option_parameter() { 185 | local cur 186 | cur="$1" 187 | 188 | for word in "${COMP_WORDS[@]:2}" 189 | do 190 | if [ "$word" == "" ] || [ "$word" == "$cur" ] 191 | then 192 | continue 193 | fi 194 | 195 | if [[ "$word" != -* ]] 196 | then 197 | true 198 | return 199 | fi 200 | done 201 | 202 | false 203 | } 204 | 205 | # Check whether the specified options are inputted or not 206 | _dvm_no_option_input() { 207 | for opt in "${@}" 208 | do 209 | if [[ ${COMP_WORDS[*]} =~ $opt ]] 210 | then 211 | false 212 | return 213 | fi 214 | done 215 | 216 | true 217 | } 218 | 219 | if [ -n "$ZSH_NAME" ] 220 | then 221 | autoload -U +X compinit && compinit 222 | autoload -U +X bashcompinit && bashcompinit 223 | fi 224 | 225 | complete -F _dvm_completion dvm 226 | -------------------------------------------------------------------------------- /dvm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Deno Version Manager 3 | # Copyright (C) 2020 ~ 2025, Chen Su and all contributors. 4 | # A lightweight, and powerful Deno version manager for MacOS, Linux, WSL, and 5 | # Windows with Bash. 6 | 7 | { # Ensure the integrality of this script 8 | 9 | export DVM_VERSION="v0.10.0" 10 | 11 | ###################### 12 | ## Helper Functions ## 13 | ###################### 14 | { 15 | ################ 16 | ## Environment ## 17 | ################ 18 | { 19 | # Check aliases directory, and try to create it if is not existed. 20 | dvm_check_alias_dir() { 21 | if [ ! -d "$DVM_DIR/aliases" ] 22 | then 23 | mkdir -p "$DVM_DIR/aliases" 24 | fi 25 | } 26 | 27 | # Gets user profile file path by the 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 or not. 45 | # Parameters: 46 | # $1: command to check. 47 | dvm_has() { 48 | command -v "$1" > /dev/null 49 | } 50 | 51 | # Set the environment variables to the 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 Deno path from the global environment variable `PATH` that added 79 | # by DVM. 80 | dvm_strip_path() { 81 | echo "$PATH" | tr ":" "\n" | grep -v "$DVM_DIR" | tr "\n" ":" 82 | } 83 | } 84 | 85 | ###################### 86 | ## Handle Parameter ## 87 | ###################### 88 | { 89 | # Check all parameters and try to match available options. 90 | dvm_parse_options() { 91 | while [ "$#" -gt "0" ] 92 | do 93 | case "$1" in 94 | "-q"|"--quiet") 95 | DVM_QUIET_MODE=true 96 | ;; 97 | "--color") 98 | DVM_COLOR_MODE=true 99 | ;; 100 | "--no-color") 101 | DVM_COLOR_MODE=false 102 | ;; 103 | "--verbose") 104 | DVM_VERBOSE_MODE=true 105 | ;; 106 | *) 107 | ;; 108 | esac 109 | 110 | shift 111 | done 112 | } 113 | } 114 | 115 | ########### 116 | ## Input ## 117 | ########### 118 | { 119 | # Print a prompt message, and get the confirm (yes or no) from the user 120 | # input. 121 | # Parameters: 122 | # $1: the prompt message. 123 | dvm_confirm_with_prompt() { 124 | local confirm 125 | local prompt 126 | 127 | if [ "$#" = 0 ] 128 | then 129 | return 130 | fi 131 | 132 | prompt="$1" 133 | echo -n "$prompt (y/n): " 134 | 135 | while true 136 | do 137 | read -r confirm 138 | 139 | case "$confirm" in 140 | [yY]*) 141 | return 0 142 | ;; 143 | [nN]*) 144 | return 1 145 | ;; 146 | *) 147 | ;; 148 | esac 149 | 150 | echo -n "Please type 'y' or 'n': " 151 | done 152 | } 153 | } 154 | 155 | ################### 156 | ## Network Tools ## 157 | ################### 158 | { 159 | # Download file from the specific url, and save the file to the specific 160 | # path. 161 | # Parameters: 162 | # - $1: downloading url. 163 | # - $2: the path of downloaded file. 164 | dvm_download_file() { 165 | local url 166 | local file 167 | local cmd 168 | local downloading_file 169 | 170 | url="$1" 171 | file="$2" 172 | downloading_file="$file.downloading" 173 | 174 | dvm_debug "downloading url: $url" 175 | dvm_debug "download destination file: $file" 176 | 177 | if dvm_has curl 178 | then 179 | cmd="curl -LJ $url -o $downloading_file" 180 | if [ "$DVM_QUIET_MODE" = true ] 181 | then 182 | cmd="$cmd -s" 183 | elif [ "$DVM_VERBOSE_MODE" = true ] 184 | then 185 | cmd="$cmd -v" 186 | fi 187 | else 188 | dvm_print_error "curl is required." 189 | dvm_failure 190 | return 191 | fi 192 | 193 | dvm_debug "download file command: $cmd" 194 | 195 | if ! eval "$cmd" 196 | then 197 | # remove failed download file 198 | rm -f "$downloading_file" 199 | dvm_failure 200 | return 201 | fi 202 | 203 | # rename the downloading file to the target file 204 | mv "$downloading_file" "$file" 205 | } 206 | 207 | # Send a GET request to the specific url, and save response to the 208 | # `DVM_REQUEST_RESPONSE` variable. 209 | # Parameters: 210 | # - $1: request url. 211 | # - $2...: options for curl. 212 | dvm_request() { 213 | local url 214 | 215 | # Clear response content. 216 | DVM_REQUEST_RESPONSE="" 217 | 218 | if ! dvm_has curl 219 | then 220 | dvm_print_error "curl is required" 221 | dvm_failure 222 | return 223 | fi 224 | 225 | url="$1" 226 | shift 227 | 228 | cmd="curl -s '$url' $*" 229 | 230 | if [ "$DVM_VERBOSE_MODE" = true ] 231 | then 232 | cmd="$cmd -v" 233 | fi 234 | 235 | if [ -n "$GITHUB_API_TOKEN" ] && [[ "$url" = "https://api.github.com/"* ]] 236 | then 237 | cmd="$cmd -H \"Authorization: Bearer $GITHUB_API_TOKEN\"" 238 | fi 239 | 240 | dvm_debug "request url: $url" 241 | dvm_debug "request command: $cmd" 242 | 243 | if ! DVM_REQUEST_RESPONSE=$(eval "$cmd") 244 | then 245 | dvm_failure 246 | return 247 | fi 248 | 249 | dvm_debug "request response: $DVM_REQUEST_RESPONSE" 250 | } 251 | } 252 | 253 | ############ 254 | ## Output ## 255 | ############ 256 | { 257 | # Print debug message in the verbose mode. 258 | # Parameters: 259 | # - $1...: the message to print. 260 | dvm_debug() { 261 | if [ "$DVM_VERBOSE_MODE" = true ] 262 | then 263 | echo -e "[DEBUG]" "$@" 264 | fi 265 | } 266 | 267 | # Print messages without quiet mode. 268 | # Parameters: 269 | # - $1...: the message to print. 270 | dvm_print() { 271 | if [ "$DVM_QUIET_MODE" = true ] 272 | then 273 | return 274 | fi 275 | 276 | echo -e "$@" 277 | } 278 | 279 | # Print error message with red color text. 280 | # Parameters: 281 | # $1...: the message to print. 282 | dvm_print_error() { 283 | dvm_print_with_color "31" "[ERR]" "$@" 284 | } 285 | 286 | # Print warning message with yellow color text. 287 | # Parameters: 288 | # $1...: the message to print. 289 | dvm_print_warning() { 290 | dvm_print_with_color "33" "[WARN]" "$@" 291 | } 292 | 293 | # Print message with the specific color. 294 | # Parameters: 295 | # - $1: the color code. 296 | # - $2...: the message to print. 297 | dvm_print_with_color() { 298 | local color="$1" 299 | 300 | shift 301 | 302 | if [ "$DVM_COLOR_MODE" = true ] && [ -n "$color" ] 303 | then 304 | dvm_print "\x1b[${color}m$*\x1b[0m" 305 | else 306 | dvm_print "$@" 307 | fi 308 | } 309 | } 310 | 311 | ################### 312 | ## Return Status ## 313 | ################### 314 | { 315 | # Set return status to true. 316 | dvm_success() { 317 | # execute true to set as success 318 | true 319 | } 320 | 321 | # Set return status to false. 322 | dvm_failure() { 323 | # execute false to set as fail 324 | false 325 | } 326 | } 327 | 328 | #################### 329 | ## Version Handle ## 330 | #################### 331 | { 332 | # Compare two version number. 333 | # Parameters: 334 | # $1, $2: the version number to compare. 335 | dvm_compare_version() { 336 | test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$2" 337 | } 338 | 339 | # Try to getting the active Deno version, and set it to `DVM_DENO_VERSION` 340 | # variable. 341 | dvm_get_current_version() { 342 | local deno_path 343 | local deno_dir 344 | 345 | if ! deno_path=$(which deno 2>/dev/null) 346 | then 347 | return 348 | fi 349 | 350 | if [[ "$deno_path" != "$DVM_DIR/versions/"* ]] 351 | then 352 | return 353 | fi 354 | 355 | deno_dir=${deno_path%/deno} 356 | 357 | DVM_DENO_VERSION=${deno_dir##*/} 358 | 359 | dvm_debug "active deno version: $DVM_DENO_VERSION" 360 | } 361 | 362 | # Try to get a Deno version from the parameters or the .dvmrc file (the 363 | # current directory or the user home directory). 364 | # Parameters: 365 | # $1...: the Deno version. 366 | dvm_get_version() { 367 | local result 368 | local prefix 369 | 370 | if ! dvm_get_version_by_param "$@" 371 | then 372 | dvm_get_version_from_dvmrc 373 | fi 374 | 375 | if [ -z "$DVM_TARGET_VERSION" ] 376 | then 377 | return 378 | fi 379 | 380 | if [[ "$DVM_TARGET_VERSION" != "v"* ]] 381 | then 382 | DVM_TARGET_VERSION="v$DVM_TARGET_VERSION" 383 | fi 384 | 385 | result=$(echo "$DVM_TARGET_VERSION" | grep -E "^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+") 386 | if [ -n "$result" ] 387 | then 388 | return 389 | fi 390 | 391 | dvm_debug "$DVM_TARGET_VERSION is a prefix" 392 | dvm_debug "try to get the latest version with the prefix $DVM_TARGET_VERSION" 393 | 394 | prefix="$DVM_TARGET_VERSION"\. 395 | DVM_TARGET_VERSION="" 396 | 397 | for version in "$DVM_DIR/versions"/* 398 | do 399 | if [[ "$version" == *"$prefix"* ]] 400 | then 401 | result=${version##*/} 402 | dvm_debug "version $result matched to the prefix $DVM_TARGET_VERSION" 403 | fi 404 | done 405 | 406 | if [ -z "$result" ] 407 | then 408 | dvm_print_error "no version found with the prefix $DVM_TARGET_VERSION" 409 | dvm_failure 410 | else 411 | dvm_debug "found the latest version $result with the prefix $DVM_TARGET_VERSION" 412 | DVM_TARGET_VERSION="$result" 413 | fi 414 | } 415 | 416 | # Try to get a valid and installed Deno version from the parameters. 417 | # Parameters: 418 | # $1...: the Deno version. 419 | dvm_get_version_by_param() { 420 | DVM_TARGET_VERSION="" 421 | 422 | while [[ "$1" == "-"* ]] 423 | do 424 | shift 425 | done 426 | 427 | if [ "$#" = "0" ] 428 | then 429 | return 1 430 | fi 431 | 432 | dvm_debug "try to get version by param: $1" 433 | 434 | if [ -f "$DVM_DIR/aliases/$1" ] 435 | then 436 | DVM_TARGET_VERSION=$(head -n 1 "$DVM_DIR/aliases/$1") 437 | 438 | if [ ! -f "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" ] 439 | then 440 | DVM_TARGET_VERSION="$1" 441 | fi 442 | else 443 | DVM_TARGET_VERSION="$1" 444 | fi 445 | } 446 | 447 | # Try to read version from .dvmrc file in the current working directory or 448 | # the user home directory. 449 | dvm_get_version_from_dvmrc() { 450 | if dvm_read_dvmrc_file "$PWD" ".dvmrc" || dvm_read_dvmrc_file "$PWD" ".deno-version" 451 | then 452 | return 0 453 | fi 454 | 455 | if [ "$PWD" != "$HOME" ] 456 | then 457 | if dvm_read_dvmrc_file "$HOME" ".dvmrc" || dvm_read_dvmrc_file "$HOME" ".deno-version" 458 | then 459 | return 0 460 | fi 461 | fi 462 | 463 | return 1 464 | } 465 | 466 | # Read .dvmrc or .deno-version file from the specified path, and set it to 467 | # `DVM_TARGET_VERSION` variable if the file is not empty. 468 | # Parameters: 469 | # - $1: path directory 470 | # - $2: file name 471 | dvm_read_dvmrc_file() { 472 | local version 473 | local file_dir="$1" 474 | local filename="$2" 475 | local file="$file_dir/$filename" 476 | 477 | if [ -f "$file" ] 478 | then 479 | dvm_debug "$file found" 480 | version=$(head -n 1 "$file") 481 | else 482 | dvm_debug "no $filename found in $file_dir" 483 | return 1 484 | fi 485 | 486 | if [ -n "$version" ] 487 | then 488 | dvm_print "Found '$file' with version $version" 489 | DVM_TARGET_VERSION="$version" 490 | return 0 491 | else 492 | dvm_debug "empty $filename file $file_dir" 493 | return 1 494 | fi 495 | } 496 | } 497 | } 498 | 499 | ################### 500 | ## Command alias ## 501 | ################### 502 | { 503 | # Set an alias to the specific Deno version, and it will overwrite if the 504 | # alias was created. 505 | # Parameters: 506 | # $1: the alias name to be set. 507 | # $2: the Deno version to alias. 508 | dvm_set_alias() { 509 | local alias_name 510 | local version 511 | 512 | dvm_check_alias_dir 513 | 514 | while [ "$#" -gt "0" ] 515 | do 516 | case "$1" in 517 | "-"*) 518 | ;; 519 | *) 520 | if [ -z "$alias_name" ] 521 | then 522 | alias_name="$1" 523 | elif [ -z "$version" ] 524 | then 525 | version="$1" 526 | fi 527 | esac 528 | 529 | shift 530 | done 531 | 532 | if [ -z "$alias_name" ] || [ -z "$version" ] 533 | then 534 | dvm_print_help 535 | dvm_failure 536 | return 537 | fi 538 | 539 | if [ ! -f "$DVM_DIR/versions/$version/deno" ] 540 | then 541 | dvm_print_error "deno $version is not installed." 542 | dvm_failure 543 | return 544 | fi 545 | 546 | echo "$version" > "$DVM_DIR/aliases/$alias_name" 547 | 548 | dvm_print "$alias_name -> $version" 549 | } 550 | } 551 | 552 | ################### 553 | ## Command clean ## 554 | ################### 555 | { 556 | # Remove version and download caches. 557 | dvm_clean_caches() { 558 | if [ -d "$DVM_DIR/cache" ] 559 | then 560 | rm -rf "$DVM_DIR/cache" 561 | fi 562 | 563 | dvm_clean_download_cache 564 | } 565 | 566 | # Clean downloading caches in the disk. 567 | dvm_clean_download_cache() { 568 | if [ ! -d "$DVM_DIR/download" ] 569 | then 570 | return 571 | fi 572 | 573 | if [ -z "$(ls -A "$DVM_DIR/download")" ] 574 | then 575 | return 576 | fi 577 | 578 | for cache_path in "$DVM_DIR/download"/* 579 | do 580 | if [ ! -d "$cache_path" ] 581 | then 582 | continue 583 | fi 584 | 585 | rm -rf "$cache_path" 586 | done 587 | } 588 | } 589 | 590 | ##################### 591 | ## Command current ## 592 | ##################### 593 | { 594 | # Gets the current Deno version and prints. It will print `system (vX.X.X)` 595 | # if Deno doesn't install by DVM. 596 | dvm_print_current_version() { 597 | local deno_version 598 | 599 | if ! dvm_has deno 600 | then 601 | dvm_print "none" 602 | return 603 | fi 604 | 605 | dvm_get_current_version 606 | 607 | if [ -n "$DVM_DENO_VERSION" ] 608 | then 609 | dvm_print "$DVM_DENO_VERSION" 610 | else 611 | deno_version=$(deno --version | grep "deno" | cut -d " " -f 2) 612 | dvm_print "system (v$deno_version)" 613 | fi 614 | } 615 | } 616 | 617 | ######################## 618 | ## Command deactivate ## 619 | ######################## 620 | { 621 | # Deactivate the active Deno version that added into the global environment 622 | # variable `PATH` by DVM 623 | dvm_deactivate() { 624 | local path_without_dvm 625 | 626 | dvm_get_current_version 627 | 628 | if [ -z "$DVM_DENO_VERSION" ] 629 | then 630 | dvm_success 631 | return 632 | fi 633 | 634 | path_without_dvm=$(dvm_strip_path) 635 | export PATH="$path_without_dvm" 636 | 637 | dvm_print "Deno has been deactivated, you can run \"dvm use $DVM_DENO_VERSION\" to restore it." 638 | 639 | unset DVM_DENO_VERSION 640 | } 641 | } 642 | 643 | #################### 644 | ## Command doctor ## 645 | #################### 646 | { 647 | # Scan the installed versions, and try to finding the invalid versions (the 648 | # versions from path and Deno `-v` option are not same). It'll try to fix the 649 | # invalid versions if it run in the `fix` mode. 650 | # Parameters: 651 | # $1: the mode of the doctor command. 652 | dvm_scan_and_fix_versions() { 653 | local mode 654 | local raw_output 655 | local invalid_message 656 | local corrupted_message 657 | local version 658 | local deno_version 659 | 660 | mode="$1" 661 | 662 | if [ ! -d "$DVM_DIR/versions" ] 663 | then 664 | return 665 | fi 666 | 667 | if [ -z "$(ls -A "$DVM_DIR/versions")" ] 668 | then 669 | return 670 | fi 671 | 672 | for version_path in "$DVM_DIR/versions/"* 673 | do 674 | if [ ! -f "$version_path/deno" ] 675 | then 676 | continue 677 | fi 678 | 679 | version=${version_path##*/} 680 | 681 | raw_output=$("$version_path/deno" --version 2>/dev/null) 682 | 683 | if [ -z "$raw_output" ] 684 | then 685 | corrupted_message="$corrupted_message$version\n" 686 | 687 | if [ "$mode" = "fix" ] 688 | then 689 | rm -rf "$version_path" 690 | fi 691 | else 692 | deno_version=$(echo "$raw_output" | grep deno | cut -d " " -f 2) 693 | 694 | if [ "$version" != "v$deno_version" ] 695 | then 696 | invalid_message="$invalid_message$version -> v$deno_version\n" 697 | 698 | if [ "$mode" = "fix" ] 699 | then 700 | mkdir -p "$DVM_DIR/doctor_temp" 701 | mv -f "$version_path" "$DVM_DIR/doctor_temp/v$deno_version" 702 | fi 703 | fi 704 | fi 705 | done 706 | 707 | if [ "$mode" = "fix" ] 708 | then 709 | dvm_fix_invalid_versions 710 | else 711 | dvm_print_doctor_message "$invalid_message" "$corrupted_message" 712 | fi 713 | } 714 | 715 | # Try to moving the Deno files to the correct path, and remove it if the 716 | # version was existed. 717 | dvm_fix_invalid_versions() { 718 | local version 719 | 720 | if [ ! -d "$DVM_DIR/doctor_temp" ] 721 | then 722 | return 723 | fi 724 | 725 | for version_path in "$DVM_DIR/doctor_temp/"* 726 | do 727 | version=${version_path##*/} 728 | 729 | if [ -d "$DVM_DIR/versions/$version" ] 730 | then 731 | rm -rf "$version_path" 732 | else 733 | mv "$version_path" "$DVM_DIR/versions/$version" 734 | fi 735 | done 736 | 737 | rmdir "$DVM_DIR/doctor_temp" 738 | 739 | dvm_print "Invalid version(s) has been fixed." 740 | } 741 | 742 | # Print the invalid (versions from file and path are not same) and the 743 | # corrupted (unable to run) versions. 744 | # Parameters: 745 | # $1: invalid versions list. 746 | # $2: corrupted versions list. 747 | dvm_print_doctor_message() { 748 | local invalid_message 749 | local corrupted_message 750 | 751 | invalid_message="$1" 752 | corrupted_message="$2" 753 | 754 | if [ -z "$invalid_message" ] && [ -z "$corrupted_message" ] 755 | then 756 | dvm_print "Everything is ok." 757 | return 758 | fi 759 | 760 | if [ -n "$invalid_message" ] 761 | then 762 | dvm_print "Invalid versions:" 763 | dvm_print "$invalid_message" 764 | fi 765 | 766 | if [ -n "$corrupted_message" ] 767 | then 768 | dvm_print "Corrupted versions:" 769 | dvm_print "$corrupted_message" 770 | fi 771 | 772 | dvm_print "You can run \"dvm doctor --fix\" to fix these errors." 773 | } 774 | } 775 | 776 | ################## 777 | ## Command help ## 778 | ################## 779 | { 780 | # Print help messages. 781 | dvm_print_help() { 782 | dvm_print 783 | dvm_print "Deno Version Manager" 784 | dvm_print 785 | dvm_print "Usage:" 786 | dvm_print " dvm install [version | prefix] Download and install by version or the prefix. Install latest or use .dvmrc file if version is omitted." 787 | dvm_print " --registry= Download and install deno with the specified registry." 788 | dvm_print " --skip-validation Skip version validation before download." 789 | dvm_print " --skip-download-cache Don't use downloaded cache file." 790 | dvm_print " dvm uninstall [name|version] Uninstall a specified version." 791 | dvm_print " dvm use [name|version] Use the specified version that passed by argument or read from .dvmrc." 792 | dvm_print " dvm run [args] Run deno on the specified version with arguments." 793 | dvm_print " dvm alias Set an alias name to specified version." 794 | dvm_print " dvm unalias Delete the specified alias name." 795 | dvm_print " dvm current Display the current version of Deno." 796 | dvm_print " dvm ls List all installed versions." 797 | dvm_print " dvm ls-remote List all remote versions." 798 | dvm_print " dvm which [current|name|version] Display the path of installed version." 799 | dvm_print " dvm clean Remove all downloaded packages and cached versions." 800 | dvm_print " dvm deactivate Deactivate Deno on current shell." 801 | dvm_print " dvm doctor Scan installed versions and find invalid / corrupted versions." 802 | dvm_print " --fix Scan and fix all invalid / corrupted versions." 803 | dvm_print " dvm upgrade Upgrade dvm itself." 804 | dvm_print " dvm purge Remove dvm from your computer." 805 | dvm_print " dvm help Show this message." 806 | dvm_print 807 | dvm_print "Options:" 808 | dvm_print " -q, --quiet Make outputs more quiet." 809 | dvm_print " --color Print colorful messages." 810 | dvm_print " --no-color Print messages without color." 811 | dvm_print " --verbose Run in verbose mode, it'll print debug messages." 812 | dvm_print 813 | dvm_print "Note:" 814 | dvm_print " is required parameter, [param] is optional parameter." 815 | dvm_print 816 | dvm_print "Examples:" 817 | dvm_print " dvm install v1.0.0" 818 | dvm_print " dvm uninstall v0.42.0" 819 | dvm_print " dvm use v1.0.0" 820 | dvm_print " dvm alias default v1.0.0" 821 | dvm_print " dvm run v1.0.0 app.ts" 822 | dvm_print 823 | } 824 | } 825 | 826 | ##################### 827 | ## Command install ## 828 | ##################### 829 | { 830 | # Try to build the binary file of Deno with the specified version, and move 831 | # the build target file to the versions directory. 832 | # Parameters: 833 | # - $1: The Deno version to building. 834 | dvm_build_deno() { 835 | local version 836 | version="$1" 837 | 838 | old_dir=$(pwd) 839 | cd "$DVM_DIR/deno_code" || return 840 | 841 | git reset --hard HEAD 842 | if ! git checkout "$version" --recurse-submodules 843 | then 844 | dvm_failure 845 | return 846 | fi 847 | 848 | cargo clean 849 | 850 | if ! cargo build --release 851 | then 852 | dvm_print_error "failed to build deno" 853 | cd "$old_dir" || return 854 | dvm_failure 855 | return 856 | fi 857 | 858 | if ! dvm_validate_build_target "$version" 859 | then 860 | cd "$old_dir" || return 861 | dvm_failure 862 | return 863 | elif ! dvm_copy_build_target_to_versions_dir "$version" 864 | then 865 | cd "$old_dir" || return 866 | dvm_failure 867 | return 868 | else 869 | cargo clean 870 | cd "$old_dir" || return 871 | fi 872 | } 873 | 874 | # Check the dependencies for building Deno from the source code. 875 | dvm_check_build_dependencies() { 876 | for command in git rustc cargo cc cmake 877 | do 878 | if ! dvm_has "$command" 879 | then 880 | dvm_print_error "$command is required" 881 | dvm_failure 882 | return 883 | fi 884 | done 885 | } 886 | 887 | # Try to check the local clone of the source code, and fetch the latest data 888 | # if the local clone is valid. It will delete the source code directory and 889 | # clone it again later if the directory is not the repo of the Deno source 890 | # code. 891 | dvm_check_local_deno_clone() { 892 | local old_dir 893 | 894 | old_dir=$(pwd) 895 | cd "$DVM_DIR/deno_code" || return 896 | 897 | ret=$(git remote -v | grep "deno.git") 898 | if [ -z "$ret" ] 899 | then 900 | dvm_print_warning "The local clone of Deno source is invalid, trying to re-clone..." 901 | rm -rf "$DVM_DIR/deno_code" 902 | 903 | cd "$old_dir" || return 904 | dvm_failure 905 | else 906 | # update repo 907 | git fetch 908 | 909 | cd "$old_dir" || return 910 | fi 911 | } 912 | 913 | # Clone the source code of Deno into the local directory, and update the 914 | # local clone if it was cloned. 915 | dvm_clone_deno_source() { 916 | if [ -d "$DVM_DIR/deno_code" ] 917 | then 918 | if dvm_check_local_deno_clone 919 | then 920 | return 921 | fi 922 | fi 923 | 924 | git clone --recurse-submodules https://github.com/denoland/deno.git "$DVM_DIR/deno_code" 925 | } 926 | 927 | # Move the build output file to the versions file. 928 | # Parameters: 929 | # - $1: The Deno version to install. 930 | dvm_copy_build_target_to_versions_dir() { 931 | local version 932 | 933 | version="$1" 934 | 935 | if ! [ -d "$DVM_DIR/versions/$version" ] 936 | then 937 | mkdir -p "$DVM_DIR/versions/$version" 938 | fi 939 | 940 | cp "$DVM_DIR/deno_code/target/release/deno" "$DVM_DIR/versions/$version" 941 | } 942 | 943 | # Download Deno with the specific version from GitHub or the specific 944 | # registry (specify by `DVM_INSTALL_REGISTRY` variable). It will download 945 | # Deno to the cache directory, and move it to versions directory after 946 | # completed. 947 | # Parameters: 948 | # - $1: the Deno version to download. 949 | dvm_download_deno() { 950 | local version 951 | local url 952 | local temp_file 953 | local registry 954 | 955 | version="$1" 956 | 957 | if [ ! -d "$DVM_DIR/download/$version" ] 958 | then 959 | mkdir -p "$DVM_DIR/download/$version" 960 | fi 961 | 962 | if [ -z "$DVM_INSTALL_REGISTRY" ] 963 | then 964 | if ! [[ "$version" < "v1.0.1" ]] || [[ "$version" = "v1.0.0" ]] 965 | then 966 | registry="https://dl.deno.land/release" 967 | else 968 | registry="https://github.com/denoland/deno/releases/download" 969 | fi 970 | else 971 | registry="$DVM_INSTALL_REGISTRY" 972 | fi 973 | 974 | dvm_debug "registry url: $registry" 975 | 976 | url="$registry/$version/$DVM_TARGET_NAME" 977 | temp_file="$DVM_DIR/download/$version/$DVM_TARGET_NAME" 978 | 979 | if dvm_download_file "$url" "$temp_file" 980 | then 981 | if dvm_validate_download_file "$version" "$url" 982 | then 983 | return 984 | fi 985 | fi 986 | 987 | if [ -f "$temp_file" ] 988 | then 989 | rm "$temp_file" 990 | fi 991 | 992 | dvm_print_error "failed to download deno $version." 993 | dvm_failure 994 | } 995 | 996 | # Extract the Deno compressed file, and add execute permission to the binary 997 | # file. 998 | dvm_extract_file() { 999 | local target_dir 1000 | 1001 | target_dir="$DVM_DIR/versions/$1" 1002 | 1003 | dvm_debug "extracting source file: $DVM_DIR/download/$1/deno.$DVM_TARGET_TYPE" 1004 | dvm_debug "extracting target path: $target_dir" 1005 | 1006 | if [ ! -d "$target_dir" ] 1007 | then 1008 | mkdir -p "$target_dir" 1009 | fi 1010 | 1011 | case $DVM_TARGET_TYPE in 1012 | "zip") 1013 | if dvm_has unzip 1014 | then 1015 | unzip "$DVM_DIR/download/$1/deno.zip" -d "$target_dir" > /dev/null 1016 | elif [ "$DVM_TARGET_OS" = "Linux" ] && dvm_has gunzip 1017 | then 1018 | gunzip -c "$DVM_DIR/download/$1/deno.zip" > "$target_dir/deno" 1019 | chmod +x "$target_dir/deno" 1020 | else 1021 | dvm_print_error "unzip is required." 1022 | dvm_failure 1023 | fi 1024 | ;; 1025 | "gz") 1026 | if dvm_has gunzip 1027 | then 1028 | gunzip -c "$DVM_DIR/download/$1/deno.gz" > "$target_dir/deno" 1029 | chmod +x "$target_dir/deno" 1030 | else 1031 | dvm_print_error "gunzip is required." 1032 | dvm_failure 1033 | fi 1034 | ;; 1035 | *) 1036 | ;; 1037 | esac 1038 | } 1039 | 1040 | # Calls GitHub api to getting deno latest release tag name. 1041 | dvm_get_latest_version() { 1042 | # the url of github api 1043 | local latest_url 1044 | # the latest release tag name 1045 | local tag_name 1046 | 1047 | dvm_print "\ntry to getting deno latest version ..." 1048 | 1049 | latest_url="https://dl.deno.land/release-latest.txt" 1050 | 1051 | if ! dvm_request "$latest_url" 1052 | then 1053 | dvm_print_error "failed to getting deno latest version." 1054 | dvm_failure 1055 | return 1056 | fi 1057 | 1058 | tag_name="$DVM_REQUEST_RESPONSE" 1059 | 1060 | if [ -z "$tag_name" ] 1061 | then 1062 | dvm_print_error "failed to getting deno latest version." 1063 | dvm_failure 1064 | return 1065 | fi 1066 | 1067 | dvm_print "Found deno latest version $tag_name" 1068 | 1069 | DVM_TARGET_VERSION="$tag_name" 1070 | DVM_INSTALL_SKIP_VALIDATION=true 1071 | } 1072 | 1073 | # Get remote package name by host os and architecture. 1074 | # Parameters: 1075 | # - $1: the deno version to install. 1076 | dvm_get_package_data() { 1077 | local target_version 1078 | 1079 | DVM_TARGET_OS=$(uname -s) 1080 | DVM_TARGET_ARCH=$(uname -m) 1081 | target_version="$1" 1082 | 1083 | dvm_debug "target os: $DVM_TARGET_OS" 1084 | dvm_debug "target arch: $DVM_TARGET_ARCH" 1085 | dvm_debug "target deno version: $target_version" 1086 | 1087 | if [ "$DVM_TARGET_OS" = "Darwin" ] && 1088 | [ "$DVM_TARGET_ARCH" = 'arm64' ] && 1089 | dvm_compare_version "$target_version" "v1.6.0" 1090 | then 1091 | dvm_print_error "Mac with M-series chips (aarch64-darwin) support deno v1.6.0 and above versions only." 1092 | dvm_failure 1093 | return 1094 | fi 1095 | 1096 | if [ "$DVM_TARGET_OS" = "Linux" ] && 1097 | [ "$DVM_TARGET_ARCH" = 'arm64' ] && 1098 | dvm_compare_version "$target_version" "v1.40.3" 1099 | then 1100 | dvm_print_error "Linux with ARM64 chips (aarch64-linux) support deno v1.40.3 and above versions only." 1101 | dvm_failure 1102 | return 1103 | fi 1104 | 1105 | if dvm_compare_version "$target_version" "v0.36.0" 1106 | then 1107 | DVM_TARGET_TYPE="gz" 1108 | else 1109 | DVM_TARGET_TYPE="zip" 1110 | fi 1111 | 1112 | dvm_debug "target file type: $DVM_TARGET_TYPE" 1113 | 1114 | case "$DVM_TARGET_OS:$DVM_TARGET_ARCH:$DVM_TARGET_TYPE" in 1115 | "Darwin:x86_64:gz") 1116 | DVM_TARGET_NAME='deno_osx_x64.gz' 1117 | ;; 1118 | "Linux:x86_64:gz") 1119 | DVM_TARGET_NAME='deno_linux_x64.gz' 1120 | ;; 1121 | "Darwin:x86_64:zip") 1122 | DVM_TARGET_NAME='deno-x86_64-apple-darwin.zip' 1123 | ;; 1124 | "Darwin:arm64:zip") 1125 | DVM_TARGET_NAME='deno-aarch64-apple-darwin.zip' 1126 | ;; 1127 | "Linux:x86_64:zip") 1128 | DVM_TARGET_NAME='deno-x86_64-unknown-linux-gnu.zip' 1129 | ;; 1130 | "Linux:aarch64:zip") 1131 | DVM_TARGET_NAME='deno-aarch64-unknown-linux-gnu.zip' 1132 | ;; 1133 | *"NT"*":x86_64:zip") 1134 | DVM_TARGET_NAME='deno-x86_64-pc-windows-msvc.zip' 1135 | ;; 1136 | *) 1137 | dvm_print_error "unsupported operating system $DVM_TARGET_OS ($DVM_TARGET_ARCH)." 1138 | dvm_failure 1139 | return 1140 | ;; 1141 | esac 1142 | 1143 | dvm_debug "target file name: $DVM_TARGET_NAME" 1144 | } 1145 | 1146 | # Gets the latest version with the prefix. 1147 | # Parameters: 1148 | # - $1: the version prefix to search. 1149 | dvm_get_remote_version_by_prefix() { 1150 | local search_text 1151 | local version_prefix 1152 | local tmp_versions 1153 | 1154 | search_text="$1" 1155 | version_prefix="$search_text" 1156 | 1157 | dvm_debug "searching version starts with $version_prefix" 1158 | 1159 | if [[ "$version_prefix" == *"." ]] 1160 | then 1161 | version_prefix="${version_prefix%%.}" 1162 | fi 1163 | version_prefix="$version_prefix\." 1164 | 1165 | dvm_debug "searching version prefix: $version_prefix" 1166 | 1167 | if ! dvm_get_remote_versions 1168 | then 1169 | dvm_failure 1170 | return 1171 | fi 1172 | 1173 | tmp_versions=$(echo "$DVM_REMOTE_VERSIONS" | grep -E "$version_prefix" | tail -n 1) 1174 | if [ -z "$tmp_versions" ] 1175 | then 1176 | dvm_print_error "no version found by $search_text" 1177 | dvm_failure 1178 | return 1179 | fi 1180 | 1181 | dvm_debug "matched version found $tmp_versions" 1182 | DVM_TARGET_VERSION="$tmp_versions" 1183 | DVM_INSTALL_SKIP_VALIDATION=true 1184 | } 1185 | 1186 | # Install Deno with the specific version, it'll try to get version from the 1187 | # parameter, .dvmrc file (current directory and home directory), or the 1188 | # latest Deno version. 1189 | # Parameters: 1190 | # - $1: the Deno version to install. (Optional) 1191 | dvm_install_version() { 1192 | local version 1193 | 1194 | version="$1" 1195 | 1196 | if [ -z "$version" ] 1197 | then 1198 | if ! dvm_get_version_from_dvmrc && ! dvm_get_latest_version 1199 | then 1200 | return 1201 | fi 1202 | else 1203 | if ! dvm_is_version_prefix "$version" 1204 | then 1205 | return 1206 | fi 1207 | fi 1208 | version="$DVM_TARGET_VERSION" 1209 | 1210 | if [ -f "$DVM_DIR/versions/$version/deno" ] 1211 | then 1212 | dvm_print "Deno $version has been installed." 1213 | dvm_success 1214 | return 1215 | fi 1216 | 1217 | if [ "$DVM_INSTALL_SKIP_VALIDATION" = false ] 1218 | then 1219 | if ! dvm_validate_remote_version "$version" 1220 | then 1221 | return 1222 | fi 1223 | fi 1224 | 1225 | if [[ "$version" != "v"* ]] 1226 | then 1227 | version="v$version" 1228 | fi 1229 | 1230 | if ! dvm_install_deno "$version" 1231 | then 1232 | dvm_failure 1233 | return 1234 | fi 1235 | 1236 | dvm_print "Deno $version has installed." 1237 | 1238 | dvm_use_version "$version" 1239 | dvm_set_default_alias_after_install "$version" 1240 | } 1241 | 1242 | # Try to install Deno from the network with the binary file, or try to build 1243 | # Deno from the source code. 1244 | # Parameters: 1245 | # - $1: The Deno version to install. 1246 | dvm_install_deno() { 1247 | local version 1248 | 1249 | version="$1" 1250 | 1251 | case "$DVM_INSTALL_MODE" in 1252 | "binary") 1253 | if ! dvm_install_deno_by_binary "$version" 1254 | then 1255 | dvm_failure 1256 | return 1257 | fi 1258 | ;; 1259 | "source") 1260 | if ! dvm_install_deno_by_source "$version" 1261 | then 1262 | dvm_failure 1263 | return 1264 | fi 1265 | ;; 1266 | *) 1267 | dvm_print_error "Unknown install mode: $DVM_INSTALL_MODE" 1268 | dvm_failure 1269 | ;; 1270 | esac 1271 | } 1272 | 1273 | # Download and install the pre-compiled Deno binary file from the network. 1274 | # Parameters: 1275 | # - $1: The Deno version to install. 1276 | dvm_install_deno_by_binary() { 1277 | local version 1278 | 1279 | version="$1" 1280 | 1281 | if ! dvm_get_package_data "$version" 1282 | then 1283 | dvm_failure 1284 | return 1285 | fi 1286 | 1287 | if [ "$DVM_INSTALL_SKIP_CACHE" = true ] || [ ! -f "$DVM_DIR/download/$version/deno.$DVM_TARGET_TYPE" ] 1288 | then 1289 | dvm_print "Downloading and installing deno $version..." 1290 | if ! dvm_download_deno "$version" 1291 | then 1292 | dvm_failure 1293 | return 1294 | fi 1295 | else 1296 | dvm_print "Installing deno $version from cache..." 1297 | fi 1298 | 1299 | dvm_extract_file "$version" 1300 | } 1301 | 1302 | # Download the source code of Deno from the network, and try to building the 1303 | # binary file. 1304 | # Parameters: 1305 | # - $1: The Deno version to install. 1306 | dvm_install_deno_by_source() { 1307 | local version 1308 | version="$1" 1309 | 1310 | if ! dvm_check_build_dependencies 1311 | then 1312 | dvm_failure 1313 | return 1314 | fi 1315 | 1316 | if ! dvm_clone_deno_source 1317 | then 1318 | dvm_failure 1319 | return 1320 | fi 1321 | 1322 | dvm_build_deno "$version" 1323 | } 1324 | 1325 | # Check the version string whether it is a prefix or not. 1326 | # Parameters: 1327 | # - $1: the string to check. 1328 | dvm_is_version_prefix() { 1329 | local result 1330 | local version 1331 | 1332 | version="$1" 1333 | if [[ "$version" != "v"* ]] 1334 | then 1335 | version="v$version" 1336 | fi 1337 | 1338 | result=$(echo "$version" | grep -E "^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+") 1339 | if [ -z "$result" ] 1340 | then 1341 | dvm_debug "$version is a version prefix" 1342 | if ! dvm_get_remote_version_by_prefix "$version" 1343 | then 1344 | dvm_failure 1345 | return 1346 | fi 1347 | else 1348 | dvm_debug "$version is not a version prefix" 1349 | DVM_TARGET_VERSION="$version" 1350 | fi 1351 | } 1352 | 1353 | # Try to set the installed version as the alias 'default' if no default set. 1354 | # Parameters: 1355 | # - $1: the Deno version to set to default. 1356 | dvm_set_default_alias_after_install() { 1357 | local version="$1" 1358 | 1359 | dvm_check_alias_dir 1360 | 1361 | if [ -f "$DVM_DIR/aliases/default" ] 1362 | then 1363 | return 1364 | fi 1365 | 1366 | echo "$version" > "$DVM_DIR/aliases/default" 1367 | dvm_print "Creating default alias: default -> $version" 1368 | } 1369 | 1370 | # Try to validate the build output file. 1371 | # Parameters: 1372 | # - $1: The Deno version to install. 1373 | dvm_validate_build_target() { 1374 | local version 1375 | local target_version 1376 | 1377 | target_version="$1" 1378 | 1379 | if ! [ -f "$DVM_DIR/deno_code/target/release/deno" ] 1380 | then 1381 | dvm_print_error "no output found." 1382 | dvm_failure 1383 | return 1384 | fi 1385 | 1386 | version=$("$DVM_DIR/deno_code/target/release/deno" --version | grep deno | cut -d " " -f 2) 1387 | if [ "v$version" != "$target_version" ] 1388 | then 1389 | dvm_print_error "unmatched build target version v$version" 1390 | dvm_debug "build file version: v$version" 1391 | dvm_debug "target version: $version" 1392 | dvm_failure 1393 | return 1394 | fi 1395 | } 1396 | 1397 | # Validate the downloaded file, and move it to the versions directory if the 1398 | # file is valid. 1399 | # Parameters: 1400 | # - $1: The Deno version to install. 1401 | dvm_validate_download_file() { 1402 | local version 1403 | local download_url 1404 | local download_file 1405 | local sha256sum_url 1406 | local sha256sum_file 1407 | local checksum 1408 | local checksum_expected 1409 | 1410 | version="$1" 1411 | download_url="$2" 1412 | 1413 | download_file="$DVM_DIR/download/$version/$DVM_TARGET_NAME" 1414 | sha256sum_url="$download_url.sha256sum" 1415 | sha256sum_file="$download_file.sha256sum" 1416 | 1417 | if [ "$DVM_INSTALL_SHA256SUM" = true ] && 1418 | dvm_has shasum && 1419 | ! dvm_compare_version "$version" "v2.0.1" 1420 | then 1421 | dvm_debug "downloading sha256sum file: $sha256sum_url" 1422 | 1423 | if ! dvm_download_file "$sha256sum_url" "$sha256sum_file" 1424 | then 1425 | dvm_print_error "failed to download sha256 file." 1426 | dvm_failure 1427 | return 1428 | fi 1429 | 1430 | dvm_print "Computing checksum with sha256sum..." 1431 | checksum=$(shasum -a 256 "$download_file" | cut -d " " -f 1) 1432 | checksum_expected=$(cut -d " " -f 1 < "$sha256sum_file" ) 1433 | dvm_debug "checksum: $checksum, expected checksum: $checksum_expected" 1434 | 1435 | if [ "$checksum" != "$checksum_expected" ] 1436 | then 1437 | dvm_print_error "Checksums failed." 1438 | dvm_failure 1439 | return 1440 | fi 1441 | 1442 | dvm_print "Checksums matched!" 1443 | rm "$sha256sum_file" 1444 | fi 1445 | 1446 | mv "$download_file" "$DVM_DIR/download/$version/deno.$DVM_TARGET_TYPE" 1447 | } 1448 | 1449 | # Get remote data by GitHub api (Get a release by tag name) to validate the 1450 | # version from the parameter. 1451 | # Parameters: 1452 | # - $1: the version to validate. 1453 | dvm_validate_remote_version() { 1454 | local version 1455 | local target_version 1456 | # GitHub get release by tag name api url 1457 | local tag_url 1458 | 1459 | version="$1" 1460 | 1461 | if [[ "$version" != "v"* ]] 1462 | then 1463 | target_version="v$version" 1464 | else 1465 | target_version="$version" 1466 | fi 1467 | 1468 | dvm_debug "validation target deno version: $version" 1469 | 1470 | if [ -f "$DVM_DIR/cache/remote-versions" ] 1471 | then 1472 | dvm_debug "remote versions cache found, try to validate version $version" 1473 | if grep "$target_version" < "$DVM_DIR/cache/remote-versions" > /dev/null 1474 | then 1475 | dvm_debug "version $version found in cache" 1476 | return 1477 | fi 1478 | dvm_debug "no version $version found in cache, try to validate from network" 1479 | fi 1480 | 1481 | tag_url="https://api.github.com/repos/denoland/deno/releases/tags/$target_version" 1482 | 1483 | if ! dvm_request "$tag_url" 1484 | then 1485 | dvm_print_warning "failed to validating deno version." 1486 | fi 1487 | 1488 | tag_name=$(echo "$DVM_REQUEST_RESPONSE" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 1489 | 1490 | if [ -z "$tag_name" ] 1491 | then 1492 | if echo "$DVM_REQUEST_RESPONSE" | grep "Not Found" > /dev/null 1493 | then 1494 | dvm_print_error "deno '$version' not found, use 'ls-remote' command to get available versions." 1495 | dvm_failure 1496 | else 1497 | dvm_print_warning "failed to validating deno version." 1498 | dvm_debug "validation response: $DVM_REQUEST_RESPONSE" 1499 | fi 1500 | fi 1501 | } 1502 | } 1503 | 1504 | ################## 1505 | ## Command list ## 1506 | ################## 1507 | { 1508 | # List all aliases and get the version of the alias name. 1509 | dvm_list_aliases() { 1510 | local aliased_version 1511 | 1512 | if [ ! -d "$DVM_DIR/aliases" ] 1513 | then 1514 | return 1515 | fi 1516 | 1517 | if [ -z "$(ls -A "$DVM_DIR/aliases")" ] 1518 | then 1519 | return 1520 | fi 1521 | 1522 | for alias_path in "$DVM_DIR/aliases"/* 1523 | do 1524 | if [ ! -f "$alias_path" ] 1525 | then 1526 | continue; 1527 | fi 1528 | 1529 | alias_name=${alias_path##*/} 1530 | aliased_version=$(head -n 1 "$alias_path") 1531 | 1532 | if [ -z "$aliased_version" ] || 1533 | [ ! -f "$DVM_DIR/versions/$aliased_version/deno" ] 1534 | then 1535 | dvm_print "$alias_name -> N/A" 1536 | else 1537 | dvm_print "$alias_name -> $aliased_version" 1538 | fi 1539 | done 1540 | } 1541 | 1542 | # List all Deno versions that have been installed. 1543 | dvm_list_local_versions() { 1544 | local version 1545 | 1546 | if [ ! -d "$DVM_DIR/versions" ] 1547 | then 1548 | return 1549 | fi 1550 | 1551 | if [ -z "$(ls -A "$DVM_DIR/versions")" ] 1552 | then 1553 | return 1554 | fi 1555 | 1556 | for dir in "$DVM_DIR/versions"/* 1557 | do 1558 | if [ ! -f "$dir/deno" ] 1559 | then 1560 | continue 1561 | fi 1562 | 1563 | version=${dir##*/} 1564 | 1565 | if [ "$version" = "$DVM_DENO_VERSION" ] 1566 | then 1567 | dvm_print_with_color "32" "-> $version" 1568 | else 1569 | dvm_print " $version" 1570 | fi 1571 | done 1572 | } 1573 | } 1574 | 1575 | ####################### 1576 | ## Command ls-remote ## 1577 | ####################### 1578 | { 1579 | # Try to get all remote version from the local cache or the remote server. 1580 | dvm_get_remote_versions() { 1581 | local last_version 1582 | local cache_file 1583 | local legacy_versions 1584 | 1585 | # deno.com/versions.json does not provide the versions before v1.0.0, so we put these version 1586 | # into the static legacy versions file. 1587 | if [ -f "$DVM_DIR/legacy-versions" ] && dvm_get_versions_from_deno_versions_json 1588 | then 1589 | legacy_versions=$(cat "$DVM_DIR/legacy-versions") 1590 | DVM_REMOTE_VERSIONS=$(echo -e "$legacy_versions\n$DVM_REMOTE_VERSIONS") 1591 | return 1592 | fi 1593 | 1594 | dvm_debug "Failed to get Deno versions from deno.com/versions.json, fallback to GitHub API" 1595 | 1596 | cache_file="$DVM_DIR/cache/remote-versions" 1597 | 1598 | if [ ! -d "$DVM_DIR/cache" ] 1599 | then 1600 | mkdir "$DVM_DIR/cache" 1601 | fi 1602 | 1603 | if [ -f "$cache_file" ] && [ "$(head -n 1 "$cache_file")" = "v0.1.0" ] 1604 | then 1605 | if [ "$(find "$cache_file" -mmin -15 2>/dev/null)" ] 1606 | then 1607 | DVM_REMOTE_VERSIONS="$(cat "$cache_file")" 1608 | dvm_debug "remote versions cache found" 1609 | return 1610 | else 1611 | last_version="$(tail -n 1 "$cache_file")" 1612 | if [ -n "$last_version" ] 1613 | then 1614 | if ! dvm_get_latest_version 1615 | then 1616 | return 1617 | fi 1618 | 1619 | dvm_debug "last version in cache: $last_version" 1620 | dvm_debug "latest version from network: $DVM_TARGET_VERSION" 1621 | 1622 | if [ "$last_version" = "$DVM_TARGET_VERSION" ] 1623 | then 1624 | DVM_REMOTE_VERSIONS="$(cat "$cache_file")" 1625 | return 1626 | fi 1627 | fi 1628 | fi 1629 | else 1630 | dvm_debug "remote versions cache not found or it's invalid" 1631 | rm -rf "$cache_file" 1632 | fi 1633 | 1634 | if ! dvm_get_versions_from_network "$last_version" 1635 | then 1636 | dvm_failure 1637 | return 1638 | fi 1639 | 1640 | echo "$DVM_REMOTE_VERSIONS" >> "$cache_file" 1641 | 1642 | # re-read the full remote versions 1643 | DVM_REMOTE_VERSIONS=$(cat "$cache_file") 1644 | } 1645 | 1646 | # Call https://deno.com/versions.json to getting all stable versions. 1647 | dvm_get_versions_from_deno_versions_json() { 1648 | local versions 1649 | 1650 | dvm_debug "getting versions from deno.com/versions.json" 1651 | 1652 | if ! dvm_request "https://deno.com/versions.json" 1653 | then 1654 | dvm_print_error "failed to list remote versions from deno.com." 1655 | dvm_failure 1656 | return 1657 | fi 1658 | 1659 | versions=${DVM_REQUEST_RESPONSE#*cli} 1660 | DVM_REMOTE_VERSIONS=$(echo "$versions" | sed 's/"/\n/g' | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$" | sort -V) 1661 | } 1662 | 1663 | # Call GitHub API to getting all versions (release tag names) from the 1664 | # Deno repo. 1665 | # Parameters: 1666 | # - $1: the last version that already fetched (optional). 1667 | dvm_get_versions_from_network() { 1668 | local request_url 1669 | local all_versions 1670 | local size 1671 | local tmp_versions 1672 | local expect_version 1673 | 1674 | if [ "$#" != "0" ] && [ -n "$1" ] 1675 | then 1676 | expect_version="$1" 1677 | fi 1678 | 1679 | size=100 1680 | request_url="https://api.github.com/repos/denoland/deno/releases?per_page=$size&page=1" 1681 | 1682 | while [ "$request_url" != "" ] 1683 | do 1684 | if ! dvm_request "$request_url" "--include" 1685 | then 1686 | dvm_print_error "failed to list remote versions." 1687 | dvm_failure 1688 | return 1689 | fi 1690 | 1691 | tmp_versions=$(echo "$DVM_REQUEST_RESPONSE" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 1692 | all_versions="$all_versions\n$tmp_versions" 1693 | 1694 | if [ -n "$expect_version" ] && echo "$tmp_versions" | grep "$expect_version" > /dev/null 1695 | then 1696 | all_versions=${all_versions%"${expect_version}"*} 1697 | break 1698 | fi 1699 | 1700 | request_url=$(echo "$DVM_REQUEST_RESPONSE" | grep -i "link:" | sed 's/,/\n/g' | grep "rel=\"next\"" \ 1701 | | sed 's/[<>]/\n/g' | grep "http") 1702 | dvm_debug "list releases next page url: $request_url" 1703 | done 1704 | 1705 | DVM_REMOTE_VERSIONS=$(echo -e "$all_versions" | sed '/^$/d' | sed 'x;1!H;$!d;x') 1706 | } 1707 | 1708 | # Get all available versions from network, and list them with installation 1709 | # status. 1710 | dvm_list_remote_versions() { 1711 | if ! dvm_get_remote_versions 1712 | then 1713 | return 1714 | fi 1715 | 1716 | dvm_get_current_version 1717 | 1718 | while read -r version 1719 | do 1720 | if [ "$DVM_DENO_VERSION" = "$version" ] 1721 | then 1722 | dvm_print_with_color "32" "-> $version *" 1723 | elif [ -f "$DVM_DIR/versions/$version/deno" ] 1724 | then 1725 | dvm_print_with_color "34" " $version *" 1726 | else 1727 | dvm_print " $version" 1728 | fi 1729 | done <<< "$DVM_REMOTE_VERSIONS" 1730 | } 1731 | } 1732 | 1733 | ################### 1734 | ## Command purge ## 1735 | ################### 1736 | { 1737 | # Remove all components of DVM from the host. 1738 | dvm_purge_dvm() { 1739 | local content 1740 | 1741 | # remove DVM directory, all installed versions will also removed. 1742 | rm -rf "$DVM_DIR" 1743 | 1744 | # get profile file and remove DVM configs. 1745 | dvm_get_profile_file 1746 | 1747 | content=$(sed "/Deno Version Manager/d;/DVM_DIR/d;/DVM_BIN/d" "$DVM_PROFILE_FILE") 1748 | echo "$content" > "$DVM_PROFILE_FILE" 1749 | 1750 | # unset global variables 1751 | unset -v DVM_COLOR_MODE DVM_DENO_VERSION DVM_DIR DVM_INSTALL_MODE \ 1752 | DVM_INSTALL_REGISTRY DVM_INSTALL_SHA256SUM DVM_INSTALL_SKIP_CACHE \ 1753 | DVM_INSTALL_SKIP_VALIDATION DVM_LATEST_VERSION DVM_PROFILE_FILE DVM_QUIET_MODE \ 1754 | DVM_REMOTE_VERSIONS DVM_REQUEST_RESPONSE DVM_SOURCE DVM_TARGET_ARCH \ 1755 | DVM_TARGET_NAME DVM_TARGET_OS DVM_TARGET_TYPE DVM_TARGET_VERSION \ 1756 | DVM_VERBOSE_MODE DVM_VERSION 1757 | # unset dvm itself 1758 | unset -f dvm 1759 | # unset dvm functions 1760 | unset -f dvm_build_deno dvm_check_alias_dir dvm_check_build_dependencies \ 1761 | dvm_check_local_deno_clone dvm_clean_caches dvm_clean_download_cache \ 1762 | dvm_clone_deno_source dvm_compare_version dvm_confirm_with_prompt \ 1763 | dvm_copy_build_target_to_versions_dir dvm_deactivate dvm_debug \ 1764 | dvm_download_deno dvm_download_file dvm_extract_file dvm_failure \ 1765 | dvm_fix_invalid_versions dvm_get_current_version \ 1766 | dvm_get_dvm_latest_version dvm_get_latest_version dvm_get_package_data \ 1767 | dvm_get_profile_file dvm_get_remote_version_by_prefix dvm_get_remote_versions \ 1768 | dvm_get_version dvm_get_version_from_dvmrc dvm_get_version_by_param \ 1769 | dvm_get_versions_from_deno_versions_json dvm_get_versions_from_network dvm_has \ 1770 | dvm_install_deno dvm_install_deno_by_binary \ 1771 | dvm_install_deno_by_source dvm_install_version dvm_is_version_prefix dvm_list_aliases \ 1772 | dvm_list_local_versions dvm_list_remote_versions dvm_locate_version dvm_parse_options \ 1773 | dvm_print dvm_print_doctor_message dvm_print_current_version dvm_print_error \ 1774 | dvm_print_help dvm_print_warning dvm_print_with_color dvm_purge_dvm \ 1775 | dvm_read_dvmrc_file dvm_request dvm_rm_alias dvm_run_with_version \ 1776 | dvm_scan_and_fix_versions dvm_set_alias \ 1777 | dvm_set_default_alias_after_install dvm_set_default_env dvm_strip_path \ 1778 | dvm_success dvm_uninstall_version dvm_update_dvm dvm_use_version \ 1779 | dvm_validate_build_target dvm_validate_download_file dvm_validate_remote_version 1780 | # unset dvm shell completion functions 1781 | unset -f _dvm_add_aliases_to_opts _dvm_add_versions_to_opts \ 1782 | _dvm_has_active_version _dvm_add_options_to_opts _dvm_completion 1783 | 1784 | echo "DVM has been removed from your computer." 1785 | } 1786 | } 1787 | 1788 | ################# 1789 | ## Command run ## 1790 | ################# 1791 | { 1792 | # Run the Deno of the specific version without activate. 1793 | # Parameters: 1794 | # $1: the version of Deno to be run. 1795 | # $2...: the parameters that passing to the Deno. 1796 | dvm_run_with_version() { 1797 | if [ ! -f "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" ] 1798 | then 1799 | dvm_print_error "deno $DVM_TARGET_VERSION is not installed." 1800 | dvm_failure 1801 | return 1802 | fi 1803 | 1804 | dvm_print "Running with deno $DVM_TARGET_VERSION." 1805 | 1806 | dvm_debug "target deno version: $DVM_TARGET_VERSION" 1807 | dvm_debug "run deno with parameters:" "$@" 1808 | 1809 | "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" "$@" 1810 | } 1811 | } 1812 | 1813 | ################### 1814 | ## Command which ## 1815 | ################### 1816 | { 1817 | # Get the path of the active version or the specific version of Deno. 1818 | # Parameters: 1819 | # $1: the version of Deno, or 'current'. 1820 | dvm_locate_version() { 1821 | local target_version 1822 | 1823 | target_version="$DVM_TARGET_VERSION" 1824 | 1825 | if [ "$1" = "current" ] 1826 | then 1827 | dvm_get_current_version 1828 | if [ -n "$DVM_DENO_VERSION" ] 1829 | then 1830 | target_version="$DVM_DENO_VERSION" 1831 | fi 1832 | fi 1833 | 1834 | if [ -f "$DVM_DIR/versions/$target_version/deno" ] 1835 | then 1836 | dvm_print "$DVM_DIR/versions/$target_version/deno" 1837 | else 1838 | dvm_print "Deno $target_version is not installed." 1839 | fi 1840 | } 1841 | } 1842 | 1843 | ##################### 1844 | ## Command unalias ## 1845 | ##################### 1846 | { 1847 | # Remove an alias name of a Deno version. 1848 | # Parameters: 1849 | # $1: the alias name to be remove. 1850 | dvm_rm_alias() { 1851 | local alias_name 1852 | local aliased_version 1853 | 1854 | dvm_check_alias_dir 1855 | 1856 | while [ "$#" -gt "0" ] 1857 | do 1858 | case "$1" in 1859 | "-"*) 1860 | ;; 1861 | *) 1862 | if [ -z "$alias_name" ] 1863 | then 1864 | alias_name="$1" 1865 | fi 1866 | esac 1867 | 1868 | shift 1869 | done 1870 | 1871 | if [ ! -f "$DVM_DIR/aliases/$alias_name" ] 1872 | then 1873 | dvm_print_error "alias $alias_name does not exist." 1874 | dvm_failure 1875 | return 1876 | fi 1877 | 1878 | aliased_version=$(head -n 1 "$DVM_DIR/aliases/$alias_name") 1879 | 1880 | rm "$DVM_DIR/aliases/$alias_name" 1881 | 1882 | dvm_print "Deleted alias $alias_name." 1883 | dvm_print "Restore it with 'dvm alias $alias_name $aliased_version'." 1884 | } 1885 | } 1886 | 1887 | ####################### 1888 | ## Command uninstall ## 1889 | ####################### 1890 | { 1891 | # Uninstall the specific version of Deno from the computer. It cannot 1892 | # uninstall the active Deno version or installing from another source. 1893 | # Parameters: 1894 | # - $1: the Deno version to uninstall. 1895 | dvm_uninstall_version() { 1896 | local input_version 1897 | 1898 | input_version="$1" 1899 | 1900 | dvm_get_current_version 1901 | 1902 | if [ "$DVM_DENO_VERSION" = "$DVM_TARGET_VERSION" ] 1903 | then 1904 | dvm_print "Cannot active deno version ($DVM_DENO_VERSION)." 1905 | dvm_failure 1906 | return 1907 | fi 1908 | 1909 | if [ -f "$DVM_DIR/versions/$DVM_TARGET_VERSION/deno" ] 1910 | then 1911 | rm -rf "$DVM_DIR/versions/$DVM_TARGET_VERSION" 1912 | 1913 | dvm_print "Uninstalled deno $DVM_TARGET_VERSION." 1914 | else 1915 | dvm_print "Deno $DVM_TARGET_VERSION is not installed." 1916 | fi 1917 | 1918 | if [ -n "$input_version" ] && [ "$input_version" != "$DVM_TARGET_VERSION" ] && [ -f "$DVM_DIR/aliases/$input_version" ] 1919 | then 1920 | rm "$DVM_DIR/aliases/$input_version" 1921 | fi 1922 | } 1923 | } 1924 | 1925 | ##################### 1926 | ## Command upgrade ## 1927 | ##################### 1928 | { 1929 | # Gets the latest version of DVM from the GitHub or Gitee repo. 1930 | dvm_get_dvm_latest_version() { 1931 | local request_url 1932 | 1933 | case "$DVM_SOURCE" in 1934 | "gitee") 1935 | request_url="https://gitee.com/api/v5/repos/ghosind/dvm/releases/latest" 1936 | ;; 1937 | "github"|*) 1938 | request_url="https://api.github.com/repos/ghosind/dvm/releases/latest" 1939 | ;; 1940 | esac 1941 | 1942 | dvm_debug "dvm source url: $request_url" 1943 | 1944 | if ! dvm_request "$request_url" 1945 | then 1946 | dvm_print_error "failed to get the latest DVM version." 1947 | dvm_failure 1948 | return 1949 | fi 1950 | 1951 | DVM_LATEST_VERSION=$(echo "$DVM_REQUEST_RESPONSE" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 1952 | if [ -n "$DVM_LATEST_VERSION" ] 1953 | then 1954 | dvm_debug "dvm latest version: $DVM_LATEST_VERSION" 1955 | else 1956 | dvm_debug "getting dvm latest response: $DVM_REQUEST_RESPONSE" 1957 | dvm_failure 1958 | fi 1959 | } 1960 | 1961 | # Upgrade the DVM itself to the specific version. 1962 | dvm_update_dvm() { 1963 | local cwd 1964 | 1965 | cwd=$(pwd) 1966 | 1967 | dvm_get_profile_file 1968 | 1969 | if ! cd "$DVM_DIR" 2>/dev/null 1970 | then 1971 | dvm_print_error "failed to update dvm." 1972 | dvm_failure 1973 | return 1974 | fi 1975 | 1976 | # reset changes if exists 1977 | if git reset --hard HEAD && git fetch --all && git pull origin master --tags && git checkout "$DVM_LATEST_VERSION" 1978 | then 1979 | dvm_print "DVM has upgrade to latest version, please restart your terminal or run \`source $DVM_PROFILE_FILE\` to apply changes." 1980 | 1981 | cd "$cwd" || dvm_failure 1982 | else 1983 | dvm_print_error "failed to update dvm." 1984 | cd "$cwd" && dvm_failure 1985 | fi 1986 | } 1987 | } 1988 | 1989 | ################# 1990 | ## Command use ## 1991 | ################# 1992 | { 1993 | # Create a symbolic link file to make the specified deno version as active 1994 | # version, the symbolic link is linking to the specified deno executable 1995 | # file. 1996 | # Parameters: 1997 | # - $1: deno version or alias name to use. 1998 | dvm_use_version() { 1999 | # deno executable file version 2000 | local deno_version 2001 | # target deno executable file path 2002 | local target_path 2003 | local path_without_dvm 2004 | 2005 | dvm_get_version "$@" 2006 | 2007 | if [ -z "$DVM_TARGET_VERSION" ] 2008 | then 2009 | dvm_print_help 2010 | dvm_failure 2011 | return 2012 | fi 2013 | 2014 | target_dir="$DVM_DIR/versions/$DVM_TARGET_VERSION" 2015 | target_path="$target_dir/deno" 2016 | 2017 | if [ -f "$target_path" ] 2018 | then 2019 | # get target deno executable file version 2020 | deno_version=$("$target_path" --version 2>/dev/null | grep deno | cut -d " " -f 2) 2021 | 2022 | if [ -n "$deno_version" ] && [ "$DVM_TARGET_VERSION" != "v$deno_version" ] 2023 | then 2024 | # print warning message when deno version is different with parameter. 2025 | dvm_print_warning "You may had upgraded this version, it is v$deno_version now." 2026 | fi 2027 | 2028 | # export PATH with the target dir in front 2029 | path_without_dvm=$(dvm_strip_path) 2030 | export PATH="$target_dir":${path_without_dvm} 2031 | 2032 | dvm_print "Using deno $DVM_TARGET_VERSION now." 2033 | else 2034 | dvm_print "Deno $DVM_TARGET_VERSION is not installed, you can run 'dvm install $DVM_TARGET_VERSION' to install it." 2035 | dvm_failure 2036 | fi 2037 | } 2038 | } 2039 | 2040 | # The entry of DVM, it will handle options and try to execute commands. 2041 | dvm() { 2042 | local version="" 2043 | 2044 | dvm_set_default_env 2045 | 2046 | if [ "$#" = "0" ] 2047 | then 2048 | dvm_print_help 2049 | dvm_success 2050 | return 2051 | fi 2052 | 2053 | dvm_parse_options "$@" 2054 | 2055 | case "$1" in 2056 | "alias") 2057 | shift 2058 | 2059 | dvm_set_alias "$@" 2060 | 2061 | ;; 2062 | "clean") 2063 | dvm_clean_caches 2064 | 2065 | ;; 2066 | "current") 2067 | # get the current version 2068 | dvm_print_current_version 2069 | 2070 | ;; 2071 | "deactivate") 2072 | dvm_deactivate 2073 | 2074 | ;; 2075 | "doctor") 2076 | local mode 2077 | 2078 | shift 2079 | 2080 | mode="scan" 2081 | 2082 | while [ "$#" -gt "0" ] 2083 | do 2084 | case "$1" in 2085 | "--fix") 2086 | mode="fix" 2087 | ;; 2088 | *) 2089 | ;; 2090 | esac 2091 | 2092 | shift 2093 | done 2094 | 2095 | if [ "$mode" = "fix" ] && 2096 | ! dvm_confirm_with_prompt "Doctor fix command will remove all duplicated / corrupted versions, do you want to continue?" 2097 | then 2098 | return 2099 | fi 2100 | 2101 | dvm_scan_and_fix_versions "$mode" 2102 | 2103 | ;; 2104 | "install"|"i") 2105 | # install the specified version 2106 | shift 2107 | 2108 | while [ "$#" -gt "0" ] 2109 | do 2110 | case "$1" in 2111 | "--registry="*) 2112 | DVM_INSTALL_REGISTRY=${1#--registry=} 2113 | ;; 2114 | "--skip-validation") 2115 | DVM_INSTALL_SKIP_VALIDATION=true 2116 | ;; 2117 | "--skip-download-cache") 2118 | DVM_INSTALL_SKIP_CACHE=true 2119 | ;; 2120 | "--from-binary") 2121 | DVM_INSTALL_MODE="binary" 2122 | ;; 2123 | "--from-source") 2124 | DVM_INSTALL_MODE="source" 2125 | ;; 2126 | "--sha256sum") 2127 | DVM_INSTALL_SHA256SUM=true 2128 | ;; 2129 | "--no-sha256sum") 2130 | DVM_INSTALL_SHA256SUM=false 2131 | ;; 2132 | "-"*) 2133 | ;; 2134 | *) 2135 | version="$1" 2136 | ;; 2137 | esac 2138 | 2139 | shift 2140 | done 2141 | 2142 | dvm_install_version "$version" 2143 | 2144 | ;; 2145 | "list"|"ls") 2146 | # list all local versions 2147 | dvm_get_current_version 2148 | 2149 | dvm_list_local_versions 2150 | 2151 | dvm_list_aliases 2152 | 2153 | ;; 2154 | "list-remote"|"ls-remote") 2155 | # list all remote versions 2156 | dvm_list_remote_versions 2157 | 2158 | ;; 2159 | "purge") 2160 | if ! dvm_confirm_with_prompt "Do you want to remove DVM from your computer?" 2161 | then 2162 | return 2163 | fi 2164 | 2165 | if ! dvm_confirm_with_prompt "Remove dvm will also remove installed deno(s), do you want to continue?" 2166 | then 2167 | return 2168 | fi 2169 | 2170 | dvm_purge_dvm 2171 | 2172 | ;; 2173 | "run") 2174 | shift 2175 | 2176 | dvm_get_version "$@" 2177 | 2178 | if [ "$DVM_TARGET_VERSION" = "" ] 2179 | then 2180 | dvm_print_help 2181 | dvm_failure 2182 | return 2183 | fi 2184 | 2185 | while [ "$#" != "0" ] 2186 | do 2187 | case "$1" in 2188 | "-"*) 2189 | shift 2190 | ;; 2191 | *) 2192 | shift 2193 | break 2194 | ;; 2195 | esac 2196 | done 2197 | 2198 | dvm_run_with_version "$@" 2199 | 2200 | ;; 2201 | "which") 2202 | shift 2203 | 2204 | if [ "$#" = "0" ] || [ "$1" != "current" ] 2205 | then 2206 | dvm_get_version "$@" 2207 | 2208 | if [ -z "$DVM_TARGET_VERSION" ] 2209 | then 2210 | dvm_print_help 2211 | dvm_failure 2212 | return 2213 | fi 2214 | fi 2215 | 2216 | dvm_locate_version "$@" 2217 | 2218 | ;; 2219 | "unalias") 2220 | shift 2221 | 2222 | dvm_rm_alias "$@" 2223 | 2224 | ;; 2225 | "uninstall") 2226 | # uninstall the specified version 2227 | shift 2228 | 2229 | dvm_get_version "$@" 2230 | if [ "$DVM_TARGET_VERSION" = "" ] 2231 | then 2232 | dvm_print_help 2233 | dvm_failure 2234 | return 2235 | fi 2236 | 2237 | dvm_uninstall_version "$DVM_TARGET_VERSION" 2238 | 2239 | ;; 2240 | "upgrade") 2241 | if ! dvm_get_dvm_latest_version 2242 | then 2243 | return 2244 | fi 2245 | 2246 | if [ "$DVM_LATEST_VERSION" = "$DVM_VERSION" ] 2247 | then 2248 | dvm_print "dvm is update to date." 2249 | dvm_success 2250 | return 2251 | fi 2252 | 2253 | dvm_update_dvm 2254 | 2255 | ;; 2256 | "use") 2257 | # change current version to specified version 2258 | shift 2259 | 2260 | dvm_use_version "$@" 2261 | 2262 | ;; 2263 | "help"|"--help"|"-h") 2264 | # print help 2265 | dvm_print_help 2266 | 2267 | ;; 2268 | "--version") 2269 | # print dvm version 2270 | dvm_print "$DVM_VERSION" 2271 | 2272 | ;; 2273 | *) 2274 | dvm_print_error "unknown command $1." 2275 | dvm_print_help 2276 | dvm_failure 2277 | ;; 2278 | esac 2279 | } 2280 | 2281 | # Activate the default version when a new terminal session was created. It 2282 | # need to run in the quiet mode to avoid printing any messages. 2283 | if [ -f "$DVM_DIR/aliases/default" ] 2284 | then 2285 | DVM_QUIET_MODE=true 2286 | dvm_use_version "default" 2287 | DVM_QUIET_MODE=false 2288 | fi 2289 | 2290 | } 2291 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Installation script for Deno Version Manager 3 | # Copyright (C) 2020 ~ 2025, Chen Su and all contributors. 4 | 5 | # Ensure the script is downloaded completely 6 | { 7 | 8 | dvm_add_into_profile_file() { 9 | local is_dvm_defined 10 | 11 | dvm_get_profile_file 12 | 13 | is_dvm_defined=$(grep DVM_DIR < "$DVM_PROFILE_FILE") 14 | 15 | if [ -n "$is_dvm_defined" ] 16 | then 17 | return 18 | fi 19 | 20 | echo " 21 | # Deno Version Manager 22 | export DVM_DIR=\"\$HOME/.dvm\" 23 | [ -f \"\$DVM_DIR/dvm.sh\" ] && . \"\$DVM_DIR/dvm.sh\" 24 | [ -f \"\$DVM_DIR/bash_completion\" ] && . \"\$DVM_DIR/bash_completion\" 25 | " >> "$DVM_PROFILE_FILE" 26 | } 27 | 28 | dvm_check_dir() { 29 | if [ ! -d "$DVM_DIR" ] 30 | then 31 | mkdir -p "$DVM_DIR" 32 | else 33 | echo "directory $DVM_DIR already exists." 34 | exit 1 35 | fi 36 | } 37 | 38 | dvm_compare_version() { 39 | test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$2" 40 | } 41 | 42 | dvm_get_latest_version() { 43 | local request_url 44 | local response 45 | 46 | case "$DVM_SOURCE" in 47 | "gitee") 48 | request_url="https://gitee.com/api/v5/repos/ghosind/dvm/releases/latest" 49 | ;; 50 | "github"|*) 51 | request_url="https://api.github.com/repos/ghosind/dvm/releases/latest" 52 | ;; 53 | esac 54 | 55 | if ! dvm_has curl 56 | then 57 | echo "curl is required." 58 | exit 1 59 | fi 60 | 61 | if ! response=$(curl -s "$request_url") 62 | then 63 | echo "Failed to get the latest DVM version." 64 | exit 1 65 | fi 66 | 67 | DVM_LATEST_VERSION=$(echo "$response" | sed 's/"/\n/g' | grep tag_name -A 2 | grep v) 68 | } 69 | 70 | dvm_get_profile_file() { 71 | case "${SHELL##*/}" in 72 | "bash") 73 | DVM_PROFILE_FILE="$HOME/.bashrc" 74 | ;; 75 | "zsh") 76 | DVM_PROFILE_FILE="$HOME/.zshrc" 77 | ;; 78 | *) 79 | DVM_PROFILE_FILE="$HOME/.profile" 80 | ;; 81 | esac 82 | } 83 | 84 | dvm_has() { 85 | command -v "$1" > /dev/null 86 | } 87 | 88 | dvm_install() { 89 | dvm_check_dir 90 | 91 | DVM_SCRIPT_DIR=${0%/*} 92 | 93 | if [ -f "$DVM_SCRIPT_DIR/dvm.sh" ] && 94 | [ -d "$DVM_SCRIPT_DIR/.git" ] && 95 | [ -f "$DVM_SCRIPT_DIR/bash_completion" ] 96 | then 97 | # Copy all files to DVM_DIR 98 | cp -R "$DVM_SCRIPT_DIR/". "$DVM_DIR" 99 | else 100 | dvm_get_latest_version 101 | dvm_install_latest_version 102 | fi 103 | 104 | dvm_add_into_profile_file 105 | 106 | echo "DVM has been installed, please restart your terminal or run \`source $DVM_PROFILE_FILE\` to apply changes." 107 | } 108 | 109 | dvm_install_latest_version() { 110 | local git_url 111 | local cmd 112 | 113 | case "$DVM_SOURCE" in 114 | "gitee") 115 | git_url="https://gitee.com/ghosind/dvm.git" 116 | ;; 117 | "github"|*) 118 | git_url="https://github.com/ghosind/dvm.git" 119 | ;; 120 | esac 121 | 122 | if ! dvm_has git 123 | then 124 | echo "git is require." 125 | exit 1 126 | fi 127 | 128 | cmd="git clone -b $DVM_LATEST_VERSION $git_url $DVM_DIR --depth=1" 129 | 130 | if ! ${cmd} 131 | then 132 | echo "failed to download DVM." 133 | exit 1 134 | fi 135 | } 136 | 137 | dvm_print_help() { 138 | echo "DVM installation script" 139 | echo 140 | echo "Usage: install.sh [-r ] [-d ]" 141 | echo 142 | echo "Options:" 143 | echo " -r Set the repository server, default github." 144 | echo " -d dir Set the dvm install directory, default ~/.dvm." 145 | echo " -h Print help." 146 | echo 147 | echo "Example:" 148 | echo " install.sh -r github -d ~/.dvm" 149 | } 150 | 151 | dvm_set_default() { 152 | DVM_DIR=${DVM_DIR:-$HOME/.dvm} 153 | DVM_SOURCE=${DVM_SOURCE:-github} 154 | } 155 | 156 | dvm_set_default 157 | 158 | while getopts "hr:d:" opt 159 | do 160 | case "$opt" in 161 | "h") 162 | dvm_print_help 163 | exit 0 164 | ;; 165 | "r") 166 | if [ "$OPTARG" != "github" ] && [ "$OPTARG" != "gitee" ] 167 | then 168 | dvm_print_help 169 | exit 1 170 | fi 171 | DVM_SOURCE="$OPTARG" 172 | ;; 173 | "d") 174 | if [ -z "$OPTARG" ] 175 | then 176 | dvm_print_help 177 | exit 1 178 | fi 179 | 180 | DVM_DIR="$OPTARG" 181 | ;; 182 | *) 183 | ;; 184 | esac 185 | done 186 | 187 | if [ "$DVM_SOURCE" != "github" ] && [ "$DVM_SOURCE" != "gitee" ] 188 | then 189 | dvm_print_help 190 | exit 1 191 | fi 192 | 193 | dvm_install 194 | 195 | } 196 | -------------------------------------------------------------------------------- /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_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_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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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_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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------