Skip to content

Commit

Permalink
Merge pull request #42 from solidusio/feature/enable-engines-conditio…
Browse files Browse the repository at this point in the history
…nally

Load Solidus engine extension files automatically
  • Loading branch information
aldesantis authored Feb 3, 2020
2 parents 128fd45 + 947778a commit cd4892d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 39 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module SolidusExtensionName
class Engine < Rails::Engine
engine_name 'solidus_extension_name'

include SolidusSupport::EngineExtensions::Decorators
include SolidusSupport::EngineExtensions

# ...
end
Expand All @@ -57,6 +57,26 @@ end
config.to_prepare(&method(:activate).to_proc)
```

#### Loading files conditionally

If you include `EngineExtensions` in your extension and structure your files according to the
expected paths, they will be loaded automagically only when the relevant Solidus engines are
available.

Here's what an example structure may look like:

- `lib/views/backend`: will only be added to the view paths when `solidus_backend` is available.
- `lib/controllers/backend`: will only be added to the controller paths when `solidus_backend` is
available.
- `lib/decorators/backend`: will only be added to the decorator paths when `solidus_backend` is
available.

The same goes for `frontend` and `api`.

We strongly recommend following this structure and making your extensions so that they're not
dependent on anything other than `solidus_core`, only augmenting the functionality of the other
engines when they are available.

## Development

To install this gem onto your local machine, run `bundle exec rake install`. To release a new
Expand Down
75 changes: 74 additions & 1 deletion lib/solidus_support/engine_extensions.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,76 @@
# frozen_string_literal: true

require_relative 'engine_extensions/decorators'
module SolidusSupport
module EngineExtensions
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
deprecate_constant 'Decorators', 'SolidusSupport::EngineExtensions'

def self.included(engine)
engine.extend ClassMethods

engine.class_eval do
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?
end
end

module ClassMethods
def activate
if Rails.respond_to?(:autoloaders) && Rails.autoloaders.main
# Add decorators folder to the Rails autoloader. This tells Zeitwerk to treat paths
# such as app/decorators/controllers as roots.
solidus_decorators_root.glob('*') do |decorators_folder|
Rails.autoloaders.main.push_dir(decorators_folder)
end
end

load_solidus_decorators_from(solidus_decorators_root)
end

# Loads decorator files.
#
# This is needed since they are never explicitly referenced in the application code and
# won't be loaded by default. We need them to be executed regardless in order to decorate
# existing classes.
def load_solidus_decorators_from(path)
path.glob('**/*.rb') do |decorator_path|
require_dependency(decorator_path)
end
end

private

# Returns the root for this engine's decorators.
#
# @return [Path]
def solidus_decorators_root
root.join('app/decorators')
end

# Enables support for a Solidus engine.
#
# This will tell Rails to:
#
# * add +lib/controllers/[engine]+ to the controller paths;
# * add +lib/views/[engine]+ to the view paths;
# * load the decorators in +lib/decorators/[engine]+.
#
# @see #load_solidus_decorators_from
def enable_solidus_engine_support(engine)
paths['app/controllers'] << "lib/controllers/#{engine}"
paths['app/views'] << "lib/views/#{engine}"

engine_context = self
config.to_prepare do
engine_context.instance_eval do
path = root.join("lib/decorators/#{engine}")
load_solidus_decorators_from(path)
end
end
end
end
end
end
37 changes: 0 additions & 37 deletions lib/solidus_support/engine_extensions/decorators.rb

This file was deleted.

2 changes: 2 additions & 0 deletions solidus_support.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Gem::Specification.new do |s|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_dependency 'activesupport', ['>= 5.2', '< 7.0.x']

s.add_development_dependency 'bundler'
s.add_development_dependency 'rake'
s.add_development_dependency 'rspec-rails'
Expand Down

0 comments on commit cd4892d

Please sign in to comment.