From 202e77c2d7887ee1edb7bf352b5a942e71b5176c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Busqu=C3=A9?= Date: Thu, 10 Jun 2021 05:20:39 +0200 Subject: [PATCH 1/2] Fix dependency on the engines load order when adding paths We were adding the view and controller paths at engine loading time. So, E.g., if a frontend engine was present, but we loaded it after the extension depending on `solidus_support` (i.e., the extension went first on the `Gemfile`), paths weren't being loaded. We're adding the paths on an initializer that runs before Rails's [`:initialize_dependency_mechanism`](https://github.com/rails/rails/blob/127dd06df66552dd272eea7832f8bb205cf6fd01/railties/lib/rails/application/bootstrap.rb#L68) one. Thenceforth Rails begins messing with the load paths, and it doesn't take them into account anymore. Keep in mind that the `SolidusSupport.#{engine}_available?` call needs to be placed within the `initializer` context and not wrapping it. The reason is the same as above: don't doing the logic at load time. --- lib/solidus_support/engine_extensions.rb | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/solidus_support/engine_extensions.rb b/lib/solidus_support/engine_extensions.rb index c3375da..54065d2 100644 --- a/lib/solidus_support/engine_extensions.rb +++ b/lib/solidus_support/engine_extensions.rb @@ -15,9 +15,9 @@ def self.included(engine) config.to_prepare(&method(:activate)) - enable_solidus_engine_support('backend') if SolidusSupport.backend_available? - enable_solidus_engine_support('frontend') if SolidusSupport.frontend_available? - enable_solidus_engine_support('api') if SolidusSupport.api_available? + enable_solidus_engine_support('backend') + enable_solidus_engine_support('frontend') + enable_solidus_engine_support('api') end end @@ -82,17 +82,23 @@ def solidus_subscribers_root # # @see #load_solidus_decorators_from def enable_solidus_engine_support(engine) - paths['app/controllers'] << "lib/controllers/#{engine}" - paths['app/views'] << "lib/views/#{engine}" + initializer "#{name}_#{engine}_paths", before: :initialize_dependency_mechanism do + if SolidusSupport.send(:"#{engine}_available?") + paths['app/controllers'] << "lib/controllers/#{engine}" + paths['app/views'] << "lib/views/#{engine}" + end + end - path = root.join("lib/decorators/#{engine}") + if SolidusSupport.send(:"#{engine}_available?") + path = root.join("lib/decorators/#{engine}") - config.autoload_paths += path.glob('*') + config.autoload_paths += path.glob('*') - engine_context = self - config.to_prepare do - engine_context.instance_eval do - load_solidus_decorators_from(path) + engine_context = self + config.to_prepare do + engine_context.instance_eval do + load_solidus_decorators_from(path) + end end end end From 47c7ca7f384e47cdd9a51a07de841cbf7259c8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Busqu=C3=A9?= Date: Thu, 10 Jun 2021 05:30:35 +0200 Subject: [PATCH 2/2] Allow detecting Solidus components through a Rails setting This allows us to define solidus components at the application level, in contrast to the typical engine definition. Components paths are loaded on an initializer, which runs before the application code that could define an `Engine` class. Adding a setting on the `application.rb`, which runs before the initializers, helps us working around it. For now, we keep the old detection mechanism, as the other extensions will need to adapt to it first. --- lib/solidus_support.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/solidus_support.rb b/lib/solidus_support.rb index c649f1d..5b4312f 100644 --- a/lib/solidus_support.rb +++ b/lib/solidus_support.rb @@ -68,15 +68,26 @@ def payment_method_parent_class(credit_card: false) end def frontend_available? - defined?(Spree::Frontend::Engine) + defined?(Spree::Frontend::Engine) || + rails_config?(:frontend_available, true) end def backend_available? - defined?(Spree::Backend::Engine) + defined?(Spree::Backend::Engine) || + rails_config?(:backend_available, true) end def api_available? - defined?(Spree::Api::Engine) + defined?(Spree::Api::Engine) || + rails_config?(:api_available, true) + end + + def rails_config?(name, value) + return false unless Rails.application + + Rails.configuration.x.respond_to?(:solidus) && + Rails.configuration.x.solidus.respond_to?(name) && + (Rails.configuration.x.solidus.send(name) == value) end end end