在rbenv中复制以前版本的Ruby中的gem

我用rbenv安装了Ruby 1.9.3-p286。 现在,在安装了较新版本(p327)之后,很明显,它对以前版本安装的GEM一无所知。

是否可以将Gems从该版本复制到较新版本,以便不再需要将它们全部下载?

我一直在从升级和重新安装的角度来看这个,而不下载。 这不是微不足道的,我建议你做一些gem的清理,以尽量减少需要完成的处理/安装量(例如,我安装了五个版本的ZenTest;在这之前我做了’gem cleanup ZenTest’)。 但要小心’gem cleanup’,因为它删除了除LAST版本之外的所有版本:如果你需要支持旧版本的Rails,请手动清理你不需要的版本。

我将此脚本称为“migrate-gems.sh”:

#! /bin/bash if [ ${#} -ne 2 ]; then echo >&2 Usage: $(basename ${0}) old-version new-version exit 1 fi home_path=$(cd ~; pwd -P) old_version=${1} new_version=${2} rbenv shell ${old_version} declare -a old_gem_paths old_gems old_gem_paths=($(gem env gempath | sed -e 's/:/ /')) rbenv shell ${new_version} for ogp in "${old_gem_paths[@]}"; do case "${ogp}" in ${home_path}/.gem/ruby*|*/.gem/ruby*) # Skip ~/.gem/ruby. continue ;; esac for old_gem in $(ls -1 ${ogp}/cache/*.gem); do gem install --local --ignore-dependencies ${ogp}/cache/${old_gem} done done 

这项工作有三个部分:

  1. gem env gempath包含安装gem的路径( : gem env gempath )。 因为gem在〜/ .gem / ruby​​中共享,所以我跳过这个。
  2. gem install接受--local ,它强制没有网络连接。
  3. gem install接受--ignore-dependencies ,它禁用依赖项检查。

我今天有一个相当大的gem列表,我不想从rubygems.org下载(另外,我需要旧版本),所以我很快就把它掀起了。

你可以复制gems/bin/文件夹,但这会导致麻烦。
bin/文件中包含硬编码路径。

我建议改为重新安装它们,如下所示:

 $ rbenv local 1.9.3-p286 $ gem list | cut -d" " -f1 > my-gems $ rbenv local 1.9.3-p327 $ gem in $(cat my-gems) 

对于后代,我写了rbenv-copy-gems.sh来帮助我做到这一点。 它不符合这个问题的标准(它安装在互联网上,而不是本地安装),但是当我通过rbenv安装升级或安装新版本的Ruby时,它对我很有用。

当前版本粘贴在下面以供参考,但随着我的改进,我保持了最新的要点。

 #!/bin/bash # copy is a misnomer; it's actually LIST + INSTALL # --from 2.2.1 [--to other-version-else-whatever-is-currently-set] # # TODO: install only most-recent version that's installed in FROM # TODO: use gem names only from FROM, install latest available version (might be more recent than in FROM) # TODO: pass arguments to gem command (eg --no-document) CURRENT_VERSION=`rbenv version | cut -d' ' -f1` GEM_LIST_ARGS="--local" while [[ $# -gt 0 ]]; do option="$1" case $option in --from) FROM="$2" shift ;; --to) TO="$2" shift ;; esac shift # past argument or value done if [ -z "${FROM}" ]; then FROM="${CURRENT_VERSION}" fi if [ -z "${TO}" ]; then TO="${CURRENT_VERSION}" fi echo ">>> Install gems from v${FROM} to v${TO}" # Get gems and versions, reformat to GEMNAME:version[,version[...]] gems=(`RBENV_VERSION=${FROM} gem list ${GEM_LIST_ARGS} | sed -e 's/[\(\)]//g' -e 's/, /,/g' -e 's/ /:/'`) for geminfo in "${gems[@]}"; do gem=`echo $geminfo | cut -d: -f1` versions=(`echo $geminfo | sed -e 's/^.*://' -e 's/,/ /g'`) for version in "${versions[@]}"; do installed=`RBENV_VERSION=${TO} gem query -i $gem -v $version` if [ "${installed}" == "false" ]; then echo ">>> Installing ${gem} ${version}:" RBENV_VERSION=${TO} gem install $gem -v $version else echo ">>> ${gem} ${version} already installed" fi echo "" done done