lolcommits-sample_plugin 0.0.3 → 0.1.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: 34f1c14597a028bb747539c372b30e1bc8da36854d4cd2890753644ccab75047
4
- data.tar.gz: 0c23c1efba939a7f17ce784b96ee21b603f82e494e33d204b5d11e3dabd0774f
3
+ metadata.gz: 9e4b2d304835ff46c9606931301a5fe8a1f9908602b524f09f36a032efa57bdb
4
+ data.tar.gz: eca9268aa5043e05b5d597f23d7e8246410d052417d2d777ff4c105036dd3254
5
5
  SHA512:
6
- metadata.gz: 99903cf451eb212ca063ed151841c9ba7d29c308735c59b35f5e0f92c94d967389b50d0c0af46c3a4d79c1f9bcc7e0505348f992ee153a24d15ccb49763e1c83
7
- data.tar.gz: 1a88c98c1426d59801a143922906d5004396ba340494846ee5e289cbca01e1b395cfeb218e7ce3caf7458cb02eaada65676227480e85bee0363909419f2ebbbb
6
+ metadata.gz: 60889f0a52a762046e7847c842eceab9bb518befc3148c859d615053d23604d16a01fc8d21cda74ba5a3670de62e57143e397f3b596d17515cfa461aa0138cd3
7
+ data.tar.gz: c7bf6610a544b54dd99ab627ebb1b9a7c19bea318e69d8367dffda38a094ea108a1142c5190b932db1a5ffc17939f84429820c1f170979051bed5988e3dd2781
data/README.md CHANGED
@@ -10,12 +10,13 @@
10
10
  every time you git commit code, and archives a lolcat style image with it. Git
11
11
  blame has never been so much fun!
12
12
 
13
- Lolcommit plugins are automatically loaded before the capturing process starts.
14
- The flexible class design allows developers to add features by running code
15
- before or after snapshots are taken.
13
+ Lolcommit plugins allow developers to add features by running code before or
14
+ after snapshots are taken. Installed plugin gems are automatically loaded before
15
+ the capturing process starts.
16
16
 
17
17
  This gem showcases an example plugin. It prints short messages to the screen
18
- before and after every lolcommit. Something like this;
18
+ before and after every lolcommit. After configuring the plugin to be enabled,
19
+ you'll see something like this for a capture:
19
20
 
20
21
  ✨ Say cheese 😁 !
21
22
  *** Preserving this moment in history.
@@ -23,90 +24,98 @@ before and after every lolcommit. Something like this;
23
24
  ✨ wow! 9e6303c is your best looking commit yet! 😘 💻
24
25
 
25
26
  Use this repo to jump-start development on your own plugin. It has tests, docs
26
- and integration with useful tools (Travis, CodeClimate, Rdoc etc.) See below for
27
- more information on how to get started.
27
+ and hooks with useful tools; Travis, CodeClimate, Rdoc etc.
28
28
 
29
29
  ## Developing your own plugin
30
30
 
31
- First, there are some things your gem *must* do to be loaded and executed
32
- correctly. At the very least:
31
+ First, there are some things your gem *must* do to be loaded and executed:
33
32
 
34
- * Name your gem with the `lolcommits-` prefix.
33
+ * The gem name must have a `lolcommits-` prefix.
34
+ * Require `lolcommits` in your `gemspec` file as a development dependency.
35
35
  * Include a class that inherits from `Lolcommits::Plugin::Base` (this will be
36
36
  the entry point to your plugin from the lolcommits gem).
37
37
  * This main plugin class must meet the requirements explained below.
38
- * Require `lolcommits` in your gem spec as a development dependency.
39
38
 
40
39
  ### Your Plugin Class
41
40
 
42
41
  You plugin class must have a namespace and path that matches your gem name and
43
- be in the `LOAD_PATH` (required) with the gem for example:
42
+ be in the gem's `LOAD_PATH`.
44
43
 
45
- # a gem named: lolcommits-zapier
46
- # should have a plugin class inheriting from Base like so:
44
+ # for a gem named lolcommits-zapier you should have a plugin class:
47
45
  class Lolcommits::Plugin::Zapier < Lolcommits::Plugin::Base
