engems
engems copied to clipboard
Question about runtime dependencies inside engines .gemspec file
Hi,
The first step I'm trying to accomplish for now is just to have runtime dependencies shared by engines to be in one place.
In order to do that, I've created a /gemfiles
folder at root with *.gemfiles and then including them with eval_gemfile
inside engines.
# gemfiles/http.gemfile
gem 'rest-client', '2.1.0'
# engines/authentication/Gemfile
source 'https://rubygems.org'
eval_gemfile '../../gemfiles/rails.gemfile'
eval_gemfile '../../gemfiles/http.gemfile'
...
The problem is that I need to require the rest-client
at engines/authentication/lib/authentication.rb
to make it available inside engine runtime:
require "authentication/version"
require "authentication/engine"
require "rest-client"
module Authentication
....
end
But, to make this work, I must define rest-client
inside engine's .gemspec (spec.add_dependency). But if I do that, it looses the purpose of the eval_gemfile
for sharing versions.
Sorry if I'm misunderstanding the concept.
Thanks.
I must define rest-client inside engine's .gemspec (spec.add_dependency). But if I do that, it looses the purpose of the eval_gemfile for sharing versions.
.gemspec
is for requirements, not freezing versions; you may have a relaxed spec for rest-client
in your .gemspec
(e.g., ~> 2.0
).
Do you use the shared lock file strategy?
Hi, sorry about long time since I've posted this.
.gemspec
is for requirements, not freezing versions; you may have a relaxed spec forrest-client
in your.gemspec
(e.g.,~> 2.0
).
Right, I've now properly set dependencies with the shared lock file strategy. The application now starts and everything loads as expected!
The only issue I've struggling to resolve/understand is around testing (with rspec). I'm using the latest script version that you've updated from @maiksimov sample repo. As far as I undertood, each component declared in the root Gemfile with:
component 'my_component', namespace: "engines"
will dynamically create a group (group component_group do
) with it's name. That way, dummy app from engine should be able to load only dependencies related by configuring Bundler.require(:my_component)
inside /config/application.rb
The error I'm getting when running rspec
command from engine is that I can't figure out the cause. If I run with *Rails.groups
it loads everything but works.

Some things I didn't understand, that can be related:
- Why it has
eval_gemfile
andgem
declarations in first two lines? https://github.com/palkan/test-rails-project/blob/main/engines/test-engine/Gemfile.dev - Everytime I run
rspec
, a Gemfile.lock is generated inside the engine (I've configured /.bundle/config)
Appreciate with any help!
Why it has eval_gemfile and gem declarations in first two lines?
The first one defines where to find local deps; the second uses .gemspec
to get the dependencies. Without the first line, Bundler wouldn't know how to satisfy local deps.
Everytime I run rspec, a Gemfile.lock is generated inside the engine (I've configured /.bundle/config)
Do you run it with bundle exec
?
The error I'm getting when running rspec command
This error doesn't seem to relevant; it looks like spec_helper.rb
(or rails_helper.rb
) is loaded twice 'cause Rails app to be initialized twice, which leads to this exception.
Try to wrap require "<...>/environment"
with begin; rescue; exit; end
to see the actual error (see https://github.com/palkan/engems/blob/6b824b182676dedc10ba88ea3aa5764e36f40e14/examples/generators/engine/templates/spec/rails_helper.rb.tt#L15-L37).