Копирование драгоценных камней из предыдущей версии Ruby в rbenv
Я установил Ruby 1.9.3-p286 с rbenv. Теперь, после установки более новой версии (p327), очевидно, что она ничего не знает о GEM, установленных с предыдущей версией.
Можно ли копировать Gems из этой версии в новую, чтобы не понадобилось снова загружать их?
Ответы
Ответ 1
Я рассматривал это специально с точки зрения обновления и переустановки без загрузки. Это не тривиально, и я рекомендую вам выполнить некоторую очистку ваших драгоценных камней, чтобы свести к минимуму количество обработки/установки, которое необходимо выполнить (например, у меня было пять версий ZenTest, я сделал "очистку Gem ZenTest", прежде чем делать это). Будьте осторожны с 'gem cleanup', хотя, поскольку он удаляет все, кроме LAST-версии: если вам нужно поддерживать более старую версию Rails, вручную очищайте версии, которые вам не нужны.
Я назвал этот script '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
Есть три части, которые делают эту работу:
-
gem env gempath
содержит пути (:
-separated), где установлены камни. Потому как
драгоценные камни разделяются в ~/.gem/ruby, я пропускаю этот.
-
gem install
принимает --local
, что не приводит к сетевым соединениям.
-
gem install
принимает --ignore-dependencies
, что отключает проверку зависимостей.
У меня был довольно большой список драгоценных камней, чтобы переместиться сегодня, и я не хотел скачивать с rubygems.org(плюс, мне нужны более старые версии), поэтому я быстро взбивал их.
Ответ 2
вы можете скопировать папки 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)
Ответ 3
Для потомков я написал rbenv-copy-gems.sh, чтобы помочь мне это сделать. Он не соответствует критериям этого вопроса (он устанавливается из Интернета, а не локально), но он был полезен для меня, когда я обновляю или устанавливаю новую версию Ruby через установку rbenv.
Текущая версия, вставленная ниже для справки, но я сохраняю суть до тех пор, пока я делаю улучшения.
#!/bin/bash
# copy is a misnomer; it actually LIST + INSTALL
# --from 2.2.1 [--to other-version-else-whatever-is-currently-set]
#
# TODO: install only most-recent version that 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