services 2.0.1 → 2.0.2

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
  SHA1:
3
- metadata.gz: 497d42516b9a0d6a95bdf84cc5387fddae35c1a0
4
- data.tar.gz: 25e03e9ceea6e04dadac955e5027c654d0a95dda
3
+ metadata.gz: 3957769bb927ced167265444d98a3a10992e8eb6
4
+ data.tar.gz: 230cfe057c104954db348751127dea932c661b69
5
5
  SHA512:
6
- metadata.gz: 8ea3bb811cc4b5f55e3e8eefda6b6d64731250b46b143ea2ed1a456819d605727e58fca08417cb15a3e3e9eb37741dee8684c225af5ba4ef83d6f3162cb821d9
7
- data.tar.gz: 757435307628879d21fe2a7106630e39901c1f806a7e4b024215d4fbdb98f336a85d6752fb88055b74c60863d29d508228d51275c27ebf69c75b123dbe47f1ea
6
+ metadata.gz: 8f0643545a27ab417933795342a71e898778bf752477ab889ac4b63ab22962dc0f4297a2a779673ff5a264b7495c9a6c1fcf530241eadf1635be6928d3d473e7
7
+ data.tar.gz: d76942f091238687ae52cb3fbeffe1f6d61f3d93c3d3e926f3eb092936937ef5f4da5fcb58bcdff8868d4c89dbcf1b1220f3cd995e9df08d872aac081d2fb3af
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 2.0.2
2
+
3
+ * Make BaseFinder smarter, don't create SQL subquery if not necessary
4
+
5
+ ## 2.0.1
6
+
7
+ * Fix disabling call logging
8
+
1
9
  ## 2.0.0
2
10
 
3
11
  * Improve call logging
data/Guardfile CHANGED
@@ -1,54 +1,61 @@
1
- # require 'guard/rspec'
2
-
3
- # module ::Guard
4
- # class RSpec < Plugin
5
- # # Add `stop` method if not defined
6
- # # so that `stop_*` callbacks work.
7
- # unless instance_methods.include?(:stop)
8
- # def stop; end
9
- # end
10
- # end
11
- # end
12
-
13
- # class Guard::StartRedisAndSidekiq
14
- # def call(guard_class, event, *args)
15
- # # Start Redis
16
- # redis_options = {
17
- # daemonize: 'yes',
18
- # port: redis_port,
19
- # dir: support_dir,
20
- # dbfilename: 'redis.rdb',
21
- # logfile: log_dir.join('redis.log'),
22
- # pidfile: redis_pidfile
23
- # }
24
- # redis = support_dir.join('redis-server')
25
- # system "#{redis} #{options_hash_to_string(redis_options)}"
26
-
27
- # # Copy call proxy
28
- # FileUtils.cp CALL_PROXY_SOURCE, CALL_PROXY_DESTINATION
29
- # end
30
- # end
31
-
32
- # class Guard::StopRedisAndSidekiq
33
- # def call(guard_class, event, *args)
34
- # # Delete call proxy
35
- # FileUtils.rm CALL_PROXY_DESTINATION
36
-
37
- # # Stop Redis
38
- # redis_cli = support_dir.join('redis-cli')
39
- # system "#{redis_cli} -p #{redis_port} shutdown"
40
-
41
- # # Truncate log files
42
- # max_len = 1024 * 1024 # 1 MB
43
- # Dir[File.join(log_dir, '*.log')].each do |file|
44
- # File.truncate file, max_len if File.size(file) > max_len
45
- # end
46
- # end
47
- # end
1
+ require 'guard/rspec'
2
+
3
+ module ::Guard
4
+ class RSpec < Plugin
5
+ # Add `stop` method if not defined
6
+ # so that `stop_*` callbacks work.
7
+ unless instance_methods.include?(:stop)
8
+ def stop; end
9
+ end
10
+ end
11
+
12
+ module ServicesGemHelpers
13
+ SPEC_SUPPORT_DIR = Pathname.new(File.expand_path('../spec/support', __FILE__))
14
+ REDIS_BIN = SPEC_SUPPORT_DIR.join('redis-server')
15
+ REDIS_CLI = SPEC_SUPPORT_DIR.join('redis-cli')
16
+ REDIS_PIDFILE = SPEC_SUPPORT_DIR.join('redis.pid')
17
+ REDIS_LOGFILE = SPEC_SUPPORT_DIR.join('log', 'redis.log')
18
+
19
+ class OnStart
20
+ def call(guard_class, event, *args)
21
+ redis_options = {
22
+ daemonize: 'yes',
23
+ dir: SPEC_SUPPORT_DIR,
24
+ dbfilename: 'redis.rdb',
25
+ logfile: REDIS_LOGFILE,
26
+ pidfile: REDIS_PIDFILE,
27
+ }
28
+ system "#{REDIS_BIN} #{redis_options.map { |k, v| "--#{k} #{v}" }.join(' ')}"
29
+
30
+ i = 0
31
+ while !File.exist?(REDIS_PIDFILE)
32
+ puts 'Waiting for Redis to start...'
33
+ sleep 1
34
+ i += 1
35
+ raise "Redis didn't start in #{i} seconds." if i >= 5
36
+ end
37
+ end
38
+ end
39
+
40
+ class OnStop
41
+ def call(guard_class, event, *args)
42
+ system "#{REDIS_CLI} shutdown"
43
+
44
+ i = 0
45
+ while File.exist?(REDIS_PIDFILE)
46
+ puts 'Waiting for Redis to stop...'
47
+ sleep 1
48
+ i += 1
49
+ raise "Redis didn't stop in #{i} seconds." if i >= 5
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
48
55
 
