cuprum 1.3.1 → 1.4.0.rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14265461b44d0a9546c04be4d5a66605d285e35ead5740e346875287b88e38b7
4
- data.tar.gz: 3730d8d83bf5382cdedd1fb8cb88684f615e2e3082ae4ae00cc61d77caa392d5
3
+ metadata.gz: 9f6ec18e2fe571f668e7b78c03e29a741ce51ce5bc41371e71b067000eb873e9
4
+ data.tar.gz: ce36aa169b233f3ffd50fa65b69f3f58d042319a92d345ab3727876d2343a36a
5
5
  SHA512:
6
- metadata.gz: 0fd517bac27cad11527308fbb2aa1a65b85b42e9ae10e870583eb5f52be807b913a3931dc15ce2d11ef576824b9220a46ba23466a402080d6e15d3832c55f59a
7
- data.tar.gz: 0e5330ab7482b7ed596a09159fff5ad2bd8600410e9a8381759d965a2f6ee902295220748d6e1d335dcca025d8c40d20bca313abb0119eb814b8cf61d3fbfed0
6
+ metadata.gz: 998790ba05c7e95186c45a2df84375e112c6113f7723c91e25818dd5a9759fad59dcbd7ac445dd041e598500401234d9af6e4f99cf1a0e2d2bcff73e01ee89ce
7
+ data.tar.gz: a12caa0abe108b96463dc1998eedca0c1325bffe22e649d0c38af583bb624139bda5dd0ed6c37eef72584de6a8cc48fb1d44ea86953cab1279140a00e3e19772
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.0
4
+
5
+ The "Signs And Portents" Update
6
+
7
+ As of version 1.3.0, Cuprum will no longer support Ruby 3.1 or 3.2.
8
+
9
+ Added `Cuprum.initializer` to initialize dependencies and error messages. Call `Cuprum.initializer.call` in the entry point or initializers of your application to avoid missing error messages.
10
+
11
+ ### Errors
12
+
13
+ Errors now support defining messages using `SleepingKingStudios::Tools::Messages` or by defining a `:MESSAGE` constant, including support for named parameters (see `Kernel#format`).
14
+
15
+ You can now store `Exception`-like backtraces for `Cuprum::Error` objects. There are two ways to generate a backtrace for an error:
16
+
17
+ - Pass `backtrace: true` when calling `Error.new` for a specific error.
18
+ - Set the `CUPRUM_ERROR_BACKTRACE=true` environment flag to store backtraces for all errors.
19
+
20
+ ### Results
21
+
22
+ Added `Result.success` and `Result.failure`, which provide singleton results with respective `:success` and `:failure` statuses.
23
+
24
+ Updated `Cuprum::ResultList` to inherit from `Cuprum::Result`.
25
+
26
+ ### RSpec
27
+
28
+ Updated `ParameterValidationExamples` to support lazy evaluation of the `message:` parameter, as well as any additional parameters passed along with `type:`. Parameters passed as a `Proc` will be evaluated in the context of the current example group.
29
+
3
30
  ## 1.3.1
4
31
 
5
32
  Added support for Ruby 4.0.
data/README.md CHANGED
@@ -37,7 +37,7 @@ On the opposite end of the scale, frameworks such as [Dry::Monads](https://dry-r
37
37
 
38
38
  ## Compatibility
39
39
 
40
- Cuprum is tested against Ruby (MRI) 3.1 through 3.4.
40
+ Cuprum is tested against Ruby (MRI) 3.3 through 4.0.
41
41
 
42
42
  ## Documentation
43
43
 
@@ -0,0 +1,7 @@
1
+ ---
2
+ cuprum:
3
+ errors:
4
+ command_not_implemented: 'no implementation defined for %<class_name>s'
5
+ invalid_parameters: 'invalid parameters for %<class_name>s - %<failure_messages>s'
6
+ multiple_errors: 'the command encountered one or more errors'
7
+ operation_not_called: '%<class_name>s was not called and does not have a result'
@@ -106,13 +106,12 @@ module Cuprum::Currying
106
106
  args = [*arguments, *args]
107
107
  kwargs = keywords.merge(kwargs)
108
108
 
109
- # rubocop:disable Style/RedundantParentheses
109
+ # rubocop:disable-next Style/RedundantParentheses
110
110
  if kwargs.empty?
111
111
  command.call(*args, &(override || block))
112
112
  else
113
113
  command.call(*args, **kwargs, &(override || block))
114
114
  end
115
- # rubocop:enable Style/RedundantParentheses
116
115
  end
117
116
  end
118
117
  end
data/lib/cuprum/error.rb CHANGED
@@ -52,22 +52,32 @@ module Cuprum
52
52
  class Error
53
53
  # Short string used to identify the type of error.
54
54
  #
55
- # Primarily used for serialization. This value can be overriden by passing
55
+ # Primarily used for serialization. This value can be overridden by passing
56
56
  # in the :type parameter to the constructor.
57
57
  #
58
58
  # Subclasses of Cuprum::Error should define their own default TYPE constant.
59
59
  TYPE = 'cuprum.error'
60
60
 
61
+ # @param backtrace [true, false] if true, captures a backtrace from
62
+ # Kernel.caller. Defaults to false unless the
63
+ # ENV['CUPRUM_ERROR_BACKTRACE'] flag is set to true.
61
64
  # @param message [String] Optional message describing the nature of the
62
65
  # error.
63
66
  # @param properties [Hash] Additional properties used to compare errors.
64
67
  # @param type [String] Short string used to identify the type of error.
65
- def initialize(message: nil, type: nil, **properties)
66
- @message = message
67
- @type = type || self.class::TYPE
68
+ def initialize(backtrace: false, message: nil, type: nil, **properties)
69
+ @type = type || self.class::TYPE
70
+ @message = message || default_message_for(**properties)
71
+ @backtrace = caller if backtrace || capture_backtrace?
68
72
  @comparable_properties = properties.merge(message:, type:)
69
73
  end
70
74
 
75
+ # @return [Array<String>, nil] the captured backtrace when the error was
76
+ # created, if any.
77
+ #
78
+ # @see Kernel#caller
79
+ attr_reader :backtrace
80
+
71
81
  # @return [String] optional message describing the nature of the error.
72
82
  attr_reader :message
73
83
 
@@ -86,9 +96,9 @@ module Cuprum
86
96
  # Generates a serializable representation of the error object.
87
97
  #
88
98
  # By default, contains the #type and #message properties and an empty :data
89
- # Hash. This can be overriden in subclasses by overriding the private method
90
- # #as_json_data; this should always return a Hash with String keys and whose
91
- # values are basic objects or data structures of the same.
99
+ # Hash. This can be overridden in subclasses by overriding the private
100
+ # method #as_json_data; this should always return a Hash with String keys
101
+ # and whose values are basic objects or data structures of the same.
92
102
  #
93
103
  # @return [Hash<String, Object>] a serializable hash representation of the
94
104
  # error.
@@ -109,5 +119,29 @@ module Cuprum
109
119
  def as_json_data
110
120
  {}
111
121
  end
122
+
123
+ def capture_backtrace?
124
+ ENV.fetch('CUPRUM_ERROR_BACKTRACE', 'false') == 'true'
125
+ end
126
+
127
+ def default_message_for(**parameters)
128
+ if type && !(type.respond_to?(:empty?) && type.empty?)
129
+ message = tools.messages.message(type, default: nil, parameters:)
130
+
131
+ return message if message
132
+ end
133
+
134
+ format_default_message(parameters)
135
+ end
136
+
137
+ def format_default_message(parameters)
138
+ return unless self.class.const_defined?(:MESSAGE)
139
+
140
+ format(self.class::MESSAGE, parameters)
141
+ rescue KeyError => exception
142
+ "Message missing parameters: #{type} #{exception.message}"
143
+ end
144
+
145
+ def tools = SleepingKingStudios::Tools::Toolbelt.instance
112
146
  end
113
147
  end
@@ -9,20 +9,18 @@ module Cuprum::Errors
9
9
  COMPARABLE_PROPERTIES = %i[command].freeze
10
10
  private_constant :COMPARABLE_PROPERTIES
11
11
 
12
- MESSAGE_FORMAT = 'no implementation defined for %s'
13
- private_constant :MESSAGE_FORMAT
14
-
15
12
  # Short string used to identify the type of error.
16
13
  TYPE = 'cuprum.errors.command_not_implemented'
17
14
 
18
- # @param command [Cuprum::Command] The command called without a definition.
19
- def initialize(command:)
15
+ # @param command [Cuprum::Command] the command called without a definition.
16
+ # @param backtrace [true, false] if true, captures a backtrace from
17
+ # Kernel.caller.
18
+ def initialize(command:, backtrace: nil)
20
19
  @command = command
21
20
 
22
21
  class_name = command&.class&.name || 'command'
23
- message = MESSAGE_FORMAT % class_name
24
22
 
25
- super(command:, message:)
23
+ super(backtrace:, class_name:, command:)
26
24
  end
27
25
 
28
26
  # @return [Cuprum::Command] The command called without a definition.
@@ -11,14 +11,20 @@ module Cuprum::Errors
11
11
 
12
12
  # @param command_class [Class] the class of the failed command.
13
13
  # @param failures [Array<String>] the messages for the failed validations.
14
- def initialize(command_class:, failures:)
15
- @command_class = command_class
16
- @failures = failures
14
+ # @param backtrace [true, false] if true, captures a backtrace from
15
+ # Kernel.caller.
16
+ def initialize(command_class:, failures:, backtrace: nil) # rubocop:disable Metrics/MethodLength
17
+ @command_class = command_class
18
+ @failures = failures
19
+ class_name = command_class.name
20
+ failure_messages = failures.join(', ')
17
21
 
18
22
  super(
23
+ backtrace:,
24
+ class_name:,
19
25
  command_class:,
20
26
  failures:,
21
- message: generate_message
27
+ failure_messages:
22
28
  )
23
29
  end
24
30
 
@@ -36,9 +42,5 @@ module Cuprum::Errors
36
42
  'failures' => failures.map(&:to_s)
37
43
  }
