ti-enxame.com

Faça o bundler usar gemas diferentes para plataformas diferentes

Estou trabalhando na atualização de um de nossos aplicativos Rails 2.3.8 para Rails 3) e encontrei um problema irritante com empacotador e implantação. o aplicativo em uma máquina Windows, mas o ambiente de produção está executando o Ubuntu Linux. Agora, meu problema é que o empacotador está ignorando a gema mysql no ambiente de produção, e o Passenger cospe: "!!! Faltando a gema do mysql. Adicione-a ao seu Gemfile: gem 'mysql', '2.8.1'"

Aqui está o meu 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

Como você pode ver, a gema mysql é especificada. No entanto, ao implantar, o bundler o ignora. Por quê? O motivo é que o Bundler gera o seguinte Gemfile.lock (Apenas partes relevantes incluídas):

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

Observe que ele inclui a gema específica da plataforma. Obviamente, NÃO é isso que eu quero que faça, pois essa gema não é adequada (e aparentemente ignorada) ao executar no Linux.

Então, o Bundler oferece alguma maneira de lidar com esses problemas? Ou tenho que lembrar de alterar manualmente a versão do mysql gem no Gemfile.lock Gerado toda vez que executo a instalação do pacote na minha máquina de desenvolvimento?

Agradeço antecipadamente!

Atualização

Parece que a equipe do bundler está ciente disso questão .

46
Daniel Abrahamsson

Este é um problema conhecido no Bundler . As soluções alternativas são:

  • Gere um Gemfile.lock em um sistema semelhante ao seu ambiente de produção para obter resultados que correspondam à sua plataforma de produção. Efetivamente, isso significa que você só pode gerar o arquivo Gemfile.lock no Windows se o seu sistema de produção for o Windows.
  • Não confirme um arquivo Gemfile.lock e determine as dependências na máquina de produção no momento da implantação (bundle install sem --deploy). Embora não seja recomendado em geral, essa é uma solução alternativa usada com freqüência até que o bug seja corrigido. Por exemplo, esta é a solução recomendada oferecida pela Heroku.
  • Alterne para o JRuby, que teria a mesma cadeia de plataformas no Windows e no Linux (Java). Eu não recomendo isso a sério, mas acredito que isso resolveria o problema.
  • Corrija o problema no código-fonte do Bundler, ou seja, ajude a equipe do Bundler a corrigir o erro. :)
37
wuputah

Eu tenho um problema semelhante. Eu gostaria de poder escrever algo assim no meu Gemfile:

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

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

Mas, o bundler me diz que não tenho permissão. Portanto, minha solução alternativa, que funciona nesse caso específico, é apontar um intervalo de versões:

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

Que - no momento - fornece a versão 1.4.4.1 no meu computador com Windows e 1.5.0.beta.2 no meu computador linux. Talvez seja possível escrever uma solução alternativa feia semelhante ;-)

8
Stefan Pettersson

Nossos engenheiros da Engine Yard enviaram um patch para o Bundler para solucionar esse problema e descongelar as gemas em uma plataforma diferente. Estamos enfrentando o mesmo problema com muitos Windows tentando implantar depois de executar o Tutorial de demonstração do RailsInstaller. A melhor correção encontrada foi a seguinte:

  1. bundle install Normalmente na sua máquina de desenvolvimento
  2. Passe pelo Gemfile.lock E, se houver alguma linha com -x86-mingw32, Remova essa parte.
    • bcrypt-Ruby (3.0.1-x86-mingw32) torna-se bcrypt-Ruby (3.0.1)
  3. Adicione Ruby na seção 'Plataformas' em Gemfile.lock
  4. Certifique-se de especificar explicitamente a gema necessária no Gemfile com o sinalizador da plataforma. (Não tenho certeza se isso é necessário, mas não dói)
    • Em Gemfile: `gem 'bcrypt-Ruby', '~> 3.0',: platform => 'Ruby'
  5. bundle install Novamente, que manterá a linha bcrypt-Ruby (3.0.1) e adicionará bcrypt-Ruby (3.0.1-x86-mingw32) novamente.

Se você estiver curioso sobre o patch do Bundler, poderá receber notificações em https://github.com/carlhuda/bundler/pull/1451

Espero que isso ajude quem ainda está procurando respostas.

5
Evan Machnic

Eu já tive esse problema antes, e o uso da mysql2 gem realmente corrige o problema. Sei que não é a resposta que você está procurando, mas combine isso com a resposta de Diego e você é de ouro.

2
bouchard

Você já tentou usar rvm ( link aqui )? Ele pode instalar máquinas isoladas Ruby Máquinas Virtuais e Gemsets, para que você possa trabalhar com um ambiente mais parecido com o que você tem em produção. Sinceramente, não sei se isso resolverá seus problemas, mas é Vale a pena experimentar.

Enfim, eu sei que essa não é a resposta que você deseja ouvir, mas o IMHO Windows não é o melhor uso de plataforma ao desenvolver no Rails. Recentemente, comprei um MacBook principalmente para desenvolver aplicativos Rails, ele evita muitas dores de cabeça. Você também pode instalar o Linux em sua máquina de desenvolvimento e usá-lo, é muito melhor do que usar portas Windows ou Cygwin.

2
Fábio Batista

Eu acho que o problema é que a gema mysql não descobre adequadamente os cabeçalhos necessários. Você pode consertar isso usando o gem do mysql2 , basta atualizar os adaptadores do banco de dados em database.yml para integração do ActiveRecord.

Além disso, você pode passar sinalizadores de construção para C estendendo gemas se for absolutamente necessário:

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

2
Daniel Mendel

Não cometa Gemfile.lock e suas jóias para produção. Você tem que executar bundler install novamente em produção.

1
Joshua Partogi

Você pode fazer algo assim:

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

Aliás, você deve colocar seu Gemfile.lock no controle de versão, pois dessa forma todas as máquinas executarão o aplicativo com as mesmas versões de gemas.

1
Diego Carrion

Me deparei com esse problema e acabei escrevendo um roteiro para essa dolorosa tarefa. http://gouravtiwari.blogspot.com/2011/03/development-on-windows-deploying-to.html

0
gouravtiwari21