Копиране на скъпоценни камъни от предишна версия на Ruby в rbenv

Инсталирах Ruby 1.9.3-p286 с rbenv. Сега, след като инсталира по-нова версия (p327), очевидно не знае нищо за GEM, инсталирани с предишната версия.

Възможно ли е да копирате Gems от тази версия в по-новата, така че да не е необходимо да ги изтегляте отново?


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
Браво, благодаря! BTW, gem list --no-versions е по-просто от cut. Може да бъде съвместим в бъдеще, ако има промени в начина на изброяване на скъпоценните камъни. - 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