Сделать упаковщик использовать разные драгоценные камни для разных платформ
Я работаю над обновлением одного из наших приложений Rails 2.3.8 до Rails 3 и столкнулся с раздражающей проблемой с пакетом и развертыванием. Я разрабатываю приложение на компьютере под управлением Windows, но в рабочей среде работает Ubuntu Linux. Теперь моя проблема заключается в том, что связка игнорирует драгоценный камень mysql
в рабочей среде, а Passenger выплевывает: "!!! Отсутствует gem mysql. Добавьте его в свой Gemfile: gem 'mysql', '2.8. 1'"
Вот мой Gemfile
:
# Edit this Gemfile to bundle your application 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 генерирует следующие Gemfile.lock
(только соответствующие части включены):
....
mime-types (1.16)
mysql (2.8.1-x86-mingw32)
net-ldap (0.1.1)
....
Обратите внимание, что он включает в себя конкретную платформу. Это, очевидно, НЕ то, что я хочу сделать, поскольку этот камень не подходит (и игнорируется) при работе под Linux.
Итак, подходит ли Bundler для решения этих проблем? Или я должен помнить, чтобы вручную изменить версию gem mysql в сгенерированном Gemfile.lock
каждый раз, когда я запускаю установку пакета на моей машине разработки?
Заранее благодарю вас!
Обновление
Кажется, что сборщик знает об этом issue.
Ответы
Ответ 1
Это известная проблема в Bundler. Обходные пути:
- Создайте файл Gemfile.lock в системе, достаточно похожей на вашу производственную среду, и получите результаты, соответствующие вашей производственной платформе. Фактически это означает, что вы можете генерировать только файл Gemfile.lock в Windows, если ваша производственная система - Windows.
- Не храните файл Gemfile.lock вообще и не определяйте зависимости на рабочей машине во время развертывания (
bundle install
без --deploy
). Хотя это не рекомендуется вообще, это часто используемый метод обхода, пока ошибка не будет исправлена. Например, это рекомендуемое решение, предлагаемое Heroku.
- Переключиться на JRuby, который будет иметь одну и ту же платформенную строку как для Windows, так и для Linux (
java
). Я не рекомендую это серьезно, но я считаю, что это устранит проблему.
- Исправить проблему в исходном коде Bundler, т.е. помочь команде Bundler исправить ошибку.:)
Ответ 2
У меня есть аналогичная проблема. Я хотел бы написать что-то подобное в моем 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-компьютере. Возможно, вы можете написать аналогичное уродливое обходное решение; -)
Ответ 3
Наши инженеры в Engine Yard представили Bundler патч для решения этой проблемы и разморозки драгоценных камней, если на другой платформе. Мы столкнулись с такой же проблемой, когда многие Windows пытались развернуть ее после запуска RodyInstaller Demo Tutorial. Лучшее исправление, которое мы обнаружили, состоит в том, чтобы выполнить следующее:
-
bundle install
как обычно на вашей машине разработки.
- Пройдите через
Gemfile.lock
, и если есть строки с -x86-mingw32
, удалите эту часть.
-
bcrypt-ruby (3.0.1-x86-mingw32)
становится bcrypt-ruby (3.0.1)
- Добавить
ruby
в разделе "Платформы" в Gemfile.lock
- Обязательно укажите нужный камень в
Gemfile
с флагом платформы. (Не уверен, что это необходимо, но это не повредит)
- В
Gemfile
: `gem 'bcrypt-ruby', '~ > 3.0',: platform = > 'ruby'
-
bundle install
, который сохранит строку bcrypt-ruby (3.0.1)
и добавит в bcrypt-ruby (3.0.1-x86-mingw32)
снова.
Если вам интересно узнать о патче Bundler, вы можете получать уведомления в https://github.com/carlhuda/bundler/pull/1451
Надеюсь, это поможет любому, кто все еще ищет ответы.
Ответ 4
Я думаю, что проблема в том, что gem mysql неправильно обнаруживает нужные заголовки. Вы можете исправить это, перейдя к использованию mysql2 gem, вам просто нужно обновить адаптеры базы данных в database.yml
для интеграции ActiveRecord.
Кроме того, вы можете передавать флаги сборки на C, расширяя камни, если это абсолютно необходимо:
bundle config build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config
.
Ответ 5
Я столкнулся с этой проблемой раньше, и использование mysql2 gem действительно устраняет проблему. Я знаю, что не тот ответ, который вы ищете, но соедините его с Diego, и вы золотые.
Ответ 6
Вы пробовали использовать ссылку rvm
(здесь)? Он может устанавливать изолированные Ruby Virtual Machines и Gemsets, поэтому вы можете работать с окружением, более похожим на тот, который у вас есть на производстве. Я честно не знаю, разрешит ли он ваши проблемы, но это стоит того.
В любом случае, я знаю, что это не тот ответ, который вы хотите услышать, но IMHO Windows - это не лучшее использование платформы при разработке в Rails. Недавно я купил MacBook для разработки приложений Rails, это избавляет вас от множества головных болей. Вы также можете установить Linux на свою машину разработки и использовать ее, это лучше, чем использование портов Windows или Cygwin.
Ответ 7
Не совершайте Gemfile.lock
и ваши драгоценные камни для производства. Вы должны снова запустить bundler install
в процессе производства.
Ответ 8
Вы можете сделать что-то вроде этого:
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
Btw, вы должны поместить свой Gemfile.lock в элемент управления версиями, потому что таким образом все машины будут запускать приложение с теми же версиями драгоценных камней.
Ответ 9
Я столкнулся с этой проблемой, а затем закончил писать script для этой болезненной задачи.
http://gouravtiwari.blogspot.com/2011/03/development-on-windows-deploying-to.html