49
56
  guard 'rspec', cmd: 'bundle exec rspec' do
50
- # callback StartRedisAndSidekiq.new, :start_begin
51
- # callback StopRedisAndSidekiq.new, :stop_begin
57
+ callback ServicesGemHelpers::OnStart.new, :start_begin
58
+ callback ServicesGemHelpers::OnStop.new, :stop_begin
52
59
 
53
60
  # Specs
54
61
  watch(%r(^spec/.+_spec\.rb$))
data/README.md CHANGED
@@ -17,6 +17,24 @@ A lot has been written about service layers in Rails apps. There are of course a
17
17
 
18
18
  For disambiguation, we let's write Services with a uppercase "S" when we mean this gem, and services with a lowercase "s" when we mean, well, the plural of service.
19
19
 
20
+ ### Requirements
21
+
22
+ #### Rails
23
+
24
+ to be described...
25
+
26
+ #### Redis
27
+
28
+ to be described...
29
+
30
+ #### Sidekiq
31
+
32
+ To process services in the background, Services uses [Sidekiq](https://github.com/mperham/sidekiq). Sidekiq is not required to use Services though. If it's not present when Services is loaded, a service will raise an exception when you try to enqueue it for background processing. If you use Sidekiq, make sure to load the Services gem after the Sidekiq gem.
33
+
34
+ #### Postgres
35
+
36
+ The SQL that `Services::BaseFinder` (discussed further down) generates is optimized for Postgres. It might work with other databases but it's not guaranteed. If you're not using Postgres, don't use `Services::BaseFinder` or, even better, submit a [pull request](https://github.com/krautcomputing/services/issues) that fixes it to work with your database!
37
+
20
38
  ### Basic principles
21
39
 
22
40
  Services is based on a couple of basic principles of what a service should be and do in your app:
@@ -41,6 +59,18 @@ Follow these conventions when using Services in your Rails app:
41
59
  * services are namespaced with the model they operate on and their names are verbs, e.g. `app/services/users/delete.rb` defines `Services::Users::Delete`. If a service operates on multiple models or no models at all, don't namespace them (`Services::DoStuff`) or namespace them by logical groups unrelated to models (`Services::Maintenance::CleanOldUsers`, `Services::Maintenance::SendDailySummary`, etc.)
42
60
  * some services call other services. Try to not combine multiple calls to other services and business logic in one service. Instead, some services should contain only business logic and other services only a bunch of service calls but no (or little) business logic. This keeps your services nice and modular.
43
61
 
62
+ ### Configure
63
+
64
+ You can set some configuration options in an initializer:
65
+
66
+ ```ruby
67
+ # config/initializers/services.rb
68
+ Services.configure do |config|
69
+ config.logger = Services::Logger::Redis.new(REDIS) # or Services::Logger::File.new(Rails.root.join('log'))
70
+ config.redis = REDIS
71
+ end
72
+ ```
73
+
44
74
  ### Rails autoload fix
45
75
 
46
76
  By default, Rails expects `app/services/users/delete.rb` to define `Users::Delete`, but we want it to expect `Services::Users::Delete`. To make this work, add the `app` folder to the autoload path:
@@ -50,20 +80,6 @@ By default, Rails expects `app/services/users/delete.rb` to define `Users::Delet
50
80
  config.autoload_paths += [config.root.join('app')]
51
81
  ```
52
82
 
53
- ### Dependence
54
-
55
- #### Redis
56
-
57
- to be described...
58
-
59
- #### Sidekiq
60
-
61
- To process services in the background, Services uses [Sidekiq](https://github.com/mperham/sidekiq). Sidekiq is not required to use Services though. If it's not present when Services is loaded, a service will raise an exception when you try to enqueue it for background processing. If you use Sidekiq, make sure to load the Services gem after the Sidekiq gem.
62
-
63
- #### Postgres
64
-
65
- The SQL that `Services::BaseFinder` (discussed further down) generates is optimized for Postgres. It might work with other databases but it's not guaranteed. If you're not using Postgres, don't use `Services::BaseFinder` or, even better, submit a [pull request](https://github.com/krautcomputing/services/issues) that fixes it to work with your database!
66
-
67
83
  ### Examples
68
84
 
69
85
  The following service takes one or more users or user IDs as an argument.
@@ -150,7 +166,12 @@ Your services also automatically get a custom `Error` class, so you can `raise E
150
166
 
151
167
  ### Logging
152
168
 
153
- to be described...
169
+ You can choose between logging to Redis or to a file.
170
+
171
+
172
+ #### Redis
173
+
174
+
154
175
 
155
176
  ### Exception wrapping
156
177
 
@@ -189,3 +210,7 @@ Or install it yourself as:
189
210
  3. Commit your changes (`git commit -am 'Add some feature'`)
190
211
  4. Push to the branch (`git push origin my-new-feature`)
191
212
  5. Create new Pull Request
213
+
214
+ ## Testing
215
+
216
+ You need Redis to run tests, check out the Guardfile!
@@ -7,11 +7,6 @@ rescue LoadError
7
7
  raise Services::BackgroundProcessorNotFound
8
8
  end
9
9
 
10
- begin
11
- require 'sidetiq'
12
- rescue LoadError
13
- end
14
-
15
10
  module Services
16
11
  module Asyncable
17
12
  extend ActiveSupport::Concern
@@ -21,7 +16,6 @@ module Services
21
16
 
22
17
  included do
23
18
  include Sidekiq::Worker
24
- include Sidetiq::Schedulable if defined?(Sidetiq)
25
19
  end
26
20
 
27
21
  module ClassMethods
@@ -53,24 +47,5 @@ module Services
53
47
 
54
48
  target.send *args
55
49
  end
56
-
57
- def own_worker
58
- return @own_worker if defined?(@own_worker)
59
- @own_worker = if self.jid.nil?
60
- nil
61
- else
62
- own_worker = Sidekiq::Workers.new.detect do |_, _, work|
63
- work['payload']['jid'] == self.jid
64
- end
65
- raise self.class::Error, "Could not find own worker with jid #{self.jid}: #{Sidekiq::Workers.new.map { |*args| args }}" if own_worker.nil?
66
- own_worker
67
- end
68
- end
69
-
70
- def sibling_workers
71
- @sibling_workers ||= Sidekiq::Workers.new.select do |_, _, work|
72
- work['payload']['class'] == self.class.to_s && (own_worker.nil? || work['payload']['jid'] != own_worker[2]['payload']['jid'])
73
- end
74
- end
75
50
  end
76
51
  end
data/lib/services/base.rb CHANGED
@@ -60,6 +60,9 @@ module Services
60
60
 
61
61
  def controller
62
62
  @controller ||= begin
63
+ # raise "You must use Rails to use the `controller` helper." unless defined?(Rails)
64
+ # host = Rails.application.routes.default_url_options[:host] || ActionMailer::Base.default_url_options[:host]
65
+ # Rails.application.routes.default_url_options[:host]
63
66
  raise 'Please configure host.' if Services.configuration.host.nil?
64
67
  request = ActionDispatch::TestRequest.new
65
68
  request.host = Services.configuration.host
@@ -5,14 +5,20 @@ module Services
5
5
  def call(ids = [], conditions = {})
6
6
  ids, conditions = Array(ids), conditions.symbolize_keys
7
7
  special_conditions = conditions.extract!(:order, :limit, :page, :per_page)
8
- scope = object_class
9
- .select("DISTINCT #{object_class.table_name}.id")
10
- .order("#{object_class.table_name}.id")
11
- scope = scope.where(id: ids) unless ids.empty?
12
8
 
13
- scope = process(scope, conditions)
9
+ object_table_id = "#{object_class.table_name}.id"
10
+
11
+ scope = object_class.public_send(Rails::VERSION::MAJOR == 3 ? :scoped : :all)
12
+ scope = scope.where(object_table_id => ids) unless ids.empty?
13
+
14
+ unless conditions.empty?
15
+ scope = scope
16
+ .select("DISTINCT #{object_table_id}")
17
+ .order(object_table_id)
18
+ scope = process(scope, conditions)
19
+ scope = object_class.where(id: scope)
20
+ end
14
21
 
15
- scope = object_class.where(id: scope)
16
22
  special_conditions.each do |k, v|
17
23
  case k
18
24
  when :order
@@ -32,6 +38,7 @@ module Services
32
38
  raise ArgumentError, "Unexpected special condition: #{k}"
33
39
  end
34
40
  end
41
+
35
42
  scope
36
43
  end
37
44
  end
@@ -1,3 +1,3 @@
1
1
  module Services
2
- VERSION = '2.0.1'
2
+ VERSION = '2.0.2'
3
3
  end
data/services.gemspec CHANGED
@@ -28,6 +28,6 @@ Gem::Specification.new do |gem|
28
28
  gem.add_development_dependency 'redis', '~> 3.0'
29
29
  gem.add_development_dependency 'tries', '~> 0.3'
30
30
  gem.add_development_dependency 'timecop', '~> 0.7'
31
- gem.add_runtime_dependency 'rails', '>= 3.0.0'
31
+ gem.add_runtime_dependency 'rails', '>= 3.2.0'
32
32
  gem.add_runtime_dependency 'gem_config', '~> 0.3'
33
33
  end
@@ -3,8 +3,10 @@ require 'spec_helper'
3
3
  describe Services::BaseFinder do
4
4
  include_context 'capture logs'
5
5
 
6
+ let(:base_find) { Services::Models::BaseFind }
7
+
6
8
  it 'has call logging disabled by default' do
7
- expect(Services::Models::BaseFind.call_logging_disabled).to eq(true)
8
- expect { Services::Models::BaseFind.call }.to_not change { logs }
9
+ expect(base_find.call_logging_disabled).to eq(true)
10
+ expect { base_find.call }.to_not change { logs }
9
11
  end
10
12
  end
@@ -57,24 +57,4 @@ describe Services::Base do
57
57
  end
58
58
  end
59
59
  end
60
-
61
- context 'when executed asynchronously' do
62
- it 'finds its own worker' do
63
- 3.times { OwnWorkerService.perform_async }
64
- jid = OwnWorkerService.perform_async
65
- own_worker_data = wait_for { Services.configuration.redis.get(jid) }
66
- own_worker_json = JSON.parse(own_worker_data)
67
- expect(own_worker_json[2]['payload']['jid']).to eq(jid)
68
- end
69
-
70
- it 'finds its sibling workers' do
71
- sibling_worker_jids = (1..3).map { SiblingWorkersService.perform_async }
72
- jid = SiblingWorkersService.perform_async
73
- sibling_worker_data = wait_for { Services.configuration.redis.get(jid) }
74
- sibling_worker_json = JSON.parse(sibling_worker_data)
75
- expect(sibling_worker_json.size).to eq(3)
76
- expected_sibling_worker_jids = sibling_worker_json.map { |_, _, work| work['payload']['jid'] }
77
- expect(expected_sibling_worker_jids).to match_array(sibling_worker_jids)
78
- end
79
- end
80
60
  end
data/spec/spec_helper.rb CHANGED
@@ -3,40 +3,34 @@ require 'tries'
3
3
  require 'redis'
4
4
  require 'sidekiq'
5
5
  require 'timecop'
6
+ require 'active_support'
6
7
  require 'active_support/core_ext'
7
8
 
8
9
  require_relative '../lib/services'
9
10
 
10
- PROJECT_ROOT = Pathname.new(File.expand_path('../..', __FILE__))
11
- TEST_SERVICES_PATH = Pathname.new(File.join('spec', 'support', 'test_services.rb'))
12
- support_dir = Pathname.new(File.expand_path('../support', __FILE__))
13
- log_dir = support_dir.join('log')
14
-
15
- CALL_PROXY_SOURCE = support_dir.join('call_proxy.rb')
11
+ PROJECT_ROOT = Pathname.new(File.expand_path('../..', __FILE__))
12
+ SUPPORT_DIR = Pathname.new(File.expand_path('../support', __FILE__))
13
+ TEST_SERVICES_PATH = Pathname.new(File.join('spec', 'support', 'test_services.rb'))
16
14
  CALL_PROXY_DESTINATION = PROJECT_ROOT.join('lib', 'services', 'call_proxy.rb')
15
+ CALL_PROXY_SOURCE = SUPPORT_DIR.join('call_proxy.rb')
16
+ SIDEKIQ_PIDFILE = SUPPORT_DIR.join('sidekiq.pid')
17
17
  WAIT = 0.5
18
18
  START_TIMEOUT = 5
19
- STOP_TIMEOUT = 20
20
-
21
- Dir[support_dir.join('**', '*.rb')].each { |f| require f }
19
+ SIDEKIQ_TIMEOUT = 20
22
20
 
23
- redis_port = 6379
24
- redis_pidfile = support_dir.join('redis.pid')
25
- redis_url = "redis://localhost:#{redis_port}/0"
21
+ Dir[SUPPORT_DIR.join('**', '*.rb')].each { |f| require f }
26
22
 
27
- sidekiq_pidfile = support_dir.join('sidekiq.pid')
28
- sidekiq_timeout = 20
29
23
 
30
24
  Services.configure do |config|
31
- config.redis = Redis.new
25
+ config.redis = Redis.new
32
26
  end
33
27
 
34
28
  Sidekiq.configure_client do |config|
35
- config.redis = { redis: redis_url, namespace: 'sidekiq', size: 1 }
29
+ config.redis = { redis: 'redis://localhost:6379/0', namespace: 'sidekiq', size: 1 }
36
30
  end
37
31
 
38
32
  Sidekiq.configure_server do |config|
39
- config.redis = { redis: redis_url, namespace: 'sidekiq' }
33
+ config.redis = { redis: 'redis://localhost:6379/0', namespace: 'sidekiq' }
40
34
  end
41
35
 
42
36
  RSpec.configure do |config|
@@ -45,78 +39,44 @@ RSpec.configure do |config|
45
39
  config.order = 'random'
46
40
 
47
41
  config.before :suite do
48
- unless ENV['TRAVIS']
49
- # Start Redis
50
- redis_options = {
51
- daemonize: 'yes',
52
- port: redis_port,
53
- dir: support_dir,
54
- dbfilename: 'redis.rdb',
55
- logfile: log_dir.join('redis.log'),
56
- pidfile: redis_pidfile
57
- }
58
- redis = support_dir.join('redis-server')
59
- system "#{redis} #{options_hash_to_string(redis_options)}"
60
- end
61
-
62
42
  # Start Sidekiq
63
43
  sidekiq_options = {
64
44
  concurrency: 10,
65
45
  daemon: true,
66
- timeout: sidekiq_timeout,
46
+ timeout: SIDEKIQ_TIMEOUT,
67
47
  verbose: true,
68
48
  require: __FILE__,
69
- logfile: log_dir.join('sidekiq.log'),
70
- pidfile: sidekiq_pidfile
49
+ logfile: SUPPORT_DIR.join('log', 'sidekiq.log'),
50
+ pidfile: SIDEKIQ_PIDFILE
71
51
  }
72
52
  system "bundle exec sidekiq #{options_hash_to_string(sidekiq_options)}"
73
53
 
74
54
  # Copy call proxy
75
55
  FileUtils.cp CALL_PROXY_SOURCE, CALL_PROXY_DESTINATION
76
56
 
77
- # Wait until Redis and Sidekiq are started
78
- @processes = {
79
- 'Sidekiq' => sidekiq_pidfile
80
- }
81
- @processes['Redis'] = redis_pidfile unless ENV['TRAVIS']
82
- @processes.each do |process, pidfile|
83
- i = 0
84
- while !File.exist?(pidfile)
85
- puts "Waiting for #{process} to start..."
86
- sleep WAIT
87
- i += WAIT
88
- raise "#{process} didn't start in #{i} seconds." if i >= START_TIMEOUT
89
- end
57
+ # Wait for Sidekiq to start
58
+ i = 0
59
+ while !File.exist?(SIDEKIQ_PIDFILE)
60
+ puts 'Waiting for Sidekiq to start...'
61
+ sleep WAIT
62
+ i += WAIT
63
+ raise "Sidekiq didn't start in #{i} seconds." if i >= START_TIMEOUT
90
64
  end
91
65
  end
92
66
 
93
67
  config.after :suite do
94
- # Delete call proxy
95
- FileUtils.rm CALL_PROXY_DESTINATION
96
-
97
68
  # Stop Sidekiq
98
- system "bundle exec sidekiqctl stop #{sidekiq_pidfile} #{sidekiq_timeout}"
99
-
100
- unless ENV['TRAVIS']
101
- # Stop Redis
102
- redis_cli = support_dir.join('redis-cli')
103
- system "#{redis_cli} -p #{redis_port} shutdown"
104
- end
69
+ system "bundle exec sidekiqctl stop #{SIDEKIQ_PIDFILE} #{SIDEKIQ_TIMEOUT}"
105
70
 
106
- @processes.each do |process, pidfile|
107
- i = 0
108
- while File.exist?(pidfile)
109
- puts "Waiting for #{process} to stop..."
110
- sleep WAIT
111
- i += WAIT
112
- raise "#{process} didn't stop in #{i} seconds." if i >= STOP_TIMEOUT
113
- end
114
- end
71
+ # Delete call proxy
72
+ FileUtils.rm CALL_PROXY_DESTINATION
115
73
 
116
- # Truncate log files
117
- max_len = 1024 * 1024 # 1 MB
118
- Dir[File.join(log_dir, '*.log')].each do |file|
119
- File.truncate file, max_len if File.size(file) > max_len
74
+ i = 0
75
+ while File.exist?(SIDEKIQ_PIDFILE)
76
+ puts 'Waiting for Sidekiq to stop...'
77
+ sleep WAIT
78
+ i += WAIT
79
+ raise "Sidekiq didn't stop in #{i} seconds." if i >= SIDEKIQ_TIMEOUT + 1
120
80
  end
121
81
  end
122
82
 
@@ -1,4 +1,4 @@
1
- shared_context 'capture logs' do
1
+ RSpec.shared_context 'capture logs' do
2
2
  let(:logger) { spy('logger') }
3
3
  let(:logs) { [] }
4
4
 
@@ -131,28 +131,6 @@ class NonUniqueService < Services::Base
131
131
  end
132
132
  end
133
133
 
134
- class OwnWorkerService < Services::Base
135
- def call
136
- if own_worker.nil?
137
- logger.error 'Could not find own worker!'
138
- else
139
- Services.configuration.redis.set self.jid, own_worker.to_json
140
- end
141
- sleep 0.5
142
- end
143
- end
144
-
145
- class SiblingWorkersService < Services::Base
146
- def call
147
- if sibling_workers.empty?
148
- logger.info 'No sibling workers found.'
149
- else
150
- Services.configuration.redis.set self.jid, sibling_workers.to_json
151
- end
152
- sleep 0.5
153
- end
154
- end
155
-
156
134
  class NestedExceptionService < Services::Base
157
135
  NestedError1 = Class.new(Error)
158
136
  NestedError2 = Class.new(Error)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: services
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Meurer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-19 00:00:00.000000000 Z
11
+ date: 2014-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: 3.0.0
117
+ version: 3.2.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: 3.0.0
124
+ version: 3.2.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: gem_config
127
127
  requirement: !ruby/object:Gem::Requirement