48
46
  ...
49
47
  end
50
48
  # at lib/lolcommits/plugin/zapier.rb
51
49
  # required in a file at lib/lolcommits/zapier.rb
52
50
 
53
- # or a gem named: lolcommits-super_awesome
54
- # should have a plugin class
51
+ # or a gem named lolcommits-super_awesome should have a plugin class:
55
52
  class Lolcommits::Plugin::SuperAwesome < Lolcommits::Plugin::Base
56
53
  ...
57
54
  end
55
+ # at lib/lolcommits/plugin/super_awesome.rb
58
56
  # required in a file at lib/lolcommits/super_awesome.rb
59
57
 
60
- You **should** override the following methods in this class:
58
+ The following methods can be overridden to execute code during the capture
59
+ process:
61
60
 
62
- * `def self.name` - identifies the plugin to lolcommits and users, keep things
63
- simple and choose a name that matches your gem name.
64
- * `def self.runner_order` - return the hooks this plugin should run at during
65
- the capture process (`:pre_capture`, `:post_capture` and/or `:capture_ready`).
66
- * `def run_pre_capture`, `def run_post_capture` and/or `def run_capture_ready` -
67
- override with your plugin's behaviour.
68
-
69
- Three hooks points are available during the lolcommits capture process.
70
-
71
- * `:pre_capture` - called before the camera starts capturing, at this point you
61
+ * `run_pre_capture` - executes before the capture starts, at this point you
72
62
  could alter the commit message/sha text.
73
- * `:post_capture` - called immediately after the camera snaps the raw image (or
74
- video for gif captures) use this hook to alter the image, other plugins may
75
- hook here to modify the image too.
76
- `:capture_ready` - called after all `:post_capture` plugins have ran, at this
77
- point the capture should be ready for exporting or sharing.
63
+ * `run_post_capture` - executes immediately after the camera captures, use this
64
+ hook to manipulate the image (e.g. resize, apply filters, annotate).
65
+ * `run_capture_ready` - executes after all `run_post_capture` hooks have ran, at
66
+ this point we consider the capture to be ready for exporting or sharing.
78
67
 
79
68
  ### Plugin configuration
80
69
 
81
- The `Base` class initializer defines an `@options` instance var, with an array
82
- of setting names that the user can configure. By default, the only option is
83
- `enabled` and plugins *must* be configured as `enabled = true` to run.
70
+ Available options can be defined in an Array (`@options` instance var) and/or a
71
+ Hash (by overriding the `default_options` method).
72
+
73
+ By default (on initialize), `@options` will be set to `[:enabled]`. This option
74
+ is mandatory since `enabled?` checks `configuration[:enabled] == true` before
75
+ any capture hooks can run.
84
76
 
85
- A plugin can be configured by the lolcommits gem with;
77
+ Using a Hash to define default options allows you to:
86
78
 
87
- lolcommits --config
88
- # or
89
- lolcommits --config -p plugin-name
79
+ - fall back to default values (or nil) if the user enters nothing when prompted
80
+ - define nested options (the user is prompted for each nested option key)
90
81
 
91
- Use the `configuration` method in your plugin class to read these options.
92
- Plugin methods you may want to override with custom configuration code include:
82
+ `configure_option_hash` will iterate over all options prompting the user for
83
+ input while building the configuration Hash.
93
84
 
94
- * `def enabled?` - usually checks `configuration['enabled']` to determine if the
95
- plugin should run.
96
- * `def configure_options!` - prompts the user for configuration (based on the
97
- `@options`) returns a hash that will be persisted.
98
- * `def configured?` - checks the persisted config hash is present.
99
- * `def valid_configuration?`- checks the persisted config hash has valid data.
85
+ Lolcommits will save this Hash to a YAML file. During the capture process the
86
+ configuration is loaded, parsed and available in the plugin class as
87
+ `configuration`. Or if you want to fall back to default values, you should use
88
+ the `config_option` method to dig into the Hash.
100
89
 