38
44
  end
39
-
40
- def generate_message
41
- "invalid parameters for #{command_class.name} - #{failures.join(', ')}"
42
- end
43
45
  end
44
46
  end
@@ -9,16 +9,15 @@ module Cuprum::Errors
9
9
  # Short string used to identify the type of error.
10
10
  TYPE = 'cuprum.errors.multiple_errors'
11
11
 
12
- # @param errors [Array<Cuprum::Error>] The wrapped errors.
13
- # @param message [String] Optional message describing the nature of the
12
+ # @param errors [Array<Cuprum::Error>] the wrapped errors.
13
+ # @param backtrace [true, false] if true, captures a backtrace from
14
+ # Kernel.caller.
15
+ # @param message [String] optional message describing the nature of the
14
16
  # error.
15
- def initialize(errors:, message: nil)
17
+ def initialize(errors:, backtrace: nil, message: nil)
16
18
  @errors = errors
17
19
 
18
- super(
19
- errors:,
20
- message: message || default_message
21
- )
20
+ super
22
21
  end
23
22
 
24
23
  # @return [Array<Cuprum::Error>] the wrapped errors.
@@ -31,9 +30,5 @@ module Cuprum::Errors
31
30
  'errors' => errors.map { |error| error&.as_json }
32
31
  }
33
32
  end
34
-
35
- def default_message
36
- 'the command encountered one or more errors'
37
- end
38
33
  end
39
34
  end
@@ -6,20 +6,17 @@ require 'cuprum/errors'
6
6
  module Cuprum::Errors
7
7
  # Error returned when trying to access the result of an uncalled Operation.
8
8
  class OperationNotCalled < Cuprum::Error
9
- MESSAGE_FORMAT = '%s was not called and does not have a result'
10
- private_constant :MESSAGE_FORMAT
11
-
12
9
  # Short string used to identify the type of error.
13
10
  TYPE = 'cuprum.errors.operation_not_called'
14
11
 
15
12
  # @param operation [Cuprum::Operation] The uncalled operation.
16
- def initialize(operation:)
13
+ # @param backtrace [true, false] if true, captures a backtrace from
14
+ # Kernel.caller.
15
+ def initialize(operation:, backtrace: nil)
17
16
  @operation = operation
