repository-manager 0.1.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -8
- data/app/models/repository_manager/repo_file.rb +5 -1
- data/app/models/repository_manager/repo_folder.rb +2 -3
- data/app/models/repository_manager/repo_item.rb +17 -5
- data/app/models/repository_manager/sharing.rb +3 -3
- data/lib/repository_manager/has_repository.rb +24 -10
- data/lib/repository_manager/version.rb +1 -1
- data/spec/has_repository_spec.rb +1 -7
- data/spec/models/repository_spec.rb +41 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f3a34384b57d18db3e94c0979860cf7723fa6e3
|
4
|
+
data.tar.gz: 3f434860b0ca8f9749a570639643f16bd33465e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c69a858299dd6c8a2a3cce3f1a05a9b86c0fdf25fff66fa124f48c7f83735051d828a3c2a8bfc53b978ba01cb3415973703732cdba97087af1748a3c885655fd
|
7
|
+
data.tar.gz: a4ffcdf75acd0333f868435d13cfebbbbc6fb9b8c84b1298f19c7028f70e34f7689e6a91c633b8217157a901299c4a27da1a9109c4293442a0e63a0e40667c53
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@ WORK IN PROGRESS, but it already works !
|
|
2
2
|
|
3
3
|
Ruby on Rails plugin (gem) for managing repositories (files/folders/permissions/sharing).
|
4
4
|
|
5
|
-
# RepositoryManager
|
5
|
+
# RepositoryManager [![Gem Version](https://badge.fury.io/rb/repository-manager.png)](http://badge.fury.io/rb/repository-manager)
|
6
6
|
|
7
7
|
This gem add functionalities to manage repositories. Each instance (users, groups, etc..) can have it own repository (with files and folders). It can manage them (edit, remove, add, etc) and share them with other objects.
|
8
8
|
|
@@ -63,6 +63,7 @@ end
|
|
63
63
|
```
|
64
64
|
|
65
65
|
For instance, if you want that a default sharing is totally free (for edit, delete, etc), just put all default parameters to `true` :
|
66
|
+
|
66
67
|
```ruby
|
67
68
|
RepositoryManager.setup do |config|
|
68
69
|
config.default_repo_item_permissions = { can_read: true, can_create: true, can_update: true, can_delete: true, can_share: true }
|
@@ -142,6 +143,11 @@ the_new_folder = user1.create_folder('The new folder', source_folder: source_fol
|
|
142
143
|
user1.create_file(params[:file], source_folder: the_new_folder)
|
143
144
|
# OR
|
144
145
|
user1.create_file(File.open('somewhere'), source_folder: the_new_folder)
|
146
|
+
# OR
|
147
|
+
repo_file = RepositoryManager::RepoFile.new
|
148
|
+
repo_file.file = your_file
|
149
|
+
user1.create_file(repo_file, source_folder: the_new_folder)
|
150
|
+
|
145
151
|
|
146
152
|
# user1 own repository :
|
147
153
|
# |-- 'Root folder'
|
@@ -177,6 +183,16 @@ user1.move_repo_item(the_new_folder, source_folder: test_folder)
|
|
177
183
|
# | |-- 'The new folder'
|
178
184
|
# | | |-- 'file.txt'
|
179
185
|
|
186
|
+
# user1 want to rename 'The new folder' to 'The renamed folder'
|
187
|
+
user1.rename_repo_item(the_new_folder, 'The renamed folder')
|
188
|
+
|
189
|
+
# user1 own repository :
|
190
|
+
# |-- 'Root folder'
|
191
|
+
# |-- 'file2.jpg'
|
192
|
+
# |-- 'Test folder'
|
193
|
+
# | |-- 'The renamed folder'
|
194
|
+
# | | |-- 'file.txt'
|
195
|
+
|
180
196
|
# Delete a repo_item
|
181
197
|
# Note : user1 needs the ':can_delete => true' permission in the folder : the_new_folder (else the method returns `false`).
|
182
198
|
user1.delete_repo_item(test_folder)
|
@@ -192,14 +208,17 @@ user1.delete_repo_item(file2)
|
|
192
208
|
|
193
209
|
```
|
194
210
|
|
195
|
-
If a user (sender of the
|
211
|
+
If a user (sender of the item) send a file or folder into a group (owner of this item), you can specify the owner and the sender like this :
|
196
212
|
|
197
213
|
```ruby
|
198
214
|
# user1 wants to create a folder and a file into group1
|
199
215
|
folder = group1.create_folder('Folder created by user1', sender: user1)
|
200
216
|
|
217
|
+
folder.owner # Returns group1
|
218
|
+
folder.sender # Returns user1
|
219
|
+
|
201
220
|
# Now he send the file into the folder
|
202
|
-
file = group1.create_file(params[:file], source_folder:
|
221
|
+
file = group1.create_file(params[:file], source_folder: folder, sender: user1)
|
203
222
|
|
204
223
|
file.owner # Returns group1
|
205
224
|
file.sender # Returns user1
|
@@ -208,6 +227,8 @@ file.sender # Returns user1
|
|
208
227
|
|
209
228
|
```
|
210
229
|
|
230
|
+
WARNING : There is no verification if the user has the authorisation to create a file or folder into this group. You have to check this in your controller ! The fact that user1 is the sender of this folder gives him NO AUTHORISATION on it !
|
231
|
+
|
211
232
|
### How can I share a repo_item (file/folder)
|
212
233
|
|
213
234
|
Now, user1 want to share his folder 'The new folder' with a Group object `group1` et another User object `user2`. You can use the `has_repository` method `share(repo_item, member, options = nil)`.
|
@@ -292,9 +313,9 @@ Recall: a repo_item can be:
|
|
292
313
|
|
293
314
|
```ruby
|
294
315
|
# We want to know if the object repo_item is a file or a folder:
|
295
|
-
if repo_item.
|
316
|
+
if repo_item.is_folder
|
296
317
|
repo_item.name #=> Returns the name of the folder (for instance : 'New folder').
|
297
|
-
elsif repo_item.
|
318
|
+
elsif repo_item.is_file?
|
298
319
|
repo_item.name #=> Returns the name of the file (for instance : 'file.png').
|
299
320
|
# Here is the file
|
300
321
|
repo_item.file.url # => '/url/to/file.png'
|
@@ -423,10 +444,7 @@ the_folder.delete_zip
|
|
423
444
|
|
424
445
|
## TODO
|
425
446
|
|
426
|
-
- Test the rename folder method
|
427
|
-
- Test if the file already exist before creating or moving it
|
428
447
|
- Do the rename file method
|
429
|
-
- Write the documentation for the rename method
|
430
448
|
- Write the methods : copy, share_link.
|
431
449
|
- Snapshot the file if possible
|
432
450
|
- Versioning
|
@@ -437,3 +455,5 @@ the_folder.delete_zip
|
|
437
455
|
|
438
456
|
This project rocks and uses MIT-LICENSE.
|
439
457
|
|
458
|
+
Created by Yves Baumann.
|
459
|
+
|
@@ -10,8 +10,12 @@ class RepositoryManager::RepoFile < RepositoryManager::RepoItem
|
|
10
10
|
file.url.split('/').last
|
11
11
|
end
|
12
12
|
|
13
|
-
# Downloading this file
|
14
13
|
def download(options = {})
|
14
|
+
self.download!(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Downloading this file
|
18
|
+
def download!(options = {})
|
15
19
|
path = file.path
|
16
20
|
#render status: :bad_request and return unless File.exist?(path)
|
17
21
|
#send_file(path)
|
@@ -122,7 +122,6 @@ class RepositoryManager::RepoFolder < RepositoryManager::RepoItem
|
|
122
122
|
end
|
123
123
|
|
124
124
|
private
|
125
|
-
|
126
125
|
# Returns the default path of the zip file
|
127
126
|
# object is the object that want to download this file
|
128
127
|
def get_default_download_path(object = nil)
|
@@ -133,10 +132,10 @@ class RepositoryManager::RepoFolder < RepositoryManager::RepoItem
|
|
133
132
|
def add_repo_item_to_zip(children, zf, object = nil, prefix = nil)
|
134
133
|
children.each do |child|
|
135
134
|
# If this is a file, we just add this file to the zip
|
136
|
-
if child.
|
135
|
+
if child.is_file?
|
137
136
|
# Add the file in the zip if the object is authorised to read it.
|
138
137
|
zf.add("#{prefix}#{child.name}", child.file.current_path) if object == nil || !RepositoryManager.accept_nested_sharing || object.can_read?(child)
|
139
|
-
elsif child.
|
138
|
+
elsif child.is_folder?
|
140
139
|
# If this folder has children, we do it again with it children
|
141
140
|
if child.has_children?
|
142
141
|
# We go in this new directory and add it repo_items
|
@@ -40,11 +40,13 @@ class RepositoryManager::RepoItem < ActiveRecord::Base
|
|
40
40
|
|
41
41
|
# Move itself into the target_folder
|
42
42
|
def move!(target_folder)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
unless target_folder.is_folder?
|
44
|
+
raise RepositoryManager::RepositoryManagerException.new("move failed. target '#{target_folder.name}' can't be a file")
|
45
|
+
end
|
46
|
+
if target_folder.name_exist_in_children?(self.name)
|
47
|
+
raise RepositoryManager::RepositoryManagerException.new("move failed. The repo_item '#{name}' already exist ine the folder '#{target_folder.name}'")
|
47
48
|
end
|
49
|
+
self.update_attribute :parent, target_folder
|
48
50
|
end
|
49
51
|
|
50
52
|
def move(target_folder)
|
@@ -59,7 +61,7 @@ class RepositoryManager::RepoItem < ActiveRecord::Base
|
|
59
61
|
def has_nested_sharing?
|
60
62
|
# An array with the ids of all ancestors and descendants
|
61
63
|
ancestor_and_descendant_ids = []
|
62
|
-
ancestor_and_descendant_ids << self.descendant_ids if self.
|
64
|
+
ancestor_and_descendant_ids << self.descendant_ids if self.is_folder? && !self.descendant_ids.empty?
|
63
65
|
ancestor_and_descendant_ids << self.ancestor_ids if !self.ancestor_ids.empty?
|
64
66
|
|
65
67
|
# If it exist a sharing, it returns true
|
@@ -70,6 +72,16 @@ class RepositoryManager::RepoItem < ActiveRecord::Base
|
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
75
|
+
# Returns true if it is a folder
|
76
|
+
def is_folder?
|
77
|
+
self.type == 'RepositoryManager::RepoFolder'
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns true if it is a file
|
81
|
+
def is_file?
|
82
|
+
self.type == 'RepositoryManager::RepoFile'
|
83
|
+
end
|
84
|
+
|
73
85
|
private
|
74
86
|
def put_sender
|
75
87
|
self.sender = owner unless sender
|
@@ -21,7 +21,7 @@ class RepositoryManager::Sharing < ActiveRecord::Base
|
|
21
21
|
# If the member is the owner, he can do what he want !
|
22
22
|
if self.owner == member
|
23
23
|
return true
|
24
|
-
elsif i = self.sharings_members.where(
|
24
|
+
elsif i = self.sharings_members.where(member: member).first
|
25
25
|
return {can_add: i.can_add, can_remove: i.can_remove}
|
26
26
|
else
|
27
27
|
return false
|
@@ -51,10 +51,10 @@ class RepositoryManager::Sharing < ActiveRecord::Base
|
|
51
51
|
if members.kind_of?(Array)
|
52
52
|
# Add each member to this sharing
|
53
53
|
members.each do |member|
|
54
|
-
self.sharings_members.where(
|
54
|
+
self.sharings_members.where(member: member).first.destroy
|
55
55
|
end
|
56
56
|
else
|
57
|
-
self.sharings_members.where(:
|
57
|
+
self.sharings_members.where(member: members).first.destroy
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -94,6 +94,11 @@ module RepositoryManager
|
|
94
94
|
# AuthorisationException if the object don't have the permission
|
95
95
|
def create_folder!(name = '', options = {})
|
96
96
|
source_folder = options[:source_folder]
|
97
|
+
if source_folder
|
98
|
+
unless source_folder.is_folder?
|
99
|
+
raise RepositoryManager::RepositoryManagerException.new("create folder failed. The source folder must be a repo_folder.")
|
100
|
+
end
|
101
|
+
end
|
97
102
|
|
98
103
|
# If he want to create a folder in a directory, we have to check if he have the authorisation
|
99
104
|
if can_create?(source_folder)
|
@@ -163,13 +168,22 @@ module RepositoryManager
|
|
163
168
|
# AuthorisationException if the object don't have the permission
|
164
169
|
def create_file!(file, options = {})
|
165
170
|
source_folder = options[:source_folder]
|
171
|
+
if source_folder
|
172
|
+
unless source_folder.is_folder?
|
173
|
+
raise RepositoryManager::RepositoryManagerException.new("create file failed. The source folder must be a repo_folder.")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
166
177
|
# If he want to create a file in a directory, we have to check if he have the authorisation
|
167
178
|
if can_create?(source_folder)
|
179
|
+
|
168
180
|
if file.class.name == 'RepositoryManager::RepoFile'
|
169
181
|
repo_file = file
|
170
|
-
|
171
|
-
repo_file = RepositoryManager::RepoFile.new
|
182
|
+
elsif file.class.name == 'File'
|
183
|
+
repo_file = RepositoryManager::RepoFile.new()
|
172
184
|
repo_file.file = file
|
185
|
+
else # "ActionController::Parameters"
|
186
|
+
repo_file = RepositoryManager::RepoFile.new(file)
|
173
187
|
end
|
174
188
|
|
175
189
|
repo_file.owner = self
|
@@ -236,7 +250,7 @@ module RepositoryManager
|
|
236
250
|
if can_download?(repo_item)
|
237
251
|
path = options[:path] if options[:path]
|
238
252
|
|
239
|
-
repo_item.download({object: self, path: path})
|
253
|
+
repo_item.download!({object: self, path: path})
|
240
254
|
else
|
241
255
|
raise RepositoryManager::AuthorisationException.new("download failed. You don't have the permission to download the repo_item '#{repo_item.name}'")
|
242
256
|
end
|
@@ -255,7 +269,7 @@ module RepositoryManager
|
|
255
269
|
unless can_update?(repo_item)
|
256
270
|
raise RepositoryManager::AuthorisationException.new("rename repo_item failed. You don't have the permission to update the repo_item '#{repo_item.name}'")
|
257
271
|
end
|
258
|
-
repo_item.rename(new_name)
|
272
|
+
repo_item.rename!(new_name)
|
259
273
|
end
|
260
274
|
|
261
275
|
# Rename the repo_item with the new_name
|
@@ -276,13 +290,13 @@ module RepositoryManager
|
|
276
290
|
raise RepositoryManager::AuthorisationException.new("move repo_item failed. You don't have the permission to create in the target_folder '#{target_folder.name}'")
|
277
291
|
end
|
278
292
|
# If it has the permission, we move the repo_item in the target_folder
|
279
|
-
repo_item.move(target_folder)
|
293
|
+
repo_item.move!(target_folder)
|
280
294
|
end
|
281
295
|
|
282
296
|
def move_repo_item(repo_item, target_folder)
|
283
297
|
begin
|
284
298
|
move_repo_item!(repo_item, target_folder)
|
285
|
-
rescue RepositoryManager::AuthorisationException
|
299
|
+
rescue RepositoryManager::RepositoryManagerException, RepositoryManager::AuthorisationException
|
286
300
|
false
|
287
301
|
end
|
288
302
|
end
|
@@ -375,7 +389,7 @@ module RepositoryManager
|
|
375
389
|
end
|
376
390
|
end
|
377
391
|
|
378
|
-
# You can here
|
392
|
+
# You can here remove members in the sharing
|
379
393
|
# Param member could be an object or an array of object
|
380
394
|
def remove_members_from!(sharing, members)
|
381
395
|
if can_remove_from?(sharing)
|
@@ -504,7 +518,7 @@ module RepositoryManager
|
|
504
518
|
# Put a default name if none is given
|
505
519
|
def default_folder_name(source_folder)
|
506
520
|
i = ''
|
507
|
-
name = "#{I18n.t 'repository_manager.models.repo_folder.name'}
|
521
|
+
name = "#{I18n.t 'repository_manager.models.repo_folder.name'}"
|
508
522
|
# We check if another item has the same name
|
509
523
|
|
510
524
|
if source_folder
|
@@ -515,7 +529,7 @@ module RepositoryManager
|
|
515
529
|
i = 1
|
516
530
|
end
|
517
531
|
i += 1
|
518
|
-
name = "#{I18n.t 'repository_manager.models.repo_folder.name'}#{i}"
|
532
|
+
name = "#{I18n.t 'repository_manager.models.repo_folder.name'} #{i}"
|
519
533
|
end
|
520
534
|
else
|
521
535
|
#TODO Optimiser, récupérer tout les instances contenants le nom, puis faire la boucle (pas boucle de requete)
|
@@ -525,7 +539,7 @@ module RepositoryManager
|
|
525
539
|
i = 1
|
526
540
|
end
|
527
541
|
i += 1
|
528
|
-
name = "#{I18n.t 'repository_manager.models.repo_folder.name'}#{i}"
|
542
|
+
name = "#{I18n.t 'repository_manager.models.repo_folder.name'} #{i}"
|
529
543
|
end
|
530
544
|
|
531
545
|
end
|
data/spec/has_repository_spec.rb
CHANGED
@@ -18,13 +18,6 @@ describe 'HasRepository' do
|
|
18
18
|
expect(@user2.sharings.last).to eq(sharing)
|
19
19
|
end
|
20
20
|
|
21
|
-
it "can add a file to repo_item" do
|
22
|
-
#TODO
|
23
|
-
end
|
24
|
-
|
25
|
-
it "can add a folder to repo_item" do
|
26
|
-
#TODO
|
27
|
-
end
|
28
21
|
|
29
22
|
it 'can share his own repo_item with other users' do
|
30
23
|
rep = FactoryGirl.build(:rm_repo_file)
|
@@ -278,4 +271,5 @@ describe 'HasRepository' do
|
|
278
271
|
expect(@user1.repo_items.count).to eq(1)
|
279
272
|
expect(@user1.repo_items.files.count).to eq(1)
|
280
273
|
end
|
274
|
+
|
281
275
|
end
|
@@ -15,11 +15,18 @@ describe 'RepoItem' do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'can create a folder in it own folder' do
|
18
|
-
|
18
|
+
@user1.create_folder('Folder1', source_folder: @user1_folder)
|
19
19
|
|
20
20
|
expect(@user1_folder.has_children?).to eq(true)
|
21
21
|
end
|
22
22
|
|
23
|
+
it 'can\'t create a folder in it a file' do
|
24
|
+
folder = @user1.create_folder('Folder1', source_folder: @user1_file)
|
25
|
+
|
26
|
+
expect(folder).to eq(false)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
23
30
|
it 'can\'t create a folder in another folder without permission' do
|
24
31
|
folder = @user2.create_folder('Folder1', source_folder: @user1_folder)
|
25
32
|
|
@@ -133,19 +140,11 @@ describe 'RepoItem' do
|
|
133
140
|
expect(test_folder.parent_id).to eq(@user1_folder.id)
|
134
141
|
end
|
135
142
|
|
136
|
-
it 'can move a folder into another folder' do
|
137
|
-
folder = @user1.create_folder('Folder1', source_folder: @user1_folder)
|
138
|
-
expect(@user1.repo_items.count).to eq(3)
|
139
|
-
folder2 = @user1.create_folder('Folder1', source_folder: @user1_folder)
|
140
|
-
expect(folder2).to eq(false)
|
141
|
-
expect(@user1.repo_items.count).to eq(3)
|
142
|
-
folder3 = @user1.create_folder('Folder2', source_folder: @user1_folder)
|
143
|
-
expect(@user1.repo_items.count).to eq(4)
|
144
|
-
# TODO
|
145
|
-
end
|
146
|
-
|
147
143
|
it 'can rename it own folder' do
|
148
|
-
|
144
|
+
@user1.rename_repo_item(@user1_folder, 'test new name')
|
145
|
+
|
146
|
+
expect(@user1_folder.reload.name).to eq('test new name')
|
147
|
+
|
149
148
|
end
|
150
149
|
|
151
150
|
it 'can rename it own file' do
|
@@ -154,12 +153,11 @@ describe 'RepoItem' do
|
|
154
153
|
|
155
154
|
it 'can rename item with share update permission' do
|
156
155
|
# TODO
|
157
|
-
|
158
156
|
end
|
159
157
|
|
160
158
|
it 'can\'t rename item without share update permission' do
|
161
|
-
|
162
|
-
|
159
|
+
@user2.rename_repo_item(@user1_folder, 'test new name')
|
160
|
+
expect(@user1_folder.reload.name).to eq('Folder')
|
163
161
|
end
|
164
162
|
|
165
163
|
it 'can create a new folder with different name' do
|
@@ -170,9 +168,9 @@ describe 'RepoItem' do
|
|
170
168
|
|
171
169
|
# TODO add translate in gem
|
172
170
|
expect(folder1.name).to eq('translation missing: en.repository_manager.models.repo_folder.name')
|
173
|
-
expect(folder2.name).to eq('translation missing: en.repository_manager.models.repo_folder.
|
171
|
+
expect(folder2.name).to eq('translation missing: en.repository_manager.models.repo_folder.name 2')
|
174
172
|
expect(folder3.name).to eq('translation missing: en.repository_manager.models.repo_folder.name')
|
175
|
-
expect(folder4.name).to eq('translation missing: en.repository_manager.models.repo_folder.
|
173
|
+
expect(folder4.name).to eq('translation missing: en.repository_manager.models.repo_folder.name 2')
|
176
174
|
|
177
175
|
end
|
178
176
|
|
@@ -220,4 +218,29 @@ describe 'RepoItem' do
|
|
220
218
|
file = @user2.create_file(File.open("#{Rails.root}/../fixture/textfile.txt"), sender: @user1)
|
221
219
|
expect(file.sender).to eq(@user1)
|
222
220
|
end
|
221
|
+
|
222
|
+
it "can move a file to folder" do
|
223
|
+
file = @user2.create_file(File.open("#{Rails.root}/../fixture/textfile.txt"))
|
224
|
+
folder = @user2.create_folder('folder')
|
225
|
+
|
226
|
+
@user2.move_repo_item(file, folder)
|
227
|
+
|
228
|
+
expect(folder.children).to eq([file])
|
229
|
+
end
|
230
|
+
|
231
|
+
it "can move a folder to folder" do
|
232
|
+
folder = @user2.create_folder('folder')
|
233
|
+
folder2 = @user2.create_folder('folder2')
|
234
|
+
@user2.move_repo_item(folder, folder2)
|
235
|
+
|
236
|
+
expect(folder2.children).to eq([folder])
|
237
|
+
end
|
238
|
+
|
239
|
+
it "can't move a folder into a file" do
|
240
|
+
file = @user2.create_file(File.open("#{Rails.root}/../fixture/textfile.txt"))
|
241
|
+
folder = @user2.create_folder('folder')
|
242
|
+
|
243
|
+
expect(@user2.move_repo_item(folder,file)).to eq(false)
|
244
|
+
end
|
245
|
+
|
223
246
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: repository-manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yves Baumann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|