101
- If your plugin requires no configuration, you could override the `enabled?`
102
- method to always return `true`. Users could disable your plugin by uninstalling
103
- the gem.
90
+ Alternatively you can override these methods to fully customise the
91
+ configuration process.
92
+
93
+ * `def configure_options!` - by default this prompts the user for option values
94
+ (based on option names in the `@options` array and/or `default_options`) and
95
+ returns a Hash that will be persisted.
96
+ * `def enabled?` - by default checks if `configuration[:enabled] == true` to
97
+ determine if the plugin should run.
98
+ * `def configured?` - checks the persisted config Hash is present.
99
+ * `def valid_configuration?`- checks the persisted config Hash is valid.
104
100
 
105
101
  By default a plugin will only run it's capture hooks if:
106
102
 
107
103
  * `valid_configuration?` returns true
108
104
  * `enabled?` returns true
109
105
 
106
+ A `parse_user_input` method is available to help parse strings from STDIN to
107
+ Ruby objects (e.g. boolean, integer or nil).
108
+
109
+ During plugin configuration, your plugin class will be initialized with the
110
+ optional `config` argument (and no runner). This allows you to read the existing
111
+ saved options during configuration. E.g. to show existing options back to the
112
+ user, allowing you to ask if they want to keep or change an option if
113
+ reconfiguring.
114
+
115
+ __NOTE__: If your plugin does not require configuration and should be enabled by
116
+ default (on gem install) you could override the `enabled?` method to always
117
+ return `true`. Simply uninstalling the gem will disable the plugin.
118
+
110
119
  For more help, check out [the
111
120
  documentation](http://www.rubydoc.info/github/lolcommits/lolcommits-sample_plugin/Lolcommits/Plugin/SamplePlugin)
112
121
  for this plugin, or take a look at [other
@@ -115,43 +124,36 @@ for this plugin, or take a look at [other
115
124
  ### The Lolcommits 'runner'
116
125
 
117
126
  The only required argument for your plugin class initializer is a
118
- `Lolcommits::Runner` instance. By default, the base plugin initializer will set
119
- this in the `runner` instance var.
120
-
121
- Use these runner methods to access the commit, repo and configuration:
127
+ [Lolcommits::Runner](https://github.com/mroth/lolcommits/blob/master/lib/lolcommits/runner.rb)
128
+ instance. By default, the base plugin initializer will set this in the `runner`
129
+ instance var for use in your plugin's code.
122
130
 
123
- * `runner.message` - the git commit message.
124
- * `runner.sha` - the git sha for the current commit.
131
+ * `runner.message` - the commit message
132
+ * `runner.sha` - the sha for the current commit
125
133
  * `runner.vcs_info` - a reference to the
126
134
  [Lolcommits::VCSInfo](https://github.com/mroth/lolcommits/blob/master/lib/lolcommits/vcs_info.rb)
127
- instance.
135
+ instance
128
136
  * `runner.config` - a reference to the
129
137
  [Lolcommits::Configuration](https://github.com/mroth/lolcommits/blob/master/lib/lolcommits/configuration.rb)
130
- instance.
138
+ instance
131
139
 
132
- After the capturing process has completed, (i.e. in the `run_post_capture` or
133
- `run_capture_ready` hooks) these methods will reveal the captured snapshot file.
140
+ After the capturing process completes, (i.e. in `run_post_capture` or
141
+ `run_capture_ready` hooks) use these methods for the captured snapshot file.
134
142
 
135
- * `runner.snapshot_loc` - the raw image file.
143
+ * `runner.snapshot_loc` - the raw image file
136
144
  * `runner.main_image` - the processed image file, resized, with text overlay
137
- applied (or any other effects from other plugins).
145
+ applied (or any other post_capture effects)
138
146
 
139
- During plugin configuration, your plugin class will be initialized with the
140
- optional `config` argument (and no runner). This allows you to read the existing
141
- saved options during configuration. E.g. to show the existing options back to
142
- the user.
143
-
144
- Take a look at the
147
+ Take a look at
145
148
  [Lolcommits::Runner](https://github.com/mroth/lolcommits/blob/master/lib/lolcommits/runner.rb)
146
149
  for more details.
147
150
 
148
151
  ### Testing your plugin
149
152
 
150
- It's a good idea to include tests with your gem. To make this easier for you,
151
- the main lolcommits gem provides helpers to work with IO and Git repos in
152
- test.
153
+ To make test setup easier, the lolcommits gem includes these helpers to work
154
+ with command line IO and Git.
153
155
 
154
- # add one or both of these to your plugin's test_helper file
156
+ # add one (or both) of these to your plugin's test_helper file
155
157
  require 'lolcommits/test_helpers/git_repo'
156
158
  require 'lolcommits/test_helpers/fake_io'
157
159
 
@@ -161,44 +163,30 @@ test.
161
163
 
162
164
  Use the following methods to manage a test repo:
163
165
 
164
- setup_repo # create the test repo
165
- commit_repo_with_message # perform a git commit in the test repo
166
- last_commit # git commit info for the last commit in the test repo
167
- teardown_repo # destroy the test repo
168
- in_repo(&block) # run lolcommits within the test repo
166
+ setup_repo # create the test repo
167
+ commit_repo_with_message # perform a git commit in the test repo
168
+ last_commit # commit info for the last test repo commit
169
+ teardown_repo # destroy the test repo
170
+ in_repo(&block) # run lolcommits within the test repo
169
171
 
170
- For submitting and capturing IO use the `fake_io_capture` method. E.g. to
171
- capture the output of the `configure_options` method, while sending the string
172
- input 'true' (followed by a carriage return) when prompted on STDIN:
172
+ For STDIN and capturing IO use the `fake_io_capture` method.
173
173
 
174
+ # capture the output of the `configure_options` method, sending the
175
+ # string input 'true' (followed by a carriage return) to STDIN:
174
176
  output = fake_io_capture(inputs: %w(true)) do
175
177
  configured_plugin_options = plugin.configure_options!
176
178
  end
177
179
 
178
180
  For more examples take a look at the [tests in this
179
- repo](https://github.com/lolcommits/lolcommits-sample_plugin/blob/master/test/lolcommits/plugin/sample_plugin_test.rb)
180
- (MiniTest).
181
+ repo](https://github.com/lolcommits/lolcommits-sample_plugin/blob/master/test/lolcommits/plugin/sample_plugin_test.rb).
181
182
 
182
183
  ### General advice
183
184
 
184
- Use this gem as a starting point, renaming files, classes and references. Or
185
- build a new plugin gem from scratch with:
186
-
187
- bundle gem lolcommits-my-plugin
188
-
189
- For more examples, take a look at other published [lolcommit
185
+ * Use this gem as a starting point, renaming files, classes etc.
186
+ * For more examples, take a look at other published [lolcommit
190
187
  plugins](https://github.com/lolcommits).
191
-
192
- If you feel something is missing (or out of date) in this short guide. Please
193
- create a new
194
- [issue](https://github.com/lolcommits/lolcommits-sample_plugin/issues).
195
-
196
- ## History
197
-
198
- Until recently, all plugins lived inside the main lolcommits gem. We are in the
199
- process of extracting them to individual gems, loaded with the new plugin
200
- manager. Ruby gem versioning will take care of managing dependencies and
201
- compatibility with the main gem.
188
+ * If you feel something is missing (or out of date) in this guide. Post an
189
+ [issue](https://github.com/lolcommits/lolcommits-sample_plugin/issues).
202
190
 
203
191
  ---
204
192
 
@@ -219,9 +207,9 @@ lolcommits first. Then run the following:
219
207
  Next configure and enable this plugin with:
220
208
 
221
209
  $ lolcommits --config -p sample_plugin
222
- # set enabled to `true`
210
+ # set enabled to `true` and configure other options as you like
223
211
 
224
- That's it! Every lolcommit now comes with it's own short (emoji themed) message!
212
+ That's it! Every lolcommit now comes with it's own emoji themed commentary!
225
213
 
226
214
  ## Development
227
215
 
@@ -247,8 +235,8 @@ Generate docs for this gem with:
247
235
  ## Troubles?
248
236
 
249
237
  If you think something is broken or missing, please raise a new
250
- [issue](https://github.com/lolcommits/lolcommits-sample_plugin/issues). Take
251
- a moment to check it hasn't been raised in the past (and possibly closed).
238
+ [issue](https://github.com/lolcommits/lolcommits-sample_plugin/issues). Take a
239
+ moment to check it hasn't been raised in the past (and possibly closed).
252
240
 
253
241
  ## Contributing
254
242
 
@@ -5,9 +5,10 @@ module Lolcommits
5
5
  class SamplePlugin < Base
6
6
 
7
7
  ##
8
- # Plugin initializer
8
+ # Initializer
9
9
  #
10
- # @param runner [Lolcommits::Runner] an instance of a lolcommits runner
10
+ # @param runner [Lolcommits::Runner] an instance of a Lolcommits runner
11
+ # @param name [String] name for this plugin, usually set from Gem name
11
12
  # @param config [Hash] plugin config hash (parsed from saved config YAML)
12
13
  #
13
14
  # The default superclass method sets @runner and @configuration instance
@@ -15,28 +16,11 @@ module Lolcommits
15
16
  #
16
17
  # Override this method to change the default configurable option names
17
18
  #
18
- def initialize(runner: nil, config: nil)
19
+ def initialize(runner: nil, name: nil, config: nil)
19
20
  super
20
21
  end
21
22
 
22
23
  ##
23
- # Returns position(s) of when this plugin should run during the capture
24
- # process.
25
- #
26
- # Defines when the plugin will execute in the capture process. This must
27
- # be defined, if the method returns nil, or [] the plugin will never run.
28
- # Three hook positions exist, your plugin code can execute in one or more
29
- # of these.
30
- #
31
- # @return [Array] the position(s) (:pre_capture, :post_capture,
32
- # :capture_ready)
33
- #
34
- def self.runner_order
35
- [:pre_capture, :post_capture, :capture_ready]
36
- end
37
-
38
- ##
39
- #
40
24
  # Pre-capture hook, runs before lolcommits captures a snapshot.
41
25
  #
42
26
  # Override this method to execute plugin code before the lolcommit
@@ -49,7 +33,6 @@ module Lolcommits
49
33
  end
50
34
 
51
35
  ##
52
- #
53
36
  # Post-capture hook, run after lolcommits captures a snapshot.
54
37
  #
55
38
  # Override this method to execute plugin code after the lolcommit snapshot
@@ -63,7 +46,6 @@ module Lolcommits
63
46
  end
64
47
 
65
48
  ##
66
- #
67
49
  # Capture ready hook, runs after lolcommits captures a snapshot.
68
50
  #
69
51
  # Override this method to execute plugin code after the lolcommit snapshot
@@ -91,7 +73,7 @@ module Lolcommits
91
73
  #
92
74
  # Note: a `valid_configuration?` method also exists and is checked before
93
75
  # any plugin hooks execute. Use that to check individual config option
94
- # values.
76
+ # values are valid.
95
77
  #
96
78
  # @return [Boolean] true/false indicating if plugin is enabled
97
79
  #
@@ -132,6 +114,12 @@ module Lolcommits
132
114
  super
133
115
  end
134
116
 
117
+ ##
118
+ # Returns a hash of default options to be presented to the user when
119
+ # configuring (with `configure_options!`.
120
+ #
121
+ # @return [Hash] with the default option names (keys) and values
122
+ #
135
123
  def default_options
136
124
  {
137
125
  ask_for_cheese: true,
@@ -1,5 +1,5 @@
1
1
  module Lolcommits
2
2
  module SamplePlugin
3
- VERSION = "0.0.3".freeze
3
+ VERSION = "0.1.0".freeze
4
4
  end
5
5
  end
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.required_ruby_version = ">= 2.1"
34
34
 
35
- spec.add_development_dependency "lolcommits", ">= 0.11.0"
35
+ spec.add_development_dependency "lolcommits", ">= 0.12.0"
36
36
  spec.add_development_dependency "bundler"
37
37
  spec.add_development_dependency "rake"
38
38
  spec.add_development_dependency "minitest"
@@ -5,12 +5,6 @@ describe Lolcommits::Plugin::SamplePlugin do
5
5
  include Lolcommits::TestHelpers::GitRepo
6
6
  include Lolcommits::TestHelpers::FakeIO
7
7
 
8
- it 'should run on pre_capture and capture_ready' do
9
- ::Lolcommits::Plugin::SamplePlugin.runner_order.must_equal [
10
- :pre_capture, :post_capture, :capture_ready
11
- ]
12
- end
13
-
14
8
  describe 'with a runner' do
15
9
  def runner
16
10
  # a simple lolcommits runner with an empty configuration Hash
@@ -36,7 +30,7 @@ describe Lolcommits::Plugin::SamplePlugin do
36
30
  describe '#run_pre_capture' do
37
31
  before { commit_repo_with_message }
38
32
 
39
- it 'should output a message to stdout' do
33
+ it 'outputs a message to stdout' do
40
34
  in_repo do
41
35
  Proc.new { plugin.run_pre_capture }.
42
36
  must_output "✨ Say cheese 😁 !\n"
@@ -46,11 +40,24 @@ describe Lolcommits::Plugin::SamplePlugin do
46
40
  after { teardown_repo }
47
41
  end
48
42
 
43
+ describe '#run_post_capture' do
44
+ before { commit_repo_with_message }
45
+
46
+ it 'outputs a message to stdout' do
47
+ plugin.configuration = valid_enabled_config
48
+ in_repo do
49
+ Proc.new { plugin.run_post_capture }.must_output "📸 📸 📸 📸 📸 Snap!\n"
50
+ end
51
+ end
52
+
53
+ after { teardown_repo }
54
+ end
55
+
49
56
  describe '#run_capture_ready' do
50
57
 
51
58
  before { commit_repo_with_message }
52
59
 
53
- it 'should output a message to stdout' do
60
+ it 'outputs a message to stdout' do
54
61
  in_repo do
55
62
  Proc.new { plugin.run_capture_ready }.
56
63
  must_output "✨ wow! #{last_commit.sha[0..10]} is your best looking commit yet! 😘 💻\n"
@@ -61,18 +68,18 @@ describe Lolcommits::Plugin::SamplePlugin do
61
68
  end
62
69
 
63
70
  describe '#enabled?' do
64
- it 'should be false by default' do
71
+ it 'returns be false by default' do
65
72
  plugin.enabled?.must_equal false
66
73
  end
67
74
 
68
- it 'should true when configured' do
75
+ it 'returns true when configured' do
69
76
  plugin.configuration = valid_enabled_config
70
77
  plugin.enabled?.must_equal true
71
78
  end
72
79
  end
73
80
 
74
81
  describe 'configuration' do
75
- it 'should allow plugin options to be configured' do
82
+ it 'allows plugin options to be configured' do
76
83
  configured_plugin_options = {}
77
84
 
78
85
  fake_io_capture(inputs: %w(true false true true 5)) do
@@ -83,11 +90,11 @@ describe Lolcommits::Plugin::SamplePlugin do
83
90
  end
84
91
 
85
92
  describe '#valid_configuration?' do
86
- it 'should be false without config set' do
93
+ it 'returns false without config set' do
87
94
  plugin.valid_configuration?.must_equal(false)
88
95
  end
89
96
 
90
- it 'should be true for a valid configuration' do
97
+ it 'returns true for a valid configuration' do
91
98
  plugin.configuration = valid_enabled_config
92
99
  plugin.valid_configuration?.must_equal true
93
100
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lolcommits-sample_plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Hutchinson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-05 00:00:00.000000000 Z
11
+ date: 2018-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lolcommits
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.11.0
19
+ version: 0.12.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.11.0
26
+ version: 0.12.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement