solidus_support 0.12.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88870615f95d8fe0794ee093b13f2875de6c84390a137352c196c7a6aa97d469
4
- data.tar.gz: 2aa7188af2b42c60e90201d4b366673ed4f1b8333cc31d11ce9da7fde534e659
3
+ metadata.gz: 2cdd9849818af1dc56048136d30a8198d6d79c7245250824283659a47c396932
4
+ data.tar.gz: e82afa4bcca816ad08c7b0afb4ff09279104c99c111818d96ba26cf0f7dab2f7
5
5
  SHA512:
6
- metadata.gz: 2f090251b1f4511057d6ec13781d63af4e951d3875818c157b7382e55c1d654a05ff464569af85fdafaa021a0ac3c998af29d29b3a70acb776c976e1becbb943
7
- data.tar.gz: dfa6ba3b3ac590ac623f1c707edfb1d09ce369435bb8508feba37feed3908dcacc59c35b9b01ecf3774c3378d42d68c038472c318596e689d30190b43d002b92
6
+ metadata.gz: f619198e4c09da849dbab523854002358b35183d9c1cf13c5a24ae4001a986b6d5c38c5edc8d4ea06412581f4f14080a0abc1628d948409dbf47dc7be5364ee0
7
+ data.tar.gz: bb3060ebe160c24dca44376cab8d5c1cdb3bf377cc47312a1a70d15eaeabee3df045d566d464433f86b0943a24dbd5e2cbfd907a89c21374808defc0a054de72
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![CircleCI](https://dl.circleci.com/status-badge/img/gh/solidusio/solidus_support/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/solidusio/solidus_support/tree/main)
2
+
1
3
  # SolidusSupport
2
4
 
3
5
  This gem contains common runtime functionality for Solidus extensions.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/deprecation"
4
+ require "flickwerk"
4
5
 
5
6
  module SolidusSupport
6
7
  module EngineExtensions
@@ -9,6 +10,7 @@ module SolidusSupport
9
10
 
10
11
  def self.included(engine)
11
12
  engine.extend ClassMethods
13
+ engine.include Flickwerk
12
14
 
13
15
  engine.class_eval do
14
16
  solidus_decorators_root.glob('*') do |decorators_folder|
@@ -27,6 +29,25 @@ module SolidusSupport
27
29
  module ClassMethods
28
30
  def activate
29
31
  load_solidus_decorators_from(solidus_decorators_root)
32
+ load_solidus_subscribers_from(solidus_subscribers_root)
33
+ end
34
+
35
+ # Loads Solidus event subscriber files.
36
+ #
37
+ # This allows to add event subscribers to extensions without explicitly subscribing them,
38
+ # similarly to what happens in Solidus core.
39
+ def load_solidus_subscribers_from(path)
40
+ if SolidusSupport::LegacyEventCompat.using_legacy?
41
+ path.glob("**/*_subscriber.rb") do |subscriber_path|
42
+ require_dependency(subscriber_path)
43
+ end
44
+
45
+ if Spree::Event.respond_to?(:activate_all_subscribers)
46
+ Spree::Event.activate_all_subscribers
47
+ else
48
+ Spree::Event.subscribers.each(&:subscribe!)
49
+ end
50
+ end
30
51
  end
31
52
 
32
53
  # Loads decorator files.
@@ -83,7 +104,7 @@ module SolidusSupport
83
104
  # by those gems, we work around those gems by adding our paths before
84
105
  # `initialize_cache`, which is the Rails initializer called before
85
106
  # `set_load_path`.
86
- initializer "#{name}_#{engine}_paths", before: :initialize_cache do
107
+ initializer "#{engine_name}_#{engine}_paths", before: :initialize_cache do
87
108
  if SolidusSupport.send(:"#{engine}_available?")
88
109
  paths['app/controllers'] << "lib/controllers/#{engine}"
89
110
  paths['app/views'] << "lib/views/#{engine}"
@@ -92,9 +113,11 @@ module SolidusSupport
92
113
 
93
114
  if SolidusSupport.send(:"#{engine}_available?")
94
115
  decorators_path = root.join("lib/decorators/#{engine}")
116
+ patches_path = root.join("lib/patches/#{engine}")
95
117
  controllers_path = root.join("lib/controllers/#{engine}")
96
118
  components_path = root.join("lib/components/#{engine}")
97
119
  config.autoload_paths += decorators_path.glob('*')
120
+ config.autoload_paths += patches_path.glob("*")
98
121
  config.autoload_paths << controllers_path if controllers_path.exist?
99
122
  config.autoload_paths << components_path if components_path.exist?
100
123
 
@@ -105,6 +128,30 @@ module SolidusSupport
105
128
  end
106
129
  end
107
130
  end
131
+
132
+ initializer "#{engine_name}_#{engine}_patch_paths" do
133
+ patch_paths = root.join("lib/patches/#{engine}").glob("*")
134
+ Flickwerk.patch_paths += patch_paths
135
+ end
136
+
137
+ initializer "#{engine_name}_#{engine}_user_patches" do |app|
138
+ app.reloader.to_prepare do
139
+ Flickwerk.aliases["Spree.user_class"] = Spree.user_class_name
140
+ end
141
+ end
142
+
143
+ initializer "eager_load_#{engine_name}_#{engine}_patches" do |app|
144
+ # Solidus versions < 4.5 `require` some of their application code.
145
+ # This leads to hard-to-debug problems with Flickwerk patches.
146
+ # What this does is eager-load all the patches in a `to_prepare`
147
+ # hook by constantizing them.
148
+ # You can override this behavior by setting the environment variable `SOLIDUS_LAZY_LOAD_PATCHES`.
149
+ if Spree.solidus_gem_version < Gem::Version.new("4.5.0.a") && !ENV["SOLIDUS_LAZY_LOAD_PATCHES"]
150
+ app.reloader.to_prepare do
151
+ Flickwerk.patches.each_value { _1.each(&:constantize) }
152
+ end
153
+ end
154
+ end
108
155
  end
109
156
  end
110
157
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusSupport
4
+ module LegacyEventCompat
5
+ # Compatibility for some event-driven operations
6
+ module Bus
7
+ # Publication of an event
8
+ #
9
+ # If extensions want to support the legacy sytem, they need to use a
10
+ # compatible API. That means it's not possible to publish an instance as
11
+ # event, which is something supported by Omnes but not the legacy adapter.
12
+ # Instead, a payload can be given. E.g.:
13
+ #
14
+ # ```
15
+ # SolidusSupport::LegacyEventCompat::Bus.publish(:foo, bar: :baz)
16
+ # ```
17
+ #
18
+ # Legacy subscribers will receive an
19
+ # `ActiveSupport::Notifications::Fanout`, while omnes subscribers will get
20
+ # an `Omnes::UnstructuredEvent`. Both instances are compatible as they
21
+ # implement a `#payload` method.
22
+ #
23
+ # @param event_name [Symbol]
24
+ # @param payload [Hash<Symbol, Any>]
25
+ def self.publish(event_name, **payload)
26
+ SolidusSupport.deprecator.warn(
27
+ "SolidusSupport::LegacyEventCompat::Bus is deprecated and will be removed in solidus_support 1.0." \
28
+ " Please use Spree::Bus.publish instead."
29
+ )
30
+ if SolidusSupport::LegacyEventCompat.using_legacy?
31
+ Spree::Event.fire(event_name, payload)
32
+ else
33
+ Spree::Bus.publish(event_name, **payload, caller_location: caller_locations(1)[0])
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "omnes"
5
+ rescue LoadError
6
+ end
7
+
8
+ module SolidusSupport
9
+ module LegacyEventCompat
10
+ # Compatibility for subscriber modules
11
+ #
12
+ # Thanks to this module, extensions can create legacy subscriber modules
13
+ # (see {Spree::Event::Subscriber}) and translate them automatically to an
14
+ # {Omnes::Subscriber}). E.g.:
15
+ #
16
+ # ```
17
+ # module MyExtension
18
+ # module MySubscriber
19
+ # include Spree::Event::Subscriber
20
+ # include SolidusSupport::LegacyEventCompat::Subscriber
21
+ #
22
+ # event_action :order_finalized
23
+ #
24
+ # def order_finalized(event)
25
+ # event.payload[:order].do_something
26
+ # end
27
+ # end
28
+ # end
29
+ #
30
+ # MyExtension::MySubscriber.omnes_subscriber.subscribe_to(Spree::Bus)
31
+ # ```
32
+ #
33
+ # The generated omnes subscriptions will call the corresponding legacy
34
+ # subscriber method with the omnes event. It'll compatible as long as the
35
+ # omnes event responds to the `#payload` method (see
36
+ # {Omnes::UnstructuredEvent}).
37
+ module Subscriber
38
+ # @api private
39
+ ADAPTER = lambda do |legacy_subscriber, legacy_subscriber_method, _omnes_subscriber, omnes_event|
40
+ legacy_subscriber.send(legacy_subscriber_method, omnes_event)
41
+ end
42
+
43
+ def self.included(legacy_subscriber)
44
+ SolidusSupport.deprecator.warn(
45
+ "SolidusSupport::LegacyEventCompat::Subscriber is deprecated and will be removed in solidus_support 1.0." \
46
+ " Please `include Omnes::Subscriber` in `#{legacy_subscriber.name}` instead."
47
+ )
48
+ legacy_subscriber.define_singleton_method(:omnes_subscriber) do
49
+ @omnes_subscriber ||= Class.new.include(::Omnes::Subscriber).tap do |subscriber|
50
+ legacy_subscriber.event_actions.each do |(legacy_subscriber_method, event_name)|
51
+ subscriber.handle(event_name.to_sym, with: ADAPTER.curry[legacy_subscriber, legacy_subscriber_method])
52
+ end
53
+ end.new
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'solidus_support/legacy_event_compat/bus'
4
+ require 'solidus_support/legacy_event_compat/subscriber'
5
+
6
+ module SolidusSupport
7
+ # Compatibility middleman for {Spree::Event} and {Spree::Bus}
8
+ #
9
+ # Solidus v3.2 changed to use [Omnes](https://github.com/nebulab/omnes) as the
10
+ # backbone for event-driven behavior (see {Spree::Bus}) by default. Before
11
+ # that, a custom adapter based on {ActiveSupport::Notifications} was used (see
12
+ # {Spree::Event}. Both systems are still supported on v3.2.
13
+ #
14
+ # This module provides compatibility support so that extensions can easily
15
+ # target both systems regardless of the underlying circumstances:
16
+ #
17
+ # - Solidus v3.2 with the new system.
18
+ # - Solidus v3.2 with the legacy system.
19
+ # - Solidus v2.9 to v3.1, when only {Spree::Event} existed.
20
+ # - Possible future versions of Solidus, whether the legacy system is
21
+ # eventually removed or not.
22
+ module LegacyEventCompat
23
+ # Returns whether the application is using the legacy event system
24
+ #
25
+ # @return [Boolean]
26
+ def self.using_legacy?
27
+ legacy_present? &&
28
+ (legacy_alone? ||
29
+ legacy_chosen?)
30
+ end
31
+
32
+ def self.legacy_present?
33
+ defined?(Spree::Event)
34
+ end
35
+ private_class_method :legacy_present?
36
+
37
+ def self.legacy_alone?
38
+ !Spree::Config.respond_to?(:use_legacy_events)
39
+ end
40
+ private_class_method :legacy_alone?
41
+
42
+ def self.legacy_chosen?
43
+ Spree::Config.use_legacy_events
44
+ end
45
+ private_class_method :legacy_chosen?
46
+ end
47
+ end
@@ -3,15 +3,10 @@
3
3
  module SolidusSupport
4
4
  module Migration
5
5
  def self.[](version)
6
- if Rails.gem_version >= Gem::Version.new('5.x')
7
- ActiveRecord::Migration[version]
8
- else
9
- # Rails < 5 doesn't support specifying rails version of migrations, but
10
- # it _is_ rails 4.2, so we can use that when requested.
11
- return ActiveRecord::Migration if version.to_s == '4.2'
12
-
13
- raise ArgumentError, "Unknown migration version '#{version}'; expected one of '4.2'"
14
- end
6
+ SolidusSupport.deprecator.warn(
7
+ "SolidusSupport::Migration[#{version}] is deprecated. Please use ActiveRecord::Migration[#{version}] instead."
8
+ )
9
+ ActiveRecord::Migration[version]
15
10
  end
16
11
  end
17
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidusSupport
4
- VERSION = '0.12.0'
4
+ VERSION = '0.14.0'
5
5
  end
@@ -3,6 +3,7 @@
3
3
  require 'solidus_support/version'
4
4
  require 'solidus_support/deprecator'
5
5
  require 'solidus_support/migration'
6
+ require 'solidus_support/legacy_event_compat'
6
7
  require 'solidus_support/engine_extensions'
7
8
  require 'solidus_core'
8
9
 
@@ -28,6 +28,9 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
+ spec.add_dependency 'flickwerk', '~> 0.3.4'
32
+ spec.add_dependency 'solidus_core', '~> 4.1'
33
+
31
34
  spec.add_development_dependency 'rails'
32
35
  spec.add_development_dependency 'bundler'
33
36
  spec.add_development_dependency 'rake'
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe SolidusSupport::LegacyEventCompat::Bus do
4
+ describe '#publish' do
5
+ if SolidusSupport::LegacyEventCompat.using_legacy?
6
+ it 'forwards to Spree::Event' do
7
+ box = nil
8
+ subscription = Spree::Event.subscribe(:foo) { |event| box = event.payload[:bar] }
9
+
10
+ described_class.publish(:foo, bar: :baz)
11
+
12
+ expect(box).to be(:baz)
13
+ ensure
14
+ Spree::Event.unsubscribe(subscription)
15
+ end
16
+ else
17
+ it 'forwards to Spree::Bus' do
18
+ box = nil
19
+ Spree::Bus.register(:foo)
20
+ subscription = Spree::Bus.subscribe(:foo) { |event| box = event.payload[:bar] }
21
+
22
+ described_class.publish(:foo, bar: :baz)
23
+
24
+ expect(box).to be(:baz)
25
+ ensure
26
+ Spree::Bus.unsubscribe(subscription)
27
+ Spree::Bus.registry.unregister(:foo)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'omnes'
4
+
5
+ RSpec.describe SolidusSupport::LegacyEventCompat::Subscriber, if: Spree.solidus_version < Gem::Version.new("4.0.0.dev") do
6
+ subject { Module.new.include(Spree::Event::Subscriber).include(described_class) }
7
+
8
+ describe '#omnes_subscriber' do
9
+ it 'returns an Omnes::Subscriber' do
10
+ subject.module_eval do
11
+ event_action :foo
12
+
13
+ def foo(_event); end
14
+ end
15
+
16
+ expect(subject.omnes_subscriber.is_a?(Omnes::Subscriber)).to be(true)
17
+ end
18
+
19
+ it 'adds single-event definitions matching legacy event actions' do
20
+ subject.module_eval do
21
+ event_action :foo
22
+
23
+ def foo(_event); end
24
+ end
25
+ bus = Omnes::Bus.new
26
+ bus.register(:foo)
27
+
28
+ subscriptions = subject.omnes_subscriber.subscribe_to(bus)
29
+
30
+ event = Struct.new(:omnes_event_name).new(:foo)
31
+ expect(subscriptions.first.matches?(event)).to be(true)
32
+ end
33
+
34
+ it 'coerces event names given as Strings' do
35
+ subject.module_eval do
36
+ event_action 'foo'
37
+
38
+ def foo(_event); end
39
+ end
40
+ bus = Omnes::Bus.new
41
+ bus.register(:foo)
42
+
43
+ subscriptions = subject.omnes_subscriber.subscribe_to(bus)
44
+
45
+ event = Struct.new(:omnes_event_name).new(:foo)
46
+ expect(subscriptions.first.matches?(event)).to be(true)
47
+ end
48
+
49
+ it 'executes legacy event action methods as handlers with the omnes event' do
50
+ subject.module_eval do
51
+ event_action :foo
52
+
53
+ def foo(event)
54
+ event[:bar]
55
+ end
56
+ end
57
+ bus = Omnes::Bus.new
58
+ bus.register(:foo)
59
+
60
+ subscriptions = subject.omnes_subscriber.subscribe_to(bus)
61
+
62
+ expect(
63
+ bus.publish(:foo, bar: :baz).executions.first.result
64
+ ).to be(:baz)
65
+ end
66
+
67
+ it 'distingish when event name is given explicitly' do
68
+ subject.module_eval do
69
+ event_action :foo, event_name: :bar
70
+
71
+ def foo(_event)
72
+ :bar
73
+ end
74
+ end
75
+ bus = Omnes::Bus.new
76
+ bus.register(:bar)
77
+
78
+ subscriptions = subject.omnes_subscriber.subscribe_to(bus)
79
+
80
+ expect(
81
+ bus.publish(:bar).executions.first.result
82
+ ).to be(:bar)
83
+ end
84
+
85
+ it "returns the same omnes subscriber instance if called again" do
86
+ expect(subject.omnes_subscriber).to be(subject.omnes_subscriber)
87
+ end
88
+
89
+ it "doesn't fail when no event action has been defined" do
90
+ expect { subject.omnes_subscriber }.not_to raise_error
91
+ end
92
+ end
93
+ end
@@ -14,9 +14,6 @@ module DummyApp
14
14
  class Application < ::Rails::Application
15
15
  config.eager_load = false
16
16
  config.paths['config/database'] = File.expand_path('dummy_app/database.yml', __dir__)
17
- if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR < 1
18
- config.active_record.legacy_connection_handling = false
19
- end
20
17
  end
21
18
  end
22
19
 
metadata CHANGED
@@ -1,16 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Hawthorn
8
8
  - Solidus Team
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2024-12-17 00:00:00.000000000 Z
11
+ date: 2025-02-11 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: flickwerk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: solidus_core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.1'
14
41
  - !ruby/object:Gem::Dependency
15
42
  name: rails
16
43
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +150,6 @@ dependencies:
123
150
  - - "~>"
124
151
  - !ruby/object:Gem::Version
125
152
  version: 0.2.2
126
- description:
127
153
  email: contact@solidus.io
128
154
  executables: []
129
155
  extensions: []
@@ -146,9 +172,14 @@ files:
146
172
  - lib/solidus_support.rb
147
173
  - lib/solidus_support/deprecator.rb
148
174
  - lib/solidus_support/engine_extensions.rb
175
+ - lib/solidus_support/legacy_event_compat.rb
176
+ - lib/solidus_support/legacy_event_compat/bus.rb
177
+ - lib/solidus_support/legacy_event_compat/subscriber.rb
149
178
  - lib/solidus_support/migration.rb
150
179
  - lib/solidus_support/version.rb
151
180
  - solidus_support.gemspec
181
+ - spec/solidus_support/legacy_event_compat/bus_spec.rb
182
+ - spec/solidus_support/legacy_event_compat/legacy_event_compat_spec.rb
152
183
  - spec/solidus_support_spec.rb
153
184
  - spec/spec_helper.rb
154
185
  - spec/support/dummy_app.rb
@@ -160,7 +191,6 @@ metadata:
160
191
  homepage_uri: https://github.com/solidusio/solidus_support
161
192
  source_code_uri: https://github.com/solidusio/solidus_support
162
193
  changelog_uri: https://github.com/solidusio/solidus_support/releases
163
- post_install_message:
164
194
  rdoc_options: []
165
195
  require_paths:
166
196
  - lib
@@ -175,11 +205,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
205
  - !ruby/object:Gem::Version
176
206
  version: '0'
177
207
  requirements: []
178
- rubygems_version: 3.5.22
179
- signing_key:
208
+ rubygems_version: 3.6.3
180
209
  specification_version: 4
181
210
  summary: Common runtime helpers for Solidus extensions.
182
211
  test_files:
212
+ - spec/solidus_support/legacy_event_compat/bus_spec.rb
213
+ - spec/solidus_support/legacy_event_compat/legacy_event_compat_spec.rb
183
214
  - spec/solidus_support_spec.rb
184
215
  - spec/spec_helper.rb
185
216
  - spec/support/dummy_app.rb