18
-
19
17
  class_name = operation&.class&.name || 'operation'
20
- message = MESSAGE_FORMAT % class_name
21
18
 
22
- super(message:, operation:)
19
+ super(backtrace:, class_name:, message:, operation:)
23
20
  end
24
21
 
25
22
  # @return [Cuprum::Operation] The uncalled operation.
@@ -10,13 +10,15 @@ module Cuprum::Errors
10
10
  TYPE = 'cuprum.errors.uncaught_exception'
11
11
 
12
12
  # @param exception [StandardError] The exception that was raised.
13
+ # @param backtrace [true, false] if true, captures a backtrace from
14
+ # Kernel.caller.
13
15
  # @param message [String] A message to display. Will be annotated with
14
16
  # details on the exception and the exception's cause (if any).
15
- def initialize(exception:, message: 'uncaught exception')
17
+ def initialize(exception:, backtrace: nil, message: 'uncaught exception')
16
18
  @exception = exception
17
19
  @cause = exception.cause
18
20
 
19
- super(message: generate_message(message))
21
+ super(backtrace:, message: generate_message(message))
20
22
  end
21
23
 
22
24
  # @return [StandardError] the exception that was raised.
@@ -6,7 +6,7 @@ module Cuprum::ParameterValidation
6
6
  # @api private
7
7
  #
8
8
  # Value class representing a single validation for a parameter.
