application_seeds 0.3.0 → 0.4.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.
- data/CHANGELOG.md +8 -1
- data/README.md +66 -7
- data/lib/application_seeds.rb +25 -9
- data/lib/application_seeds/version.rb +1 -1
- data/spec/application_seeds_spec.rb +55 -0
- data/spec/seed_data/test_inheritable_data_set/companies.yml +9 -0
- data/spec/seed_data/test_inheritable_data_set/level_2/departments.yml +7 -0
- data/spec/seed_data/test_inheritable_data_set/level_2/level_3/people.yml +26 -0
- data/spec/seed_data/test_inheritable_data_set/level_2/people.yml +12 -0
- metadata +12 -4
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
v0.
|
1
|
+
v0.4.0, 2014-02-09
|
2
|
+
------------------
|
3
|
+
|
4
|
+
* Added support for nested/inheritable datasets
|
5
|
+
* Warn user if `ApplicationSeeds.config=` is called after `ApplicationSeeds.dataset=`
|
6
|
+
|
7
|
+
|
8
|
+
v0.3.0, 2014-01-09
|
2
9
|
------------------
|
3
10
|
|
4
11
|
* Added support for Capistrano 3.x
|
data/README.md
CHANGED
@@ -34,12 +34,12 @@ the YAML files into a gem. The gem should have the following directory
|
|
34
34
|
structure:
|
35
35
|
|
36
36
|
```
|
37
|
-
lib
|
38
|
-
+-- seeds
|
39
|
-
|-- seed_data_set_1
|
37
|
+
lib/
|
38
|
+
+-- seeds/
|
39
|
+
|-- seed_data_set_1/
|
40
40
|
| |-- some_data.yml
|
41
41
|
| +-- some_other_data.yml
|
42
|
-
+-- seed_data_set_2
|
42
|
+
+-- seed_data_set_2/
|
43
43
|
|-- some_data.yml
|
44
44
|
+-- some_other_data.yml
|
45
45
|
```
|
@@ -63,11 +63,11 @@ be identical to what is described above in the "Via a gem" section, but the `lib
|
|
63
63
|
diretory is not required.
|
64
64
|
|
65
65
|
```
|
66
|
-
seeds
|
67
|
-
|-- seed_data_set_1
|
66
|
+
seeds/
|
67
|
+
|-- seed_data_set_1/
|
68
68
|
| |-- some_data.yml
|
69
69
|
| +-- some_other_data.yml
|
70
|
-
+-- seed_data_set_2
|
70
|
+
+-- seed_data_set_2/
|
71
71
|
|-- some_data.yml
|
72
72
|
+-- some_other_data.yml
|
73
73
|
```
|
@@ -160,6 +160,65 @@ Then, you can seed a remote database by running the following:
|
|
160
160
|
bundle exec cap <environment> deploy:application_seeds -s dataset=your_data_set
|
161
161
|
|
162
162
|
|
163
|
+
## The Datasets
|
164
|
+
|
165
|
+
The `application_seeds` library supports multiple datasets within the
|
166
|
+
same source (place on the file system, gem, etc). The user specifies
|
167
|
+
which dataset to load when beginning to work with the seed data.
|
168
|
+
|
169
|
+
ApplicationSeeds.dataset = "my_data_set"
|
170
|
+
|
171
|
+
### Nested Datasets
|
172
|
+
|
173
|
+
Datasets can be structured so that child directories can inherit the
|
174
|
+
seed data files that are stored in the parent directories. For example,
|
175
|
+
let's look at the following directory structure:
|
176
|
+
|
177
|
+
```
|
178
|
+
seeds/
|
179
|
+
+-- parent_data_set/
|
180
|
+
|-- companies.yml
|
181
|
+
+-- child_data_set/
|
182
|
+
|-- departments.yml
|
183
|
+
+-- grandchild_data_set/
|
184
|
+
+-- people.yml
|
185
|
+
```
|
186
|
+
|
187
|
+
In this example, if the `grandchild_data_set` is loaded, you will have
|
188
|
+
access to the seed data files in `grandchild_data_set`,
|
189
|
+
`child_data_set`, and `parent_data_set`. Because of this, data from
|
190
|
+
`people.yml`, `departments.yml`, and `companies.yml` can be loaded.
|
191
|
+
|
192
|
+
If `child_data_set` is loaded, you will have access to the seed data
|
193
|
+
files in `child_data_set` and `parent_data_set`, but **not**
|
194
|
+
`grandchild_data_set`. This includes the `departments.yml` and
|
195
|
+
`companies.yml` data files.
|
196
|
+
|
197
|
+
### Merging Data Files
|
198
|
+
|
199
|
+
It is possible to have files for the same data type scattered throughout
|
200
|
+
the dataset hierarchy.
|
201
|
+
|
202
|
+
```
|
203
|
+
seeds/
|
204
|
+
+-- parent_data_set/
|
205
|
+
|-- companies.yml
|
206
|
+
|-- people.yml
|
207
|
+
+-- child_data_set/
|
208
|
+
|-- departments.yml
|
209
|
+
|-- people.yml
|
210
|
+
+-- grandchild_data_set/
|
211
|
+
+-- people.yml
|
212
|
+
```
|
213
|
+
|
214
|
+
In this example, when data is loaded from the `people` dataset via call
|
215
|
+
to `ApplicationSeeds.people`, then the result will contain the data from
|
216
|
+
all three files.
|
217
|
+
|
218
|
+
If the files contain conflicting labels, then precedence is given to
|
219
|
+
data at the lowest level (`grandchild_data_set` in this example).
|
220
|
+
|
221
|
+
|
163
222
|
## The Seed Files
|
164
223
|
|
165
224
|
The seed files contain the data that the Rake task works with to
|
data/lib/application_seeds.rb
CHANGED
@@ -86,6 +86,7 @@ module ApplicationSeeds
|
|
86
86
|
# Specify any configuration, such as the type of ids to generate (:integer or :uuid).
|
87
87
|
#
|
88
88
|
def config=(config)
|
89
|
+
warn "WARNING! Calling ApplicationSeeds.config= after dataset has been set (ApplicationSeeds.dataset=) may not produce expected results." unless @dataset.nil?
|
89
90
|
@_config = config
|
90
91
|
end
|
91
92
|
|
@@ -140,8 +141,8 @@ module ApplicationSeeds
|
|
140
141
|
# the dataset could not be found.
|
141
142
|
#
|
142
143
|
def dataset=(dataset)
|
143
|
-
if dataset.nil? || dataset.strip.empty? ||
|
144
|
-
datasets = Dir[File.join(seed_data_path, "*")].map { |x| File.basename(x) }.join(', ')
|
144
|
+
if dataset.nil? || dataset.strip.empty? || dataset_path(dataset).nil?
|
145
|
+
datasets = Dir[File.join(seed_data_path, "**", "*")].select { |x| File.directory?(x) }.map { |x| File.basename(x) }.join(', ')
|
145
146
|
|
146
147
|
error_message = "\nERROR: A valid dataset is required!\n"
|
147
148
|
error_message << "Usage: bundle exec rake application_seeds:load[your_data_set]\n\n"
|
@@ -150,6 +151,7 @@ module ApplicationSeeds
|
|
150
151
|
end
|
151
152
|
|
152
153
|
store_dataset(dataset)
|
154
|
+
find_seed_data_files(dataset)
|
153
155
|
process_labels(dataset)
|
154
156
|
load_seed_data(dataset)
|
155
157
|
@dataset = dataset
|
@@ -241,14 +243,19 @@ module ApplicationSeeds
|
|
241
243
|
|
242
244
|
def load_seed_data(dataset)
|
243
245
|
@seed_data = {}
|
244
|
-
|
246
|
+
@seed_data_files.each do |seed_file|
|
245
247
|
basename = File.basename(seed_file, ".yml")
|
246
248
|
data = YAML.load(ERB.new(File.read(seed_file)).result)
|
247
249
|
if data
|
248
250
|
data.each do |label, attributes|
|
249
251
|
data[label] = replace_labels_with_ids(attributes)
|
250
252
|
end
|
251
|
-
|
253
|
+
|
254
|
+
if @seed_data[basename].nil?
|
255
|
+
@seed_data[basename] = data
|
256
|
+
else
|
257
|
+
@seed_data[basename] = data.merge(@seed_data[basename])
|
258
|
+
end
|
252
259
|
end
|
253
260
|
end
|
254
261
|
end
|
@@ -313,6 +320,10 @@ module ApplicationSeeds
|
|
313
320
|
end
|
314
321
|
end
|
315
322
|
|
323
|
+
def dataset_path(dataset)
|
324
|
+
Dir[File.join(seed_data_path, "**", "*")].select { |x| File.directory?(x) && File.basename(x) == dataset }.first
|
325
|
+
end
|
326
|
+
|
316
327
|
def fetch(type, &block)
|
317
328
|
result = {}
|
318
329
|
@seed_data[type].each do |label, attrs|
|
@@ -350,11 +361,20 @@ module ApplicationSeeds
|
|
350
361
|
Database.connection.exec("INSERT INTO application_seeds (dataset) VALUES ('#{dataset}');")
|
351
362
|
end
|
352
363
|
|
364
|
+
def find_seed_data_files(dataset)
|
365
|
+
@seed_data_files = []
|
366
|
+
path = dataset_path(dataset)
|
367
|
+
while (seed_data_path != path) do
|
368
|
+
@seed_data_files.concat(Dir[File.join(path, "*.yml")])
|
369
|
+
path.sub!(/\/[^\/]+$/, "")
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
353
373
|
def process_labels(dataset)
|
354
374
|
return @seed_labels unless @seed_labels.nil?
|
355
375
|
|
356
376
|
@seed_labels = {}
|
357
|
-
|
377
|
+
@seed_data_files.each do |seed_file|
|
358
378
|
seed_type = File.basename(seed_file, ".yml")
|
359
379
|
@seed_labels[seed_type] = {}
|
360
380
|
|
@@ -379,10 +399,6 @@ module ApplicationSeeds
|
|
379
399
|
{ :integer => id, :uuid => "00000000-0000-0000-0000-%012d" % id }
|
380
400
|
end
|
381
401
|
|
382
|
-
def seed_files(dataset)
|
383
|
-
Dir[File.join(seed_data_path, dataset, "*.yml")]
|
384
|
-
end
|
385
|
-
|
386
402
|
def id_type(type)
|
387
403
|
self.config["#{type}_id_type".to_sym] || self.config[:id_type]
|
388
404
|
end
|
@@ -9,6 +9,24 @@ class Person
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
class Company
|
13
|
+
attr_accessor :attributes, :id, :saved
|
14
|
+
attr_accessor :name
|
15
|
+
|
16
|
+
def save!(options={})
|
17
|
+
@saved = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Department
|
22
|
+
attr_accessor :attributes, :id, :saved
|
23
|
+
attr_accessor :name
|
24
|
+
|
25
|
+
def save!(options={})
|
26
|
+
@saved = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
12
30
|
describe "ApplicationSeeds" do
|
13
31
|
before do
|
14
32
|
ApplicationSeeds.data_directory = File.join(File.dirname(__FILE__), "seed_data")
|
@@ -219,8 +237,44 @@ describe "ApplicationSeeds" do
|
|
219
237
|
end
|
220
238
|
end
|
221
239
|
|
240
|
+
describe "with a nested dataset" do
|
241
|
+
before do
|
242
|
+
ApplicationSeeds.stub(:store_dataset)
|
243
|
+
ApplicationSeeds.dataset = "level_3"
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "finding seed data" do
|
247
|
+
it "can find data at the root level" do
|
248
|
+
company = ApplicationSeeds.companies(:mega_corp)
|
249
|
+
expect(company['name']).to eql("Megacorp")
|
250
|
+
end
|
251
|
+
it "can find data at the middle level" do
|
252
|
+
department = ApplicationSeeds.departments(:engineering)
|
253
|
+
expect(department['name']).to eql("Engineering")
|
254
|
+
end
|
255
|
+
it "can find data at the lowest level" do
|
256
|
+
person = ApplicationSeeds.people(:joe_smith)
|
257
|
+
expect(person['first_name']).to eql("Joe")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe "merging seed data" do
|
262
|
+
it "can merge data from different levels" do
|
263
|
+
person = ApplicationSeeds.people(:joe_smith)
|
264
|
+
expect(person['first_name']).to eql("Joe")
|
265
|
+
person = ApplicationSeeds.people(:sam_jones)
|
266
|
+
expect(person['first_name']).to eql("Sam")
|
267
|
+
end
|
268
|
+
it "gives the data in lower levels precendence" do
|
269
|
+
person = ApplicationSeeds.people(:ken_adams)
|
270
|
+
expect(person['first_name']).to eql("Ken")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
222
275
|
describe "with UUIDs configured for all seed types" do
|
223
276
|
before do
|
277
|
+
ApplicationSeeds.instance_variable_set("@dataset", nil)
|
224
278
|
ApplicationSeeds.stub(:store_dataset)
|
225
279
|
ApplicationSeeds.config = { :id_type => :uuid }
|
226
280
|
ApplicationSeeds.dataset = "test_data_set"
|
@@ -239,6 +293,7 @@ describe "ApplicationSeeds" do
|
|
239
293
|
|
240
294
|
describe "with data type specific key types configured" do
|
241
295
|
before do
|
296
|
+
ApplicationSeeds.instance_variable_set("@dataset", nil)
|
242
297
|
ApplicationSeeds.stub(:store_dataset)
|
243
298
|
ApplicationSeeds.config = { :id_type => :uuid, :companies_id_type => :integer }
|
244
299
|
ApplicationSeeds.dataset = "test_data_set"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
joe_smith:
|
2
|
+
first_name: Joe
|
3
|
+
last_name: Smith
|
4
|
+
company_id: mega_corp
|
5
|
+
start_date: <%= 2.months.ago.to_date %>
|
6
|
+
bogus_attribute: foo
|
7
|
+
|
8
|
+
jane_doe:
|
9
|
+
first_name: Jane
|
10
|
+
last_name: Doe
|
11
|
+
company_id: mega_corp
|
12
|
+
start_date: <%= 10.months.ago.to_date %>
|
13
|
+
bogus_attribute: foo
|
14
|
+
|
15
|
+
john_walsh:
|
16
|
+
first_name: John
|
17
|
+
last_name: Walsh
|
18
|
+
company_id: ma_and_pa
|
19
|
+
start_date: <%= 10.years.ago.to_date %>
|
20
|
+
bogus_attribute: foo
|
21
|
+
|
22
|
+
ken_adams:
|
23
|
+
first_name: Ken
|
24
|
+
last_name: Adams
|
25
|
+
employer_id: ma_and_pa (companies)
|
26
|
+
start_date: <%= 10.years.ago.to_date %>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: application_seeds
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -101,6 +101,10 @@ files:
|
|
101
101
|
- spec/seed_data/test_data_set/companies.yml
|
102
102
|
- spec/seed_data/test_data_set/departments.yml
|
103
103
|
- spec/seed_data/test_data_set/people.yml
|
104
|
+
- spec/seed_data/test_inheritable_data_set/companies.yml
|
105
|
+
- spec/seed_data/test_inheritable_data_set/level_2/departments.yml
|
106
|
+
- spec/seed_data/test_inheritable_data_set/level_2/level_3/people.yml
|
107
|
+
- spec/seed_data/test_inheritable_data_set/level_2/people.yml
|
104
108
|
homepage: https://github.com/centro/application_seeds
|
105
109
|
licenses:
|
106
110
|
- MIT
|
@@ -116,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
120
|
version: '0'
|
117
121
|
segments:
|
118
122
|
- 0
|
119
|
-
hash:
|
123
|
+
hash: 1911143344573555233
|
120
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
125
|
none: false
|
122
126
|
requirements:
|
@@ -125,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
129
|
version: '0'
|
126
130
|
segments:
|
127
131
|
- 0
|
128
|
-
hash:
|
132
|
+
hash: 1911143344573555233
|
129
133
|
requirements: []
|
130
134
|
rubyforge_project:
|
131
135
|
rubygems_version: 1.8.23
|
@@ -139,3 +143,7 @@ test_files:
|
|
139
143
|
- spec/seed_data/test_data_set/companies.yml
|
140
144
|
- spec/seed_data/test_data_set/departments.yml
|
141
145
|
- spec/seed_data/test_data_set/people.yml
|
146
|
+
- spec/seed_data/test_inheritable_data_set/companies.yml
|
147
|
+
- spec/seed_data/test_inheritable_data_set/level_2/departments.yml
|
148
|
+
- spec/seed_data/test_inheritable_data_set/level_2/level_3/people.yml
|
149
|
+
- spec/seed_data/test_inheritable_data_set/level_2/people.yml
|