her 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2RhYjBkODQ3ZjE1NmNlM2VmZTExNWJkNDU3NTI4YjI3OGNhN2RiZQ==
4
+ MDYyOTQxNDk5MmVhOGYxZDg4OTI0YTAxN2Y3MzBkYzliODc2MjgzZg==
5
5
  data.tar.gz: !binary |-
6
- OTBmNmRjM2I2NDE3ZmQ4MjZmZDJjMzI5NjQ2ODJjODUwMDczNWRiNw==
6
+ ZWJmNTZiODg5ZWFkYjZjM2M3YmRkNzhhNzk5MzYzOWQxOTdkYmNjNw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzZhZjExMWI1MmYwYTUwODU4OGM0OWM2OWI2NDgyOGU5OTM0ZWViY2UzYjdh
10
- NTZmNTI1YmFhMDlmMzQ5YTBmZWQzMWZhZjRlOWUwMzcxZTY0NWQ5YWQ2ODk3
11
- ZjA0M2ExMmMyM2UxNjMwYzJjOWNjNmVjYzY4MDJkZmM3NjM2NzY=
9
+ OTM0ZGNmYmRjODRiNDJhMzhkNTY2NGViNjU1Y2EzNzQwMGE2MTE3OWRlZDM4
10
+ N2Q4MWJlMjYxMjU5ZTg5MGU5MTdmZWEyZGY3ZmJmNThmYzY4NWNlMGQ5YzMw
11
+ ZGM1ZjcwYmRhZjA4ZWYyNjU4MTJiMzdkYjk4YzE0YmU3ZjY4MTc=
12
12
  data.tar.gz: !binary |-
13
- ZDM4NWJjMzllNDdhZTc1NGI2NWVmMjlhYTAyYzgzYTIxOTkzNDgwNGEzZDVi
14
- ZmI0OWRmYjdhNjVkNWMwNzVhYjIyYjg2YTM0ZjczMGY5OTBkNDU3Nzg4ZWVk
15
- OWYwY2Y0NDk0Zjc1MDlkM2M1ZDJlNzkzZTA4NGMxNTI2M2FlODI=
13
+ YmU3ODE5Mzk0YmY4YWQxOTA4YjVkMGNlNmFkNzBmZGMzOTAwNTA2MTFmNThl
14
+ MDFkNDQ2MTlkY2FkNWNlYWE2ZjFjZjFkMmJjZmIxY2UyYjY1ZGUyNjExNjVl
15
+ ODlmMDUwN2Q2NjhiOGY4ZmMyNmJkNDI4Nzg4OWM5YjZlNWIyNzc=
data/.travis.yml CHANGED
@@ -1,8 +1,9 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
+ - 2.0.0
4
5
  - 1.9.3
5
6
  - 1.9.2
6
- - 2.0.0
7
+ - 1.8.7
7
8
 
8
9
  script: "echo 'COME ON!' && bundle exec rake spec"