9
- class ValidationRule < Struct.new( # rubocop:disable Style/StructInheritance
9
+ class ValidationRule < Struct.new(
10
10
  :name,
11
11
  :type,
12
12
  :method_name,
data/lib/cuprum/result.rb CHANGED
@@ -5,6 +5,14 @@ require 'cuprum'
5
5
  module Cuprum
6
6
  # Data object that encapsulates the result of calling a Cuprum command.
7
7
  class Result
8
+ class << self
9
+ # @return [Cuprum::Result] a result with a status of :failure.
10
+ def failure = @failure ||= new(status: :failure)
11
+
12
+ # @return [Cuprum::Result] a result with a status of :success.
13
+ def success = @success ||= new(status: :success)
14
+ end
15
+
8
16
  # Enumerates the default permitted values for a Result#status.
9
17
  STATUSES = %i[success failure].freeze
10
18
 
@@ -4,6 +4,7 @@ require 'forwardable'
4
4
 
5
5
  require 'cuprum'
6
6
  require 'cuprum/errors/multiple_errors'
7
+ require 'cuprum/result'
7
8
 
8
9
  module Cuprum
9
10
  # Collection object that encapsulates a set of Cuprum results.
@@ -16,11 +17,11 @@ module Cuprum
16
17
  # endpoint that performs a bulk operation.
17
18
  #
18
19
  # @see Cuprum::Result.
19
- class ResultList
20
+ class ResultList < Cuprum::Result
20
21
  extend Forwardable
21
22
  include Enumerable
22
23
 
23
- UNDEFINED = Object.new.freeze
24
+ UNDEFINED = SleepingKingStudios::Tools::UNDEFINED
24
25
  private_constant :UNDEFINED
25
26
 
26
27
  # @!method each
@@ -47,55 +48,24 @@ module Cuprum
47
48
  def initialize(
48
49
  *results,
49
50
  allow_partial: false,
50
- error: UNDEFINED,
51
+ error: UNDEFINED,
51
52
  status: UNDEFINED,
52
- value: UNDEFINED
53
+ value: UNDEFINED
53
54
  )
54
55
  @allow_partial = allow_partial
55
56
  @results = normalize_results(results)
56
- @error = error == UNDEFINED ? build_error : error
57
- @status = status == UNDEFINED ? build_status : status
58
- @value = value == UNDEFINED ? values : value
57
+
58
+ error = build_error if error == UNDEFINED
59
+ status = build_status if status == UNDEFINED
60
+ value = values if value == UNDEFINED
61
+
62
+ super(error:, status:, value:)
59
63
  end
60
64
 
61
65
  # @return [Array<Cuprum::Result>] the wrapped results.
62
66
  attr_reader :results
63
67
  alias_method :to_a, :results
64
68
 
65
- # Returns the error for the result list.
66
- #
67
- # If the result list was initialized with an error, returns that error.
68
- #
69
- # If any of the results have errors, aggregates the result errors into a
70
- # Cuprum::MultipleErrors object.
71
- #
72
- # If none of the results have errors, returns nil.
73
- #
74
- # @return [Cuprum::Errors::MultipleErrors, Cuprum::Error, nil] the error for
75
- # the result list.
76
- attr_reader :error
77
-
78
- # Determines the status of the combined results.
79
- #
80
- # If the result list was initialize with a status, returns that status.
81
- #
82
- # If there are no failing results, i.e. the results array is empty or all of
83
- # the results are passing, returns :success.
84
- #
85
- # If there is at least one failing result, it instead returns :failure.
86
- #
87
- # If the :allow_partial flag is set to true, returns :success if the results
88
- # array is empty or there is at least one passing result. If there is at
89
- # least one failing result and no passing results, it instead returns
90
- # :failure.
91
- #
92
- # @return [:success, :failure] the status of the combined results.
93
- attr_reader :status
94
-
95
- # @return [Object] The value of the result. Defaults to the mapped values of
96
- # the results.
97
- attr_reader :value
98
-
99
69
  def_delegators :@results, :each
100
70
 
101
71
  # @return [true, false] true if the other object is a ResultList with
@@ -120,32 +90,11 @@ module Cuprum
120
90
  @errors ||= results.map(&:error)
121
91
  end
122
92
 
123
- # @return [Boolean] true if the result status is :failure, otherwise false.
124
- def failure?
125
- status == :failure
126
- end
127
-
128
93
  # @return [Array<Symbol>] the status for each result.
129
94
  def statuses
130
95
  @statuses ||= results.map(&:status)
131
96
  end
132
97
 
133
- # @return [Boolean] true if the result status is :success, otherwise false.
134
- def success?
135
- status == :success
136
- end
137
-
138
- # Converts the result list to a Cuprum::Result.
139
- #
140
- # @return [Cuprum::Result] the converted result.
141
- #
142
- # @see #error
143
- # @see #status
144
- # @see #value
145
- def to_cuprum_result
146
- Cuprum::Result.new(error:, status:, value:)
147
- end
148
-
149
98
  # @return [Array<Object, nil>] the value, if any, for each result.
150
99
  def values
151
100
  @values ||= results.map(&:value)
@@ -125,9 +125,9 @@ module Cuprum::RSpec
125
125
  elsif !properties_match?
126
126
  message + properties_failure_message
127
127
  else
128
- # :nocov:
128
+ # simplecov:disable
129
129
  message
130
- # :nocov:
130
+ # simplecov:enable
131
131
  end
132
132
  end
133
133
 
@@ -57,10 +57,19 @@ module Cuprum::RSpec::Deferred
57
57
 
58
58
  deferred_examples 'should validate the parameter' \
59
59
  do |name, type = nil, message: nil, **options|
60
+ let(:expected_message) do
61
+ message.is_a?(Proc) ? instance_exec(&message) : message
62
+ end
63
+ let(:expected_options) do
64
+ options.transform_values do |value|
65
+ value.is_a?(Proc) ? instance_exec(&value) : value
66
+ end
67
+ end
68
+
60
69
  it 'should return a failing result with InvalidParameters error' do
61
70
  expected_failure =
62
- message ||
63
- tools.assertions.error_message_for(type, as: name, **options)
71
+ expected_message ||
72
+ tools.assertions.error_message_for(type, as: name, **expected_options)
64
73
  expected_error = Cuprum::Errors::InvalidParameters.new(
65
74
  command_class: subject.class,
66
75
  failures: [expected_failure]
@@ -71,11 +80,5 @@ module Cuprum::RSpec::Deferred
71
80
  .with_error(expected_error)
72
81
  end
73
82
  end
74
-
75
- private
76
-
77
- def tools
78
- SleepingKingStudios::Tools::Toolbelt.instance
79
- end
80
83
  end
81
84
  end
@@ -131,10 +131,10 @@ module Cuprum::Utils
131
131
  if kwargs.empty?
132
132
  Cuprum::Utils::InstanceSpy.send(:call_spies_for, self, *args, &)
133
133
  else
134
- # :nocov:
134
+ # simplecov:disable
135
135
  Cuprum::Utils::InstanceSpy
136
136
  .send(:call_spies_for, self, *args, **kwargs, &)
137
- # :nocov:
137
+ # simplecov:enable
138
138
  end
139
139
 
140
140
  super
@@ -10,13 +10,13 @@ module Cuprum
10
10
  # Major version.
11
11
  MAJOR = 1
12
12
  # Minor version.
13
- MINOR = 3
13
+ MINOR = 4
14
14
  # Patch version.
15
- PATCH = 1
15
+ PATCH = 0
16
16
  # Prerelease version.
17
- PRERELEASE = nil
17
+ PRERELEASE = :rc
18
18
  # Build metadata.
19
- BUILD = nil
19
+ BUILD = 0
20
20
 
21
21
  class << self
22
22
  # Generates the gem version string from the Version constants.
data/lib/cuprum.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sleeping_king_studios/tools/toolbox/initializer'
4
+
3
5
  # Toolkit for implementing business logic as function objects.
4
6
  module Cuprum
5
7
  autoload :Command, 'cuprum/command'
6
8
  autoload :CommandFactory, 'cuprum/command_factory'
7
9
  autoload :Currying, 'cuprum/currying'
8
10
  autoload :Error, 'cuprum/error'
11
+ autoload :Errors, 'cuprum/errors'
9
12
  autoload :ExceptionHandling, 'cuprum/exception_handling'
10
13
  autoload :MapCommand, 'cuprum/map_command'
11
14
  autoload :Matcher, 'cuprum/matcher'
@@ -16,7 +19,30 @@ module Cuprum
16
19
  autoload :ResultList, 'cuprum/result_list'
17
20
  autoload :Steps, 'cuprum/steps'
18
21
 
22
+ @initializer = SleepingKingStudios::Tools::Toolbox::Initializer.new do
23
+ SleepingKingStudios::Tools.initializer.call
24
+
25
+ SleepingKingStudios::Tools::Messages::Registry
26
+ .global
27
+ .register(
28
+ file: File.join(Cuprum.gem_path, 'config', 'messages.yml'),
29
+ scope: 'cuprum.errors'
30
+ )
31
+ end
32
+
19
33
  class << self
34
+ # @return [SleepingKingStudios::Tools::Toolbox::Initializer] the initializer
35
+ # for the module.
36
+ attr_reader :initializer
37
+
38
+ # @return [String] the absolute path to the gem directory.
39
+ def gem_path
40
+ sep = File::SEPARATOR
41
+ pattern = /#{sep}lib#{sep}?\z/
42
+
43
+ __dir__.sub(pattern, '')
44
+ end
45
+
20
46
  # @return [String] the current version of the gem.
21
47
  def version
22
48
  VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuprum
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0.rc.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
@@ -15,20 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.2'
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: 1.2.1
18
+ version: '1.3'
22
19
  type: :runtime
23
20
  prerelease: false
24
21
  version_requirements: !ruby/object:Gem::Requirement
25
22
  requirements:
26
23
  - - "~>"
27
24
  - !ruby/object:Gem::Version
28
- version: '1.2'
29
- - - ">="
30
- - !ruby/object:Gem::Version
31
- version: 1.2.1
25
+ version: '1.3'
32
26
  description: |-
33
27
  An opinionated implementation of the Command pattern for Ruby applications.
34
28
  Cuprum wraps your business logic in a consistent, object-oriented interface
@@ -45,6 +39,7 @@ files:
45
39
  - DEVELOPMENT.md
46
40
  - LICENSE
47
41
  - README.md
42
+ - config/messages.yml
48
43
  - lib/cuprum.rb
49
44
  - lib/cuprum/built_in.rb
50
45
  - lib/cuprum/built_in/identity_command.rb
@@ -112,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
107
  - !ruby/object:Gem::Version
113
108
  version: '0'
114
109
  requirements: []
115
- rubygems_version: 4.0.2
110
+ rubygems_version: 4.0.20
116
111
  specification_version: 4
117
112
  summary: An opinionated implementation of the Command pattern.
118
113
  test_files: []