2 个版本 (1 个稳定版)

1.2.6 2023年1月30日

#1821命令行工具

MIT 许可证

305KB
7K SLoC

rtx

Crates.io License: MIT CI Codecov Discord

多语言运行时管理器 (asdf rust 克隆版)

快速入门

安装 rtx(其他方法 在此

$ https://rtx.jdxcode.com/rtx-latest-macos-arm64 > ~/bin/rtx
$ rtx --version
rtx 1.2.6

将 rtx 集成到您的 shell 中。如果尚未添加,这将自动将 ~/bin 添加到 PATH。 (选择一个,然后打开新的 shell 会话以使更改生效)

$ echo 'eval "$(~/bin/rtx activate -s bash)"' >> ~/.bashrc
$ echo 'eval "$(~/bin/rtx activate -s zsh)"' >> ~/.zshrc
$ echo '~/bin/rtx activate -s fish | source' >> ~/.config/fish/config.fish

警告

如果您使用 direnv,请参阅 以下 以获取兼容 direnv 的设置。

安装一个运行时并将其设置为默认

$ rtx install nodejs@18
$ rtx global nodejs@18
$ node -v
v18.10.9

注意

rtx install 是可选的,如果未安装,rtx global 将提示安装运行时。这可以在 ~/.config/rtx/config.toml 中进行配置。

关于

rtx 是一个用于管理编程语言和工具版本的工具。例如,可以使用此工具安装项目所需特定版本的 node.js 和 ruby。使用 rtx activate,当您 cd 到项目目录时,您的 shell 将自动切换到正确的 node 和 ruby 版本。您的机器上的其他项目可以使用不同版本的集合。

rtx 受 asdf 的启发,并在底层使用 asdf 的庞大 插件生态系统。然而,它比 asdf 快得多,并且具有更友好的用户体验。有关 rtx 与 asdf 的比较,请参阅 以下内容。这个项目的目标是创建一个更好的 asdf 前端。

它使用与 asdf 相同的 .tool-versions 文件。它还与像 .node-version.ruby-version 这样的惯用版本文件兼容。有关更多信息,请参阅以下 旧版版本文件

discord 上聊天关于 rtx。

它如何工作

rtx 作为shell扩展(例如 rtx activate -s zsh)安装,它将 PATH 环境变量设置为指向正确的运行时二进制文件。当你 cd 进入包含 .tool-versions 文件的目录时,rtx 将自动激活正确的版本。

每次你的提示符启动时,它都会调用 rtx hook-env 来获取新的环境变量。这应该非常快,如果目录没有改变或者 .tool-version 文件没有更新,它将提前退出。在我的机器上,即使它 没有 提前退出,这也只需要 1-2 毫秒。

与 asdf 不同,它使用 shim 文件在调用时动态定位运行时,rtx 则在提前修改 PATH,这样就可以直接调用运行时。这不仅更快,因为它避免了任何开销,而且还使得像 which node 这样的命令能够按预期工作。这也意味着在安装新的运行时二进制文件后,没有必要运行 asdf reshim

常见示例命令

rtx install nodejs@20.0.0       Install a specific version number
rtx install nodejs@20.0         Install a fuzzy version number
rtx local nodejs@20             Use node-20.x in current project
rtx global nodejs@20            Use node-20.x as default

rtx install nodejs              Install the latest available version
rtx local nodejs@latest         Use latest node in current directory
rtx global nodejs@system        Use system node as default

rtx x nodejs@20 -- node app.js  Run `node app.js` with the PATH pointing to node-20.x

安装

警告

无论安装方法如何,在卸载 rtx 时,请删除 RTX_DATA_DIR 文件夹(通常是 ~/.local/share/rtx),以彻底清理。

独立

请注意,不需要将 rtx 放在 PATH 上。如果您在rc文件中运行激活脚本,rtx 将自动将其添加到 PATH

$ curl https://rtx.jdxcode.com/install.sh | sh

注意

目前 rtx 中没有自动更新器。因此,如果您使用此方法,您需要记住手动获取新版本以修复错误或添加新功能。我不确定我是否会添加自动更新器,因为这可能会在引入破坏性更改的大版本中造成干扰。

或者如果您对 | sh 过敏

$ curl https://rtx.jdxcode.com/rtx-latest-macos-arm64 > /usr/local/bin/rtx

位置不重要。所以可以使用 ~/bin/usr/local/bin~/.local/share/rtx/bin/rtx 或任何其他位置。

支持的架构

  • x64
  • arm64

支持的平台

  • macos
  • linux

如果您需要其他东西,请使用 cargo 编译。

Homebrew

$ brew install jdxcode/tap/rtx

Cargo

使用 Cargo 从源代码构建。

$ cargo install rtx-cli

使用 cargo-binstall 来加快构建速度

$ cargo install cargo-binstall
$ cargo binstall rtx-cli

npm

rtx 作为预编译二进制文件在 npm 上可用。这不是一个 node.js 包,只是通过 npm 分发。这对于想要通过 package.jsonnpx 设置 rtx 的 JS 项目来说可能很有用。

$ npm install -g @jdxcode/rtx

或者如果您只是想测试它,可以使用 npx 而无需完全安装

$ npx @jdxcode/rtx exec [email protected] -- python some_script.py

GitHub 发布

GitHub 下载最新发布版本。

$ curl https://github.com/jdxcode/rtx/releases/download/v1.2.6/rtx-v1.2.6-linux-x64 | tar -xJv
$ mv rtx/bin/rtx /usr/local/bin

apt

对于 Ubuntu/Debian 的安装

wget -qO - https://rtx.jdxcode.com/gpg-key.pub | gpg --dearmor | sudo tee /usr/share/keyrings/rtx-archive-keyring.gpg 1> /dev/null
echo "deb [signed-by=/usr/share/keyrings/rtx-archive-keyring.gpg arch=amd64] https://rtx.jdxcode.com/deb stable main" | sudo tee /etc/apt/sources.list.d/rtx.list
sudo apt update
sudo apt install -y rtx

警告

如果您是 arm64,您需要运行以下命令

echo "deb [signed-by=/usr/share/keyrings/rtx-archive-keyring.gpg arch=arm64] https://rtx.jdxcode.com/deb stable main" | sudo tee /etc/apt/sources.list.d/rtx.list

dnf

对于 Fedora、CentOS、Amazon Linux、RHEL 及其他基于 dnf 的发行版

dnf install -y dnf-plugins-core
dnf config-manager --add-repo https://rtx.jdxcode.com/rpm/rtx.repo
dnf install -y rtx

yum

yum install -y yum-utils
yum-config-manager --add-repo https://rtx.jdxcode.com/rpm/rtx.repo
yum install -y rtx

apk(即将推出)

对于 Alpine Linux

apk add rtx --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/

aur

对于 Arch Linux

git clone https://aur.archlinux.org/rtx.git
cd rtx
makepkg -si

其他 Shell

Bash

$ echo 'eval "$(rtx activate -s bash)"' >> ~/.bashrc

Fish

$ echo 'rtx activate -s fish | source' >> ~/.config/fish/config.fish

配置

.tool-versions

.tool-versions 文件用于指定项目的运行时版本。以下是一个例子

nodejs      20.0.0  # comments are allowed
ruby        3       # can be fuzzy version
shellcheck  latest  # also supports "latest"
jq          1.6

手动创建 .tool-versions 文件,或使用 rtx local 自动创建它们。有关此文件格式的更多信息,请参阅 asdf 文档

旧版版本文件

RTX 支持类似于 asdf 的“旧版版本文件”。

这背后有一个配置设置“legacy_version_file”,但它默认启用(asdf 默认禁用)。您可以使用 rtx settings set legacy_version_file false 禁用这些文件。当这些文件被解析时,由于它是由插件在 bin/parse-version-file 中执行的,因此会有性能成本。但是,这些文件已被 缓存,所以这并不是什么大问题。您甚至可能不会注意到。

这些文件非常适合设置项目的运行时版本,而不必强制其他开发者使用特定的工具,如 rtx/asdf。

它们支持别名,这意味着您终于可以有一个 .nvmrc 文件,并使用 lts/hydrogen,它将在 rtx nvm 中工作。这是 asdf 无法实现的。

以下是支持的旧版版本文件

插件 “旧版”(惯用)文件
crystal .crystal-version
elixir .exenv-version
golang .go-versiongo.mod
java .java-version
nodejs .nvmrc.node-version
python .python-version
ruby .ruby-versionGemfile
terraform .terraform-version.packer-versionmain.tf
yarn .yvmrc

注意

asdf 称这些为“旧版版本文件”,所以我们也是如此。我认为这个名字不好,因为它暗示了不应该使用它们——这绝对不是我的观点。我更喜欢使用“惯用”版本文件,因为它们是版本文件,不是特定于 asdf/rtx 的,并且可以被其他工具使用。(.npmrc 是一个值得注意的例外,它与特定工具相关。)

全局配置:~/.config/rtx/config.toml

您可以在 ~/.config/rtx/config.toml 中配置 rtx。以下是一些可用的选项(显示默认值)

# whether to prompt to install plugins and runtimes if they're not already installed
missing_runtime_behavior = 'prompt' # other options: 'ignore', 'warn', 'prompt', 'autoinstall'

# plugins can read the versions files used by other version managers (if enabled by the plugin)
# for example, .nvmrc in the case of nodejs's nvm
legacy_version_file = true         # enabled by default (different than asdf)

# configure `rtx install` to always keep the downloaded archive
always_keep_download = false        # deleted after install by default

# configure how frequently (in minutes) to fetch updated plugin repository changes
# this is updated whenever a new runtime is installed
plugin_autoupdate_last_check_duration = 10080 # (one week) set to 0 to disable updates

# configure how frequently (in minutes) to fetch updated shortname repository changes
# note this is not plugins themselves, it's the shortname mappings
# e.g.: nodejs -> https://github.com/asdf-vm/asdf-nodejs.git
plugin_repository_last_check_duration = 10080 # (one week) set to 0 to disable updates

# disables the short name repository (described above)
disable_plugin_short_name_repository = false

[alias.nodejs]
my_custom_node = '18'  # makes `rtx install nodejs@my_custom_node` install node-18.x
                       # this can also be specified in a plugin (see below in "Aliases")

您也可以使用 rtx settings ls|get|set|unset 管理这些设置。

环境变量

您还可以通过环境变量配置 rtx。以下是一些可用的选项

RTX_MISSING_RUNTIME_BEHAVIOR

这与 ~/.config/rtx/config.toml 中的 missing_runtime_behavior 配置选项相同。

RTX_DATA_DIR

这是 rtx 存储其数据的目录。默认为 ~/.local/share/rtx

$ RTX_MISSING_RUNTIME_BEHAVIOR=ignore rtx install nodejs@20
$ RTX_NODEJS_VERSION=20 rtx exec -- node --version

RTX_CONFIG_FILE

这是配置文件的路径。默认为 ~/.config/rtx/config.toml。(如果设置了 $XDG_CONFIG_HOME/config.toml,则为 $XDG_CONFIG_HOME/config.toml

RTX_DEFAULT_TOOL_VERSIONS_FILENAME

将其设置为不同于 ".tool-versions" 的名称,以便 rtx 在具有不同名称的配置中查找。

RTX_${PLUGIN}_VERSION

为运行时设置版本。例如,RTX_NODEJS_VERSION=20 将使用 [email protected],而不考虑 .tool-versions 中设置的值。

RTX_LEGACY_VERSION_FILE

插件可以读取其他版本管理器使用的版本文件(如果插件已启用),例如,nodejs的nvm的情况下的.nvmrc。

别名

rtx支持对运行时版本进行别名设置。其中一个用途是为运行时的LTS版本定义别名。例如,您可能希望将lts/hydrogen指定为[email protected]的版本。因此,您可以在.tool-versions中使用nodejs lts/hydrogen

用户别名可以通过在~/.config/rtx/config.toml中添加一个alias.<PLUGIN>部分来创建。

[alias.nodejs]
my_custom_18 = '18'

插件也可以通过一个bin/list-aliases脚本来提供别名。以下是一个显示node.js版本的示例。

#!/usr/bin/env bash

echo "lts/hydrogen 18"
echo "lts/gallium 16"
echo "lts/fermium 14"

注意

由于这是rtx特有的功能,目前asdf没有使用,因此不太可能在任何插件中找到,但插件作者可以在不影响asdf用户的情况下添加此脚本。

插件

rtx底层使用asdf的插件生态系统。有关插件列表,请参阅https://github.com/asdf-vm/asdf-plugins

常见问题解答

我不想在我的项目中放入.tool-versions文件,因为git将其显示为未跟踪文件。

您可以通过以下三种方式使git忽略这些文件

  • .tool-versions添加到项目的.gitignore文件中。缺点是您需要提交忽略文件的变化。
  • .tool-versions添加到项目的.git/info/exclude。此文件是项目本地的,因此不需要提交。
  • .tool-versions添加到全局gitignore(core.excludesFile)。这将导致git忽略所有项目中的.tool-versions文件。如果需要,您可以使用git add --force .tool-versions显式地将一个添加到项目中。

我如何创建自己的插件?

只需遵循asdf文档。一切应该都是相同的。如果不是,请提交一个问题。

rtx失败或工作不正常

首先尝试设置RTX_LOG_LEVEL=debugRTX_LOG_LEVEL=trace,并查看是否提供了更多信息。您还可以设置RTX_LOG_FILE=/path/to/logfile以将日志写入文件。

如果激活钩子有问题,您可以尝试禁用它并手动调用eval "$(rtx hook-env)"。使用rtx env查看它想使用哪些环境变量也可能有所帮助。

最后,还有一个rtx doctor命令。它里面没有太多内容,但我希望添加更多功能来帮助调试问题。

Windows支持?

这种情况不太可能发生,因为它是基于Bash脚本的asdf插件庞大生态系统的一部分。在某个时候,探索一个兼容Windows的替代插件格式可能值得。

命令

rtx activate

Enables rtx to automatically modify runtimes when changing directory

This should go into your shell's rc file.
Otherwise, it will only take effect in the current session.
(e.g. ~/.bashrc)

Usage: activate [OPTIONS]

Options:
  -s, --shell <SHELL>
          Shell type to generate the script for
          
          [possible values: bash, fish, zsh]

  -h, --help
          Print help (see a summary with '-h')


Examples:
    $ eval "$(rtx activate -s bash)"
    $ eval "$(rtx activate -s zsh)"
    $ rtx activate -s fish | source

rtx alias ls

List aliases
Shows the aliases that can be specified.
These can come from user config or from plugins in `bin/list-aliases`.

For user config, aliases are defined like the following in `~/.config/rtx/config.toml`:

  [alias.nodejs]
  lts = "18.0.0"

Usage: ls [OPTIONS]

Options:
  -p, --plugin <PLUGIN>
          Show aliases for <PLUGIN>

  -h, --help
          Print help (see a summary with '-h')

Examples:
  $ rtx aliases
  nodejs    lts/hydrogen   18.0.0

rtx complete

generate shell completions

Usage: complete --shell <SHELL>

Options:
  -s, --shell <SHELL>
          shell type
          
          [possible values: bash, elvish, fish, powershell, zsh]

  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx complete

rtx current

Shows currently active, and installed runtime versions

This is similar to `rtx list --current`, but this
only shows the runtime and/or version so it's
designed to fit into scripts more easily.

Usage: current [PLUGIN]

Arguments:
  [PLUGIN]
          plugin to show versions of
          
          e.g.: ruby, nodejs

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:

  $ rtx current
  shfmt@3.6.0
  shellcheck@0.9.0
  nodejs@18.13.0

  $ rtx current nodejs
  18.13.0

rtx deactivate

disable rtx for current shell session

This can be used to temporarily disable rtx in a shell session.

Usage: deactivate [OPTIONS]

Options:
  -s, --shell <SHELL>
          shell type to generate the script for
          
          e.g.: bash, zsh, fish
          
          [possible values: bash, fish, zsh]

  -h, --help
          Print help (see a summary with '-h')


Examples:
    $ eval "$(rtx deactivate -s bash)"
    $ eval "$(rtx deactivate -s zsh)"
    $ rtx deactivate -s fish | source

rtx direnv activate

Output direnv function to use rtx inside direnv

See https://github.com/jdxcode/rtx#direnv for more information

Because this generates the legacy files based on currently installed plugins,
you should run this command after installing new plugins. Otherwise
direnv may not know to update environment variables when legacy file versions change.

Usage: activate

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:
    $ rtx direnv activate > ~/.config/direnv/lib/use_rtx.sh
    $ echo 'use rtx' > .envrc
    $ direnv allow

rtx doctor

Check rtx installation for possible problems.

Usage: doctor

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx doctor
  [WARN] plugin nodejs is not installed

rtx env

exports environment variables to activate rtx in a single shell session

It's not necessary to use this if you have `rtx activate` in your shell rc file.
Use this if you don't want to permanently install rtx.
This can be used similarly to `asdf shell`.
Unfortunately, it requires `eval` to work since it's not written in Bash though.
It's also useful just to see what environment variables rtx sets.

Usage: env [OPTIONS] [RUNTIME]...

Arguments:
  [RUNTIME]...
          runtime version to use

Options:
  -s, --shell <SHELL>
          Shell type to generate environment variables for
          
          [possible values: bash, fish, zsh]

  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ eval "$(rtx env -s bash)"
  $ eval "$(rtx env -s zsh)"
  $ rtx env -s fish | source

rtx exec

execute a command with runtime(s) set

use this to avoid modifying the shell session or running ad-hoc commands with the rtx runtimes
set.

Runtimes will be loaded from .tool-versions, though they can be overridden with <RUNTIME> args
Note that only the plugin specified will be overriden, so if a `.tool-versions` file
includes "nodejs 20" but you run `rtx exec python@3.11`; it will still load nodejs@20.

The "--" separates runtimes from the commands to pass along to the subprocess.

Usage: exec [OPTIONS] [RUNTIME]... [-- <COMMAND>...]

Arguments:
  [RUNTIME]...
          runtime(s) to start
          
          e.g.: nodejs@20 python@3.10

  [COMMAND]...
          the command string to execute (same as --command)

Options:
  -c, --command <C>
          the command string to execute

  -h, --help
          Print help (see a summary with '-h')


Examples:
  rtx exec nodejs@20 -- node ./app.js  # launch app.js using node-20.x
  rtx x nodejs@20 -- node ./app.js     # shorter alias

Specify command as a string:
  rtx exec nodejs@20 python@3.11 --command "node -v && python -V"

rtx global

sets global .tool-versions to include a specified runtime

this file is `$HOME/.tool-versions` by default
use `rtx local` to set a runtime version locally in the current directory

Usage: global [OPTIONS] [RUNTIME]...

Arguments:
  [RUNTIME]...
          runtimes
          
          e.g.: nodejs@20

Options:
      --fuzzy
          save fuzzy match to .tool-versions e.g.: `rtx global --fuzzy nodejs@20` will save `nodejs 20` to .tool-versions, by default, it would save the exact version, e.g.: `nodejs 20.0.0`

      --remove <PLUGIN>
          remove the plugin(s) from ~/.tool-versions

  -h, --help
          Print help (see a summary with '-h')


Examples:
  # set the current version of nodejs to 20.x
  # will use a precise version (e.g.: 20.0.0) in .tool-versions file
  $ rtx global nodejs@20     

  # set the current version of nodejs to 20.x
  # will use a fuzzy version (e.g.: 20) in .tool-versions file
  $ rtx global --fuzzy nodejs@20

rtx install

install a runtime

this will install a runtime to `~/.local/share/rtx/installs/<PLUGIN>/<VERSION>`
it won't be used simply by being installed, however.
For that, you must set up a `.tool-version` file manually or with `rtx local/global`.
Or you can call a runtime explicitly with `rtx exec <PLUGIN>@<VERSION> -- <COMMAND>`.

Usage: install [OPTIONS] [RUNTIME]...

Arguments:
  [RUNTIME]...
          runtime(s) to install
          
          e.g.: nodejs@20

Options:
  -p, --plugin <PLUGIN>
          only install runtime(s) for <PLUGIN>

  -f, --force
          force reinstall even if already installed

  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx install nodejs@18.0.0  # install specific nodejs version
  $ rtx install nodejs@18      # install fuzzy nodejs version
  $ rtx install nodejs         # install latest nodejs version—or what is specified in .tool-versions
  $ rtx install                # installs all runtimes specified in .tool-versions for installed plugins

rtx latest

get the latest runtime version of a plugin's runtimes

Usage: latest <RUNTIME>

Arguments:
  <RUNTIME>
          Runtime to get the latest version of

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx latest nodejs@18  # get the latest version of nodejs 18
  18.0.0
  
  $ rtx latest nodejs     # get the latest stable version of nodejs
  20.0.0

rtx local

Sets .tool-versions to include a specific runtime

use this to set the runtime version when within a directory
use `rtx global` to set a runtime version globally

Usage: local [OPTIONS] [RUNTIME]...

Arguments:
  [RUNTIME]...
          runtimes to add to .tool-versions
          
          e.g.: nodejs@20

Options:
  -p, --parent
          recurse up to find a .tool-versions file rather than using the current directory only by default this command will only set the runtime in the current directory ("$PWD/.tool-versions")

      --fuzzy
          save fuzzy match to .tool-versions e.g.: `rtx local --fuzzy nodejs@20` will save `nodejs 20` to .tool-versions by default it would save the exact version, e.g.: `nodejs 20.0.0`

      --remove <PLUGIN>
          remove the plugin(s) from .tool-versions

  -h, --help
          Print help (see a summary with '-h')


Examples:
  # set the current version of nodejs to 20.x for the current directory
  # will use a precise version (e.g.: 20.0.0) in .tool-versions file
  $ rtx local nodejs@20

  # set nodejs to 20.x for the current project (recurses up to find .tool-versions)
  $ rtx local -p nodejs@20

  # set the current version of nodejs to 20.x for the current directory
  # will use a fuzzy version (e.g.: 20) in .tool-versions file
  $ rtx local --fuzzy nodejs@20

  # removes nodejs from .tool-versions
  $ rtx local --remove=nodejs

rtx ls

list installed runtime versions

The "arrow (->)" indicates the runtime is installed, active, and will be used for running commands.
(Assuming `rtx activate` or `rtx env` is in use).

Usage: ls [OPTIONS]

Options:
  -p, --plugin <PLUGIN>
          Only show runtimes from [PLUGIN]

  -c, --current
          Only show runtimes currently specified in .tool-versions

  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx list
  -> nodejs     20.0.0 (set by ~/src/myapp/.tool-versions)
  -> python     3.11.0 (set by ~/.tool-versions)
     python     3.10.0
     
  $ rtx list --current
  -> nodejs     20.0.0 (set by ~/src/myapp/.tool-versions)
  -> python     3.11.0 (set by ~/.tool-versions)

rtx ls-remote

list runtime versions available for install
note that these versions are cached for commands like `rtx install nodejs@latest`
however _this_ command will always clear that cache and fetch the latest remote versions

Usage: ls-remote <PLUGIN>

Arguments:
  <PLUGIN>
          Plugin

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx list-remote nodejs
  18.0.0
  20.0.0

rtx plugins install

install a plugin

note that rtx automatically can install plugins when you install a runtime
e.g.: `rtx install nodejs@18` will autoinstall the nodejs plugin

This behavior can be modified in ~/.rtx/config.toml

Usage: install [OPTIONS] <NAME> [GIT_URL]

Arguments:
  <NAME>
          The name of the plugin to install
          
          e.g.: nodejs, ruby

  [GIT_URL]
          The git url of the plugin
          
          e.g.: https://github.com/asdf-vm/asdf-nodejs.git

Options:
  -f, --force
          Reinstalls even if plugin exists

  -h, --help
          Print help (see a summary with '-h')


EXAMPLES:
    $ rtx install nodejs  # install the nodejs plugin using the shorthand repo:
                          # https://github.com/asdf-vm/asdf-plugins

    $ rtx install nodejs https://github.com/asdf-vm/asdf-nodejs.git
                          # install the nodejs plugin using the git url

    $ rtx install https://github.com/asdf-vm/asdf-nodejs.git
                          # install the nodejs plugin using the git url only
                          # (nodejs is inferred from the url)

rtx plugins ls

List installed plugins

Can also show remotely available plugins to install.

Usage: ls [OPTIONS]

Options:
  -a, --all
          list all available remote plugins
          
          same as `rtx plugins ls-remote`

  -u, --urls
          show the git url for each plugin
          
          e.g.: https://github.com/asdf-vm/asdf-nodejs.git

  -h, --help
          Print help (see a summary with '-h')

List installed plugins
Can also show remotely available plugins to install.

Examples:

  $ rtx plugins ls
  nodejs
  ruby
  
  $ rtx plugins ls --urls
  nodejs                        https://github.com/asdf-vm/asdf-nodejs.git
  ruby                          https://github.com/asdf-vm/asdf-ruby.git

rtx plugins ls-remote

List all available remote plugins

These are fetched from https://github.com/asdf-vm/asdf-plugins

Examples:
  $ rtx plugins ls-remote


Usage: ls-remote [OPTIONS]

Options:
  -u, --urls
          show the git url for each plugin
          
          e.g.: https://github.com/asdf-vm/asdf-nodejs.git

  -h, --help
          Print help (see a summary with '-h')

rtx plugins uninstall

removes a plugin

Usage: uninstall <PLUGIN>

Arguments:
  <PLUGIN>
          plugin to remove

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx uninstall nodejs

rtx plugins update

updates a plugin to the latest version

note: this updates the plugin itself, not the runtime versions

Usage: update [OPTIONS] [PLUGIN]...

Arguments:
  [PLUGIN]...
          plugin(s) to update

Options:
  -a, --all
          update all plugins

  -h, --help
          Print help (see a summary with '-h')


Examples:
  rtx plugins update --all   # update all plugins
  rtx plugins update nodejs  # update only nodejs

rtx settings get

Show a current setting

This is the contents of a single entry in ~/.config/rtx/config.toml

Note that aliases are also stored in this file
but managed separately with `rtx aliases get`

Usage: get <KEY>

Arguments:
  <KEY>
          The setting to show

Options:
  -h, --help
          Print help (see a summary with '-h')

Examples:
  $ rtx settings get legacy_version_file
  true

rtx settings ls

Show current settings

This is the contents of ~/.config/rtx/config.toml

Note that aliases are also stored in this file
but managed separately with `rtx aliases`

Usage: ls

Options:
  -h, --help
          Print help (see a summary with '-h')

Examples:
  $ rtx settings
  legacy_version_file = false

rtx settings set

Add/update a setting

This modifies the contents of ~/.config/rtx/config.toml

Usage: set <KEY> <VALUE>

Arguments:
  <KEY>
          The setting to set

  <VALUE>
          The value to set

Options:
  -h, --help
          Print help (see a summary with '-h')

Examples:
  $ rtx settings set legacy_version_file true

rtx settings unset

Clears a setting

This modifies the contents of ~/.config/rtx/config.toml

Usage: unset <KEY>

Arguments:
  <KEY>
          The setting to remove

Options:
  -h, --help
          Print help (see a summary with '-h')

Examples:
  $ rtx settings unset legacy_version_file

rtx uninstall

removes runtime versions

Usage: uninstall <RUNTIME>...

Arguments:
  <RUNTIME>...
          runtime(s) to remove

Options:
  -h, --help
          Print help (see a summary with '-h')


Examples:
  $ rtx uninstall nodejs@18 # will uninstall ALL nodejs-18.x versions
  $ rtx uninstall nodejs    # will uninstall ALL nodejs versions

rtx version

Show rtx version

Usage: version

Options:
  -h, --help
          Print help

与asdf的比较

rtx基本上是asdf的克隆,但在一些显著领域已经进行了改进。

性能

asdf做出了(我认为)一个不好的设计决策,使用介于对运行时的调用和运行时本身之间的shim文件。例如:当你调用node时,它将调用一个asdf shim文件~/.asdf/shims/node,然后该文件调用asdf exec,然后调用正确的node版本。

这些shim文件性能极差,每次调用都会增加约200毫秒。rtx不使用shim,而是更新PATH,以便在简单地调用二进制文件时不产生任何开销。这些shim文件是我写这个的主要原因。

我认为asdf不可能解决这个问题。asdf的作者对性能问题进行了很好的总结性能问题。asdf是用bash编写的,这当然使得它很难具有高性能,但我认为真正的问题是shim设计。我认为不可能在不完全重写的情况下解决这个问题。

rtx每次目录更改时都会调用一个内部命令rtx hook-env,但由于它是用Rust编写的,所以在我的机器上非常快——只需约2毫秒。

总结:asdf在调用运行时时会增加开销(约200毫秒),而rtx在更改目录时会增加少量开销(约2毫秒)。

环境变量

asdf只帮助管理运行时可执行文件。然而,一些工具是通过环境变量管理的(特别是Java,它通过JAVA_HOME进行切换)。asdf在这方面支持得不是很好,需要单独的shell扩展来管理。

但是asdf的插件有一个bin/exec-env脚本来导出环境变量,如JAVA_HOME。rtx只是将插件中的环境变量导出到bin/exec-env脚本中,但将它们放置在shell中的所有命令中。在asdf中,只有在调用shim时才会导出这些命令。这意味着如果你调用java,它将设置JAVA_HOME,但如果你调用Java工具(如mvn),则不会。

这意味着我们只是在使用现有的插件脚本,但由于rtx不使用shim,它可以用于更多的事情。可以轻松制作一个插件,导出任意环境变量,如dotenvdirenv

用户体验

在asdf中,一些命令是相同的,但其他命令已经更改。asdf中可能实现的所有功能都应在rtx中实现,但可能使用稍微不同的语法。rtx拥有更宽容的命令,例如使用模糊匹配,例如:rtx install nodejs@18。而在asdf中,您可以运行asdf install nodejs latest:18,但在.tool-versions文件或许多其他地方,您不能使用latest:18。在rtx中,您可以在任何地方使用模糊匹配。

如果插件未安装,asdf需要几个步骤来安装新的运行时,例如。

$ asdf plugin add nodejs
$ asdf install nodejs latest:18
$ asdf local nodejs latest:18

rtx中,这些都可以在单个步骤中完成,以设置本地运行时版本。如果需要安装插件和/或运行时,它将提示。

$ asdf local nodejs@18
rtx: Would you like to install [email protected]? [Y/n] Y
Trying to update node-build... ok
Downloading node-v18.13.0-darwin-arm64.tar.gz...
-> https://node.org.cn/dist/v18.13.0/node-v18.13.0-darwin-arm64.tar.gz
Installing node-v18.13.0-darwin-arm64...
Installed node-v18.13.0-darwin-arm64 to /Users/jdx/.local/share/rtx/installs/nodejs/18.13.0
$ node -v
v18.13.0

我发现asdf特别僵化且难以学习。它还做出了奇怪的决定,例如有asdf list allasdf latest --all(为什么一个是一个标志,另一个是一个位置参数?)。rtx大量使用别名,因此您不需要记住它是rtx plugin add nodejs还是rtx plugin install nodejs。如果您可以猜到您想的是什么,那么我会尝试让rtx以正确的方式响应。

话虽如此,asdf有很多优点。它是最好的多运行时管理器,我对插件系统印象深刻。作者做出的大多数设计决策都非常好。我真正只有2个抱怨:shims和它是用Bash编写的。

direnv

direnv和rtx都基于目录管理环境变量。因为它们都在各自相应的“hook”命令运行前后分析当前环境变量,所以它们很容易冲突并覆盖彼此的环境变量(包括但不限于PATH)。

为了避免这种情况,不要与direnv一起使用rtx activate。相反,在direnv内部调用rtx,以便它可以单独跟踪环境变量。

为此,首先使用rtx构建一个您可以在.envrc文件中使用的use_rtx函数。

$ rtx direnv activate > ~/.config/direnv/lib/use_rtx.sh
# replace ~/.config with XDG_CONFIG_HOME if you've changed it

现在在您的.envrc文件中添加以下内容

use rtx

direnv将现在调用rtx以导出其环境变量。您需要确保将use_rtx添加到所有使用rtx的项目中(或使用direnv的source_up从子目录中加载它)。

缓存行为

rtx在许多地方使用缓存以提高效率。关于缓存保留多长时间的所有细节最终都将可配置。当前行为中可能存在一些差距,其中某些内容是硬编码的,但我很高兴添加更多设置以覆盖所需的任何配置。

以下我将解释围绕缓存使用的行为。如果您看到某些内容似乎没有更新,这是一个好地方开始。

简写仓库缓存

asdf维护一个简写仓库,它将插件简写名称(例如:nodejs)映射到完整仓库名称(例如:https://github.com/asdf-vm/asdf-nodejs)。

此信息存储在~/.local/share/rtx/repository中,如果请求简短名称,则默认每周更新一次。这类似于asdf的功能,但我正在考虑将其直接集成到代码库中,以便无需单独提取/维护。新插件添加的频率不高。

插件缓存

每个插件都有一个缓存,存储在~/.local/share/rtx/plugins/<PLUGIN>/.rtxcache.msgpack.gz。它存储了该插件的可用版本列表(rtx ls-remote <PLUGIN>)和旧版文件名(见下文)。

默认情况下,它每天更新一次,或者当显式调用rtx ls-remote时。该文件是gzip消息包,如果您想查看它,可以运行以下命令(需要msgpack-cli)。

cat ~/.local/share/rtx/plugins/nodejs/.rtxcache.msgpack.gz | gunzip | msgpack-cli decode

运行时缓存

每个运行时(例如语言版本:nodejs@20.0.0)都有一个名为"runtimeconf"的文件,存储在安装目录中,例如:~/.asdf/installs/nodejs/20.0.0/.rtxconf.msgpack。它存储了安装后不应更改的运行时信息。目前这只是插件在bin/list-bin-paths中定义的bin路径。默认情况下,这只是/bin。这是rtx在运行时激活时添加到PATH的路径列表。

我还没有看到具有动态 bin 路径的插件,但如果您找到了,请告诉我。如果是这种情况,我们可能需要将其缓存而不是静态的。

"Runtimeconf"以未压缩的消息包格式存储,可以使用以下方式查看

cat ~/.local/share/rtx/installs/nodejs/18.13.0/.rtxconf.msgpack | msgpack-cli decode

旧版文件缓存

如果启用,rtx将读取旧版文件名,例如.node-version,用于asdf-nodejs。这利用了插件调用时的缓存

  • list-legacy-filenames 在我看到的每个插件中,它只是返回一个静态的文件名列表,如".nvmrc .node-version"。它与标准"runtime"缓存一起缓存,默认情况下每天刷新一次。
  • parse-legacy-file 调用此插件二进制文件以解析旧版文件以获取版本。它相对昂贵,因此每个解析为旧版文件的文件都会缓存到~/.local/share/rtx/legacy_cache中。它将保留在缓存中,直到文件被修改。这是一个简单的文本文件,其中存储了旧版文件的路径,作为文件名的哈希。

开发

使用just运行测试

$ just test

使用以下方式检查代码库

$ just lint-fix

依赖项

~16–27MB
~420K SLoC