Заставить бандлер использовать разные гемы для разных платформ - PullRequest
46 голосов
/ 04 сентября 2010

Я работаю над обновлением одного из наших приложений Rails 2.3.8 до Rails 3, и столкнулся с досадной проблемой с пакетированием и развертыванием.Я разрабатываю приложение на компьютере под управлением Windows, но производственная среда работает под управлением Ubuntu Linux.Теперь моя проблема в том, что упаковщик игнорирует гем mysql в производственной среде, и Пассажир выплевывает: "!!! Отсутствует драгоценный камень mysql. Добавьте его в свой Gemfile: gem 'mysql', '2.8.1 '"

Вот мой Gemfile:

# Edit this Gemfile to bundle your application's dependencies.
# This preamble is the current preamble for Rails 3 apps; edit as needed.
source 'http://rubygems.org'

gem 'rails', '3.0.0'
gem 'net-ldap', :require => 'net/ldap'
gem 'highline', :require => 'highline/import'
gem 'mysql', '2.8.1'
gem 'net-ssh', :require => 'net/ssh'

# Bundle gems for the local environment. Make sure to
# put test-only gems in this group so their generators
# and rake tasks are available in development mode:
group :development, :test do
  gem 'fakeweb', :require => 'fakeweb'
  gem 'flexmock', :require => 'flexmock/test_unit'
end

Как видите, указан камень mysql.Однако при развертывании, bundler игнорирует его.Зачем?Причина в том, что Bundler генерирует следующие Gemfile.lock (только соответствующие части включены):

....
mime-types (1.16)
mysql (2.8.1-x86-mingw32)
net-ldap (0.1.1)
....

Обратите внимание, что он включает в себя конкретный гем платформы.Это явно НЕ то, что я хочу, потому что этот гем не подходит (и явно игнорируется) при работе под Linux.

Итак, есть ли у Bundler какой-либо способ справиться с этими проблемами?Или я должен помнить, что нужно вручную менять версию mysql gem в сгенерированном Gemfile.lock каждый раз, когда я запускаю пакетную установку на моей машине для разработки?

Заранее спасибо!

Обновление

Кажется, команда разработчиков знает об этой проблеме .

Ответы [ 9 ]

37 голосов
/ 06 ноября 2010

Это известная проблема в Bundler . Обходные пути:

  • Создайте Gemfile.lock в системе, достаточно похожей на вашу производственную среду, чтобы получить результаты, соответствующие вашей производственной платформе. Фактически это означает, что вы можете сгенерировать файл Gemfile.lock в Windows только в том случае, если ваша производственная система - Windows.
  • Ни в коем случае не фиксируйте файл Gemfile.lock, а определяйте зависимости от рабочей машины во время развертывания (bundle install без --deploy). Хотя это и не рекомендуется в целом, это часто используемый обходной путь, пока ошибка не будет устранена. Например, это рекомендуемое решение, предлагаемое Heroku.
  • Переключиться на JRuby, который будет иметь одинаковую строку платформы для Windows и Linux (java). Я не рекомендую это серьезно, но я верю, что это решит проблему.
  • Исправить проблему в исходном коде Bundler, то есть помочь команде Bundler исправить ошибку. :)
8 голосов
/ 07 декабря 2010

У меня похожая проблема. Я хотел бы иметь возможность написать что-то вроде этого в моем Gemfile:

platforms :ruby do                      # linux
  gem 'nokogiri', "1.5.0.beta.2" 
end

platforms :mswin do
  gem 'nokogiri', "1.4.4.1" 
end

Но Бандлер говорит, что мне не разрешено. Итак, мой обходной путь, который работает в данном конкретном случае, - указать диапазон версий:

gem 'nokogiri', ">= 1.4.4.1", "<=1.5.0.beta.2" 

Который - на данный момент - дает версию 1.4.4.1 на моем компьютере с Windows и 1.5.0.beta.2 на моем компьютере с Linux. Возможно, вам удастся написать похожий уродливый обходной путь; -)

5 голосов
/ 04 октября 2011

Наши инженеры в Engine Yard представили Bundler патч для решения этой проблемы и разморозки драгоценных камней, если они находятся на другой платформе. У нас возникла та же проблема со многими Windows, которые пытались развернуть после запуска демонстрационного учебника по RailsInstaller. Лучшее найденное нами исправление - выполнить следующее:

  1. bundle install как обычно на вашей машине для разработки
  2. Пройдите через Gemfile.lock и, если есть строки с -x86-mingw32, удалите эту часть.
    • bcrypt-ruby (3.0.1-x86-mingw32) становится bcrypt-ruby (3.0.1)
  3. Добавьте ruby в разделе «Платформы» в Gemfile.lock
  4. Обязательно явно укажите необходимый драгоценный камень в Gemfile с флагом платформы. (Не уверен, если это необходимо, но это не больно)
    • В Gemfile: `gem 'bcrypt-ruby', '~> 3.0',: platform => 'ruby'
  5. bundle install снова, что сохранит строку bcrypt-ruby (3.0.1) и добавит bcrypt-ruby (3.0.1-x86-mingw32) снова.

Если вам интересен патч Bundler, вы можете получить уведомления на https://github.com/carlhuda/bundler/pull/1451

Надеюсь, это поможет любому, кто все еще ищет ответы.

2 голосов
/ 08 ноября 2010

Вы пытались использовать rvm ( ссылка здесь )? Он может устанавливать изолированные виртуальные машины Ruby и Gemsets, чтобы вы могли работать в среде, более похожей на ту, которая у вас есть в рабочей среде. Честно говоря, я не знаю, решит ли это ваши проблемы, но стоит попробовать.

В любом случае, я знаю, что это не тот ответ, который вы хотели бы услышать, но ИМХО Windows - не лучшее использование платформы при разработке в Rails. Я недавно купил MacBook в основном для разработки приложений на Rails, он избавляет вас от многих головных болей. Вы также можете установить Linux на свой компьютер для разработки и использовать его, это намного лучше, чем использовать порты Windows или Cygwin.

2 голосов
/ 04 ноября 2010

Я сталкивался с этой проблемой ранее, и использование гема mysql2 действительно решает проблему. Я знаю, что это не тот ответ, который вы ищете, но объедините его с ответом Диего , и вы получите золото.

2 голосов
/ 03 ноября 2010

Я думаю, что проблема в том, что самоцвет mysql не может правильно найти необходимые заголовки. Вы можете исправить это, перейдя к использованию mysql2 gem , вам просто нужно обновить свои адаптеры базы данных в database.yml для интеграции ActiveRecord.

Кроме того, вы можете передавать флаги сборки на C, расширяющие гемы, если это абсолютно необходимо:

bundle config build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config.

1 голос
/ 20 сентября 2010

Вы можете сделать что-то вроде этого:

platforms :ruby do
  gem "sqlite3-ruby", :require => "sqlite3", :group => [:development, :test]
end

platforms :jruby do
  gem 'activerecord-jdbc-adapter', :require => false
  gem "jdbc-sqlite3", :require => false
end

Кстати, вы должны поместить свой Gemfile.lock в систему управления версиями, потому что таким образом все машины будут запускать приложение с одинаковыми версиями gems.

1 голос
/ 05 сентября 2010

Не передавайте Gemfile.lock и ваши драгоценные камни в производство. Вы должны снова запустить bundler install на производстве.

0 голосов
/ 24 марта 2011

Я столкнулся с этой проблемой, а затем закончил писать сценарий для этой болезненной задачи. http://gouravtiwari.blogspot.com/2011/03/development-on-windows-deploying-to.html

...