Копирование драгоценных камней из предыдущей версии Ruby в rbenv

Я установил Ruby 1.9.3-p286 с помощью rbenv. Теперь, после установки более новой версии (p327), очевидно, он ничего не знает о GEM, установленных с предыдущей версией.

Можно ли скопировать драгоценные камни из этой версии в более новую, чтобы не нужно было загружать их все заново?


person ArashM    schedule 30.11.2012    source источник


Ответы (3)


Я смотрел на это специально с точки зрения обновления и переустановки без загрузки. Это не тривиально, и я рекомендую вам выполнить некоторую очистку ваших драгоценных камней, чтобы свести к минимуму объем необходимой обработки/установки (например, у меня было установлено пять версий ZenTest; перед этим я выполнил «очистку драгоценных камней ZenTest»). Однако будьте осторожны с «очисткой драгоценных камней», так как она удаляет все, кроме ПОСЛЕДНЕЙ версии: если вам нужно поддерживать более старую версию 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/ruby, я пропускаю этот пункт.
  2. gem install принимает --local, что не требует подключения к сети.
  3. gem install принимает --ignore-dependencies, что отключает проверку зависимостей.

У меня был довольно большой список драгоценных камней, которые нужно было перенести сегодня, и я не хотел скачивать их с rubygems.org (плюс, мне нужны были более старые версии), поэтому я довольно быстро это сделал.

person Community    schedule 31.01.2013
comment
Я немного изменил его, и теперь он работает! Я составил для этого суть: gist.github.com/4701056 - person ArashM; 03.02.2013
comment
Вероятно, в этом разница между BSD-ish ls (у меня Mac) и GNU-ish ls (у вас Ubuntu). Правильное решение, вероятно, просто использовать ${ogp}/cache/$(basename ${old_gem}). Вы получите некоторые ошибки — некоторые старые драгоценные камни просто несовместимы с более новым Ruby — но в целом это будет работать довольно хорошо. - person Austin Ziegler; 03.02.2013

Можно скопировать папки gems/ и bin/, но это приведет к проблемам. Файлы в bin/ имеют жестко заданные пути.

Я бы рекомендовал переустановить их, что было бы так же просто:

$ rbenv local 1.9.3-p286
$ gem list | cut -d" " -f1 > my-gems
$ rbenv local 1.9.3-p327
$ gem install $(cat my-gems)
person Community    schedule 30.11.2012
comment
хм... Я думал, что может быть лучший способ. Спасибо, в любом случае :) - person ArashM; 30.11.2012
comment
лучший способ - сохранить Gemfile в своей домашней папке, а при установке новой версии просто установить на нее bundler. тогда вы просто делаете bundle install в своей домашней папке :) - person ; 30.11.2012
comment
Собственно, основная проблема здесь в том, что я не хочу снова скачивать гемы. Так что это тоже не поможет. - person ArashM; 30.11.2012
comment
Хорошо, спасибо! Кстати, gem list --no-versions проще, чем вырезать. Это может быть совместимо с будущим, если будут изменения в том, как перечислены драгоценные камни. - person Ivan; 16.10.2014

Для потомков я написал rbenv-copy-gems.sh, чтобы помочь мне в этом. Он не соответствует критериям этого вопроса (устанавливается из Интернета, а не локально), но мне это было полезно, когда я обновлял или устанавливал новую версию Ruby через rbenv install.

Текущая версия вставлена ​​ниже для справки, но я обновляю суть по мере внесения улучшений.

#!/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 (e.g. --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
person Jim Meyer    schedule 07.07.2016
comment
p.s. Если вы назовете выбранный вами сценарий «rbenv-copy-gems.sh», сделаете его исполняемым и поместите его где-нибудь в своем пути, вы можете rbenv shell <to-version> && rbenv copy-gems --from <from-version> или rbenv copy-gems --from <from-version> --to <to-version> - person Jim Meyer; 07.07.2016