data/README.md CHANGED
@@ -1,14 +1,9 @@
1
1
  # Her
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/her.png)][gem]
4
- [![Build Status](https://secure.travis-ci.org/remiprev/her.png?branch=master)][travis]
5
- [![Dependency Status](https://gemnasium.com/remiprev/her.png?travis)][gemnasium]
6
- [![Code Climate](https://codeclimate.com/github/remiprev/her.png)][codeclimate]
7
-
8
- [gem]: https://rubygems.org/gems/her
9
- [travis]: http://travis-ci.org/remiprev/her
10
- [gemnasium]: https://gemnasium.com/remiprev/her
11
- [codeclimate]: https://codeclimate.com/github/remiprev/her
3
+ [![Gem Version](https://badge.fury.io/rb/her.png)](https://rubygems.org/gems/her)
4
+ [![Build Status](https://secure.travis-ci.org/remiprev/her.png?branch=master)](http://travis-ci.org/remiprev/her)
5
+ [![Dependency Status](https://gemnasium.com/remiprev/her.png?travis)](https://gemnasium.com/remiprev/her)
6
+ [![Code Climate](https://codeclimate.com/github/remiprev/her.png)](https://codeclimate.com/github/remiprev/her)
12
7
 
13
8
  Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API instead of a database.
14
9
 
@@ -53,17 +48,17 @@ User.find(1)
53
48
  # GET https://api.example.com/users/1 and return a User object
54
49
 
55
50
  @user = User.create(fullname: "Tobias Fünke")
56
- # POST "https://api.example.com/users" with the data and return a User object
51
+ # POST "https://api.example.com/users" with `fullname=Tobias+Fünke` and return the saved User object
57
52
 
58
53
  @user = User.new(fullname: "Tobias Fünke")
59
54
  @user.occupation = "actor"
60
55
  @user.save
61
- # POST https://api.example.com/users with the data and return a User object
56
+ # POST https://api.example.com/users with `fullname=Tobias+Fünke&occupation=actore` and return the saved User object
62
57
 
63
58
  @user = User.find(1)
64
59
  @user.fullname = "Lindsay Fünke"
65
60
  @user.save
66
- # PUT https://api.example.com/users/1 with the data and return+update the User object
61
+ # PUT https://api.example.com/users/1 with `fullname=Lindsay+Fünke` and return the updated User object
67
62
  ```
68
63
 
69
64
  ### ActiveRecord-like methods
@@ -505,6 +500,7 @@ You can easily define custom requests for your models using `custom_get`, `custo
505
500
  ```ruby
506
501
  class User
507
502
  include Her::Model
503
+
508
504
  custom_get :popular, :unpopular
509
505
  custom_post :from_default
510
506
  end
@@ -518,7 +514,7 @@ User.unpopular
518
514
  # [#<User id=3>, #<User id=4>]
519
515
 
520
516
  User.from_default(name: "Maeby Fünke")
521
- # POST /users/from_default?name=Maeby+Fünke
517
+ # POST /users/from_default with `name=Maeby+Fünke`
522
518
  # #<User id=5 name="Maeby Fünke">
523
519
  ```
524
520
 
@@ -538,7 +534,7 @@ User.get(:single_best)
538
534
  # #<User id=1>
539
535
  ```
540
536
 
541
- Also, `get_collection` (which maps the returned data to a collection of resources), `get_resource` (which maps the returned data to a single resource) or `get_raw` (which yields the parsed data return from the HTTP request) can also be used. Other HTTP methods are supported (`post_raw`, `put_resource`, etc.).
537
+ Also, `get_collection` (which maps the returned data to a collection of resources), `get_resource` (which maps the returned data to a single resource) or `get_raw` (which yields the parsed data and the raw response from the HTTP request) can also be used. Other HTTP methods are supported (`post_raw`, `put_resource`, etc.).
542
538
 
543
539
  ```ruby
544
540
  class User
@@ -549,7 +545,7 @@ class User
549
545
  end
550
546
 
551
547
  def self.total
552
- get_raw(:stats) do |parsed_data|
548
+ get_raw(:stats) do |parsed_data, response|
553
549
  parsed_data[:data][:total_users]
554
550
  end
555
551
  end
@@ -558,6 +554,7 @@ end
558
554
  User.popular
559
555
  # GET /users/popular
560
556
  # [#<User id=1>, #<User id=2>]
557
+
561
558
  User.total
562
559
  # GET /users/stats
563
560
  # => 42
@@ -605,7 +602,7 @@ end
605
602
 
606
603
  @user = User.new(fullname: "Tobias Fünke", organization_id: 2)
607
604
  @user.save
608
- # POST /organizations/2/users
605
+ # POST /organizations/2/users with `fullname=Tobias+Fünke`
609
606
  ```
610
607
 
611
608
  ### Custom primary keys
@@ -656,9 +653,9 @@ Just like with ActiveRecord, you can define named scopes for your models. Scopes
656
653
  class User
657
654
  include Her::Model
658
655
 
659
- scope :by_role, lambda { |role| where(:role => role) }
656
+ scope :by_role, lambda { |role| where(role: role) }
660
657
  scope :admins, lambda { by_role('admin') }
661
- scope :active, lambda { where(:active => 1) }
658
+ scope :active, lambda { where(active: 1) }
662
659
  end
663
660
 
664
661
  @admins = User.admins
data/lib/her/model.rb CHANGED
@@ -46,6 +46,10 @@ module Her
46
46
  included do
47
47
  # Assign the default API
48
48
  use_api Her::API.default_api
49
+ method_for :create, :post
50
+ method_for :update, :put
51
+ method_for :find, :get
52
+ method_for :destroy, :delete
49
53
 
50
54
  # Define the default primary key
51
55
  primary_key :id
@@ -36,6 +36,12 @@ module Her
36
36
  end
37
37
  alias :eql? :==
38
38
 
39
+ # ruby 1.8.7 compatibility
40
+ # @private
41
+ def id
42
+ fetch.id
43
+ end
44
+
39
45
  # @private
40
46
  def method_missing(method, *args, &blk)
41
47
  fetch.send(method, *args, &blk)
@@ -45,7 +45,7 @@ module Her
45
45
  return nil
46
46
  end
47
47
 
48
- @klass.get_resource("#{path}", @query_attrs)
48
+ @klass.get_resource(path, @query_attrs)
49
49
  else
50
50
  @parent.attributes[@name]
51
51
  end
@@ -104,7 +104,7 @@ module Her
104
104
  # Override the method to prevent from returning the object ID
105
105
  # @private
106
106
  def id
107
- attributes[self.class.primary_key] || super
107
+ attributes[self.class.primary_key]
108
108
  end
109
109
 
110
110
  # Return `true` if the other object is also a Her::Model and has matching data
@@ -38,7 +38,8 @@ module Her
38
38
  # - <method>_resource(path, attrs, &block)
39
39
  # - custom_<method>(path, attrs)
40
40
  METHODS.each do |method|
41
- define_method method do |path, attrs={}|
41
+ define_method method do |path, *attrs|
42
+ attrs = attrs.first || {}
42
43
  path = build_request_path_from_string_or_symbol(path, attrs)
43
44
  send(:"#{method}_raw", path, attrs) do |parsed_data, response|
44
45
  if parsed_data[:data].is_a?(Array)
@@ -49,19 +50,23 @@ module Her
49
50
  end
50
51
  end
51
52
 
52
- define_method :"#{method}_raw" do |path, attrs={}, &block|
53
+ define_method :"#{method}_raw" do |path, *attrs, &block|
54
+ attrs = attrs.first || {}
53
55
  path = build_request_path_from_string_or_symbol(path, attrs)
54
56
  request(attrs.merge(:_method => method, :_path => path), &block)
55
57
  end
56
58
 
57
- define_method :"#{method}_collection" do |path=nil, attrs={}|
59
+ define_method :"#{method}_collection" do |*args|
60
+ path = args.first
61
+ attrs = args[1] || {}
58
62
  path = build_request_path_from_string_or_symbol(path, attrs)
59
63
  send(:"#{method}_raw", build_request_path_from_string_or_symbol(path, attrs), attrs) do |parsed_data, response|
60
64
  new_collection(parsed_data)
61
65
  end
62
66
  end
63
67
 
64
- define_method :"#{method}_resource" do |path, attrs={}|
68
+ define_method :"#{method}_resource" do |path, *attrs|
69
+ attrs = attrs.first || {}
65
70
  path = build_request_path_from_string_or_symbol(path, attrs)
66
71
  send(:"#{method}_raw", path, attrs) do |parsed_data, response|
67
72
  new(parse(parsed_data[:data]).merge :_metadata => parsed_data[:metadata], :_errors => parsed_data[:errors])
@@ -45,7 +45,7 @@ module Her
45
45
  def assign_nested_attributes_for_simple_association(association_type, association_name, attributes)
46
46
  association = self.class.associations[association_type].find { |association| association[:name] == association_name }
47
47
  if has_data?(association[:name])
48
- self.send("#{association[:name]}").assign_data(attributes)
48
+ self.send(association[:name]).assign_data(attributes)
49
49
  else
50
50
  klass = self.class.her_nearby_class(association[:class_name])
51
51
  instance = klass.new(klass.parse(attributes))
data/lib/her/model/orm.rb CHANGED
@@ -6,7 +6,7 @@ module Her
6
6
 
7
7
  # Return `true` if a resource was not saved yet
8
8
  def new?
9
- attributes[self.class.primary_key].nil?
9
+ id.nil?
10
10
  end
11
11
 
12
12
  # Return `true` if a resource is not `#new?`
@@ -34,17 +34,13 @@ module Her
34
34
  # @user.save
35
35
  # # Called via POST "/users"
36
36
  def save
37
- if new?
38
- callback = :create
39
- method = :post
40
- else
41
- callback = :update
42
- method = :put
43
- end
37
+ callback = new? ? :create : :update
38
+ method = self.class.method_for(callback)
44
39
 
45
40
  run_callbacks callback do
46
41
  run_callbacks :save do
47
- self.class.request(to_params.merge(:_method => method, :_path => "#{request_path}")) do |parsed_data, response|
42
+ params = to_params
43
+ self.class.request(to_params.merge(:_method => method, :_path => request_path)) do |parsed_data, response|
48
44
  assign_attributes(self.class.parse(parsed_data[:data])) if parsed_data[:data].any?
49
45
  self.metadata = parsed_data[:metadata]
50
46
  self.response_errors = parsed_data[:errors]
@@ -65,9 +61,9 @@ module Her
65
61
  # @user.destroy
66
62
  # # Called via DELETE "/users/1"
67
63
  def destroy
68
- resource = self
64
+ method = self.class.method_for(:destroy)
69
65
  run_callbacks :destroy do
70
- self.class.request(:_method => :delete, :_path => "#{request_path}") do |parsed_data, response|
66
+ self.class.request(:_method => method, :_path => request_path) do |parsed_data, response|
71
67
  assign_attributes(self.class.parse(parsed_data[:data])) if parsed_data[:data].any?
72
68
  self.metadata = parsed_data[:metadata]
73
69
  self.response_errors = parsed_data[:errors]
@@ -91,7 +87,7 @@ module Her
91
87
  params = ids.last.is_a?(Hash) ? ids.pop : {}
92
88
  results = ids.flatten.compact.uniq.map do |id|
93
89
  resource = nil
94
- request(params.merge(:_method => :get, :_path => "#{build_request_path(params.merge(primary_key => id))}")) do |parsed_data, response|
90
+ request(params.merge(:_method => method_for(:find), :_path => build_request_path(params.merge(primary_key => id)))) do |parsed_data, response|
95
91
  if response.success?
96
92
  resource = new(parse(parsed_data[:data]).merge :_metadata => parsed_data[:metadata], :_errors => parsed_data[:errors])
97
93
  resource.run_callbacks :find
@@ -122,8 +118,12 @@ module Her
122
118
  # User.admins # Called via GET "/users?admin=1"
123
119
  # User.page(2).all # Called via GET "/users?page=2"
124
120
  def scope(name, code)
125
- define_singleton_method(name) { |*args| instance_exec(*args, &code) }
121
+ # Add the scope method to the class
122
+ (class << self; self end).define_method(name) do |*args|
123
+ instance_exec(*args, &code)
124
+ end
126
125
 
126
+ # Add the scope method to the Relation class
127
127
  Relation.instance_eval do
128
128
  define_method(name) { |*args| instance_exec(*args, &code) }
129
129
  end
@@ -135,8 +135,8 @@ module Her
135
135
  end
136
136
 
137
137
  # Delegate the following methods to `scoped`
138
- [:all, :where, :create].each do |method|
139
- define_method(method) { |*attrs| scoped.send(method, attrs.first) }
138
+ [:all, :where, :create, :build, :first_or_create, :first_or_initialize].each do |method|
139
+ define_method(method) { |*attrs| scoped.send(method, *attrs) }
140
140
  end
141
141
 
142
142
  # Save an existing resource and return it
@@ -156,10 +156,24 @@ module Her
156
156
  # User.destroy_existing(1)
157
157
  # # Called via DELETE "/users/1"
158
158
  def destroy_existing(id, params={})
159
- request(params.merge(:_method => :delete, :_path => "#{build_request_path(params.merge(primary_key => id))}")) do |parsed_data, response|
159
+ request(params.merge(:_method => method_for(:destroy), :_path => build_request_path(params.merge(primary_key => id)))) do |parsed_data, response|
160
160
  new(parse(parsed_data[:data]).merge(:_destroyed => true))
161
161
  end
162
162
  end
163
+
164
+ # Return or change the HTTP method used to create or update records
165
+ #
166
+ # @param [Symbol, String] action The behavior in question (`:create` or `:update`)
167
+ # @param [Symbol, String] method The HTTP method to use (`'PUT'`, `:post`, etc.)
168
+ def method_for(action = nil, method = nil)
169
+ @method_for ||= (superclass.respond_to?(:method_for) ? superclass.method_for : {})
170
+ return @method_for if action.nil?
171
+
172
+ action = action.to_s.downcase.to_sym
173
+
174
+ return @method_for[action] if method.nil?
175
+ @method_for[action] = method.to_s.downcase.to_sym
176
+ end
163
177
  end
164
178
  end
165
179
  end
@@ -47,7 +47,7 @@ module Her
47
47
  # end
48
48
  def collection_path(path = nil)
49
49
  if path.nil?
50
- @_her_collection_path ||= "#{root_element.to_s.pluralize}"
50
+ @_her_collection_path ||= root_element.to_s.pluralize
51
51
  else
52
52
  @_her_collection_path = path
53
53
  @_her_resource_path = "#{path}/:id"
@@ -51,7 +51,8 @@ module Her
51
51
  def fetch
52
52
  @_fetch ||= begin
53
53
  path = @parent.build_request_path(@query_attrs)
54
- @parent.request(@query_attrs.merge(:_method => :get, :_path => path)) do |parsed_data, response|
54
+ method = @parent.method_for(:find)
55
+ @parent.request(@query_attrs.merge(:_method => method, :_path => path)) do |parsed_data, response|
55
56
  @parent.new_collection(parsed_data)
56
57
  end
57
58
  end
@@ -103,6 +104,7 @@ module Her
103
104
  fetch.first || build(attrs)
104
105
  end
105
106
 
107
+ # @private
106
108
  def clear_fetch_cache!
107
109
  instance_variable_set(:@_fetch, nil)
108
110
  end
data/lib/her/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.2"
3
3
  end
@@ -15,6 +15,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
15
15
  before do
16
16
  Her::API.default_api.connection.adapter :test do |stub|
17
17
  stub.post("/users") { |env| [200, {}, { :id => 1, :name => env[:body][:name] }.to_json] }
18
+ stub.put("/users/1") { |env| [200, {}, { :id => 1, :name => env[:body][:name] }.to_json] }
18
19
  end
19
20
  end
20
21
 
@@ -38,6 +39,23 @@ describe "Her::Model and ActiveModel::Callbacks" do
38
39
 
39
40
  its(:name) { should == "TOBIAS FUNKE" }
40
41
  end
42
+
43
+ context "when changing a value of an existing resource in a callback" do
44
+ before do
45
+ class Foo::User
46
+ before_save :alter_name
47
+ def alter_name
48
+ self.name = "Lumberjack" if persisted?
49
+ end
50
+ end
51
+ end
52
+
53
+ it "should call the server with the canged value" do
54
+ subject.name.should == "Tobias Funke"
55
+ subject.save
56
+ subject.name.should == "Lumberjack"
57
+ end
58
+ end
41
59
  end
42
60
 
43
61
  context :before_create do
@@ -156,6 +156,7 @@ describe Her::Model::ORM do
156
156
  builder.adapter :test do |stub|
157
157
  stub.get("/users/1") { |env| [200, {}, { :id => 1, :age => 42 }.to_json] }
158
158
  stub.get("/users/2") { |env| [200, {}, { :id => 2, :age => 34 }.to_json] }
159
+ stub.get("/users?age=42&foo=bar") { |env| [200, {}, [{ :id => 3, :age => 42 }].to_json] }
159
160
  stub.get("/users?age=42") { |env| [200, {}, [{ :id => 1, :age => 42 }].to_json] }
160
161
  stub.get("/users?age=40") { |env| [200, {}, [{ :id => 1, :age => 40 }].to_json] }
161
162
  end
@@ -195,9 +196,9 @@ describe Her::Model::ORM do
195
196
  end
196
197
 
197
198
  it "handles finding with other parameters" do
198
- @users = User.where(:age => 42).all
199
+ @users = User.where(:age => 42, :foo => "bar").all
199
200
  @users.should be_kind_of(Array)
200
- @users.should be_all { |u| u.age == 42 }
201
+ @users.first.id.should == 3
201
202
  end
202
203
 
203
204
  it "handles finding with other parameters and scoped" do
@@ -308,4 +309,68 @@ describe Her::Model::ORM do
308
309
  @user.should be_destroyed
309
310
  end
310
311
  end
312
+
313
+ context 'customizing HTTP methods' do
314
+ before do
315
+ Her::API.setup :url => "https://api.example.com" do |builder|
316
+ builder.use Her::Middleware::FirstLevelParseJSON
317
+ builder.use Faraday::Request::UrlEncoded
318
+ end
319
+ end
320
+
321
+ context 'create' do
322
+ before do
323
+ Her::API.default_api.connection.adapter :test do |stub|
324
+ stub.put('/users') { |env| [200, {}, { :id => 1, :fullname => 'Tobias Fünke' }.to_json] }
325
+ end
326
+ spawn_model 'Foo::User' do
327
+ attributes :fullname, :email
328
+ method_for :create, 'PUT'
329
+ end
330
+ end
331
+
332
+ context 'for top-level class' do
333
+ it 'uses the custom method (PUT) instead of default method (POST)' do
334
+ user = Foo::User.new(:fullname => 'Tobias Fünke')
335
+ user.should be_new
336
+ user.save.should be_true
337
+ end
338
+ end
339
+
340
+ context 'for children class' do
341
+ before do
342
+ class User < Foo::User; end
343
+ @spawned_models << :User
344
+ end
345
+
346
+ it 'uses the custom method (PUT) instead of default method (POST)' do
347
+ user = User.new(:fullname => 'Tobias Fünke')
348
+ user.should be_new
349
+ user.save.should be_true
350
+ end
351
+ end
352
+ end
353
+
354
+ context 'update' do
355
+ before do
356
+ Her::API.default_api.connection.adapter :test do |stub|
357
+ stub.get('/users/1') { |env| [200, {}, { :id => 1, :fullname => 'Lindsay Fünke' }.to_json] }
358
+ stub.post('/users/1') { |env| [200, {}, { :id => 1, :fullname => 'Tobias Fünke' }.to_json] }
359
+ end
360
+
361
+ spawn_model 'Foo::User' do
362
+ attributes :fullname, :email
363
+ method_for :update, :post
364
+ end
365
+ end
366
+
367
+ it 'uses the custom method (POST) instead of default method (PUT)' do
368
+ user = Foo::User.find(1)
369
+ user.fullname.should eq 'Lindsay Fünke'
370
+ user.fullname = 'Toby Fünke'
371
+ user.save
372
+ user.fullname.should eq 'Tobias Fünke'
373
+ end
374
+ end
375
+ end
311
376
  end
@@ -8,7 +8,7 @@ module Her
8
8
  base, submodel = klass.split(/::/).map{ |s| s.to_sym }
9
9
  Object.const_set(base, Module.new) unless Object.const_defined?(base)
10
10
  Object.const_get(base).module_eval do
11
- remove_const submodel if constants.include?(submodel)
11
+ remove_const submodel if constants.map(&:to_sym).include?(submodel)
12
12
  submodel = const_set(submodel, Class.new)
13
13
  submodel.send(:include, Her::Model)
14
14
  submodel.class_eval(&block) if block_given?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: her
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rémi Prévost
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-21 00:00:00.000000000 Z
11
+ date: 2013-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake