sprig 0.1.6 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +61 -10
  3. data/lib/generators/sprig/install_generator.rb +5 -1
  4. data/lib/sprig.rb +21 -0
  5. data/lib/sprig/configuration.rb +19 -2
  6. data/lib/sprig/directive.rb +3 -3
  7. data/lib/sprig/helpers.rb +15 -3
  8. data/lib/sprig/planter.rb +1 -1
  9. data/lib/sprig/process_notifier.rb +4 -4
  10. data/lib/sprig/seed/attribute.rb +27 -3
  11. data/lib/sprig/seed/entry.rb +8 -4
  12. data/lib/sprig/seed/factory.rb +1 -1
  13. data/lib/sprig/source.rb +10 -1
  14. data/lib/sprig/version.rb +8 -1
  15. data/spec/adapters/active_record.rb +34 -0
  16. data/spec/adapters/mongoid.rb +19 -0
  17. data/spec/adapters/mongoid.yml +12 -0
  18. data/spec/feature/configurations_spec.rb +5 -5
  19. data/spec/fixtures/models/{comment.rb → active_record/comment.rb} +0 -0
  20. data/spec/fixtures/models/{post.rb → active_record/post.rb} +0 -0
  21. data/spec/fixtures/models/{tag.rb → active_record/tag.rb} +0 -0
  22. data/spec/fixtures/models/{user.rb → active_record/user.rb} +0 -0
  23. data/spec/fixtures/models/mongoid/comment.rb +9 -0
  24. data/spec/fixtures/models/mongoid/post.rb +18 -0
  25. data/spec/fixtures/models/mongoid/tag.rb +7 -0
  26. data/spec/fixtures/models/mongoid/user.rb +9 -0
  27. data/spec/fixtures/seeds/shared/comments.yml +4 -0
  28. data/spec/fixtures/seeds/shared/files/cat.png +0 -0
  29. data/spec/fixtures/seeds/shared/invalid_users.yml +4 -0
  30. data/spec/fixtures/seeds/shared/legacy_posts.yml +4 -0
  31. data/spec/fixtures/seeds/shared/posts.csv +2 -0
  32. data/spec/fixtures/seeds/shared/posts.json +1 -0
  33. data/spec/fixtures/seeds/shared/posts.md +5 -0
  34. data/spec/fixtures/seeds/shared/posts.yml +4 -0
  35. data/spec/fixtures/seeds/shared/posts_delete_existing_by.yml +7 -0
  36. data/spec/fixtures/seeds/shared/posts_find_existing_by_missing.yml +7 -0
  37. data/spec/fixtures/seeds/shared/posts_find_existing_by_multiple.yml +8 -0
  38. data/spec/fixtures/seeds/shared/posts_find_existing_by_single.yml +7 -0
  39. data/spec/fixtures/seeds/shared/posts_missing_dependency.yml +5 -0
  40. data/spec/fixtures/seeds/shared/posts_missing_record.yml +5 -0
  41. data/spec/fixtures/seeds/shared/posts_partially_dynamic_value.yml +4 -0
  42. data/spec/fixtures/seeds/shared/posts_with_cyclic_dependencies.yml +4 -0
  43. data/spec/fixtures/seeds/shared/posts_with_files.yml +5 -0
  44. data/spec/fixtures/seeds/shared/posts_with_habtm.yml +7 -0
  45. data/spec/fixtures/seeds/shared/tags.yml +5 -0
  46. data/spec/fixtures/seeds/test/posts_partially_dynamic_value.yml +4 -0
  47. data/spec/lib/generators/sprig/install_generator_spec.rb +6 -2
  48. data/spec/lib/sprig/configuration_spec.rb +6 -6
  49. data/spec/lib/sprig/directive_list_spec.rb +4 -4
  50. data/spec/lib/sprig/directive_spec.rb +21 -11
  51. data/spec/lib/sprig/null_record_spec.rb +2 -2
  52. data/spec/lib/sprig/parser/base_spec.rb +1 -1
  53. data/spec/lib/sprig/process_notifier_spec.rb +5 -3
  54. data/spec/lib/sprig/seed/entry_spec.rb +3 -3
  55. data/spec/lib/sprig/seed/record_spec.rb +3 -3
  56. data/spec/lib/sprig/source_spec.rb +2 -2
  57. data/spec/lib/sprig_spec.rb +59 -8
  58. data/spec/spec_helper.rb +35 -31
  59. data/spec/sprig_shared_spec.rb +467 -0
  60. data/spec/sprig_spec.rb +105 -34
  61. data/spec/support/helpers/logger_mock.rb +2 -1
  62. metadata +167 -87
  63. data/lib/sprig/data.rb +0 -6
  64. data/spec/db/activerecord.db +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a11f717b26ca547b63e3a10d77e90e5fb0b34f99
4
- data.tar.gz: 875a60cf93f12dda5e3cf04f17dca18c1201f53c
2
+ SHA256:
3
+ metadata.gz: 467afaf41af6215b9da174e770e94265ae30774763a0b3f650086a56d15ecaea
4
+ data.tar.gz: 15ca2de82777633d207c659acef1bbd4aed1cfa0c4eb579a36ac8f74a12e9ae9
5
5
  SHA512:
6
- metadata.gz: 3c5b80e9fbc98aeca33b2f535336a4ac577f4837ecc88b5315351f5cef5582bf67b6fad52a4af4b706c045bdb3120461c1c74b5e118eb177406f66a824e5cf99
7
- data.tar.gz: 7660d42b5f0ca71849c63de2abaef6cc4ad324ee08598b00676b4196c80050eeb49264589258e601504ad5bac97514edfe42d5ec0624dbdb87193a903d0db875
6
+ metadata.gz: 29ffd4703a02baed76c2b6c4f1a1a30d56eed668e7bdf9ae4da07902e6271196e6f846ec734c0cd1aa6f24b52b4bf222b61bb9e62cd6a5a65933deed0d55fa7a
7
+ data.tar.gz: 69cb476a52cec76ca0752ef562dad5d5ee4c260367d7d4d62ae30e1adadf346d5adb69670142e4ce285a048c652bcd1acda934ebb00125aaeac77d8a702f9531
data/README.md CHANGED
@@ -10,9 +10,13 @@ Learn more about Sprig and view documentation at [http://vigetlabs.github.io/spr
10
10
 
11
11
  ## Installation
12
12
 
13
- Use `rails generate sprig:install` to create environment-specific seed directories.
13
+ Add into your Gemfile
14
+ ```ruby
15
+ gem "sprig"
16
+ ```
17
+ Use `rails generate sprig:install` to create environment-specific and shared seed directories.
14
18
 
15
- ##The Sprig Directive
19
+ ## The Sprig Directive
16
20
 
17
21
  Within your seed file, you can use the `sprig` directive to initiate Sprig's dark magicks. A simple directive might look like this.
18
22
 
@@ -22,18 +26,30 @@ Within your seed file, you can use the `sprig` directive to initiate Sprig's dar
22
26
  include Sprig::Helpers
23
27
 
24
28
  sprig [User, Post, Comment]
29
+
30
+ For shared seeds:
31
+ sprig_shared [User, Post, Comment]
25
32
  ```
26
33
 
27
34
  This directive tells Sprig to go find your datafiles for the `User`, `Post`, and `Comment` seed resources, build records from the data entries, and insert them into the database. Sprig will automatically detect known datafile types like `.yml`, `.json`, or `.csv` within your environment-specific seed directory.
28
35
 
29
- ##Environment
36
+ ## Environment
30
37
 
31
38
  Seed files are unique to the environment in which your Rails application is running. Within `db/seeds` create an environment-specific directory (i.e. `/development` for your 'development' environment).
32
39
 
33
- Todo: [Support for shared seed files]
40
+ ### Shared
34
41
 
42
+ Shared seed files default directory is `shared` (eg `db/seeds/shared`)
43
+ You can change it by settings`
44
+
45
+ To insert env specific together with shared seeds use:
46
+ ```ruby
47
+ sprig [User]
48
+ sprig_shared [User]
49
+ ```
50
+ This will insert `:env/users` and `shared/users` seeds
35
51
 
36
- ##Seed files
52
+ ## Seed files
37
53
 
38
54
  Hang your seed definitions on a `records` key for *yaml* and *json* files.
39
55
 
@@ -47,7 +63,7 @@ records:
47
63
  first_name: 'Lawson'
48
64
  last_name: 'Kurtz'
49
65
  username: 'lawdawg'
50
- - sprig_id: 2
66
+ - sprig_id: 'ryan' # Note: Sprig IDs can be integers or strings
51
67
  first_name: 'Ryan'
52
68
  last_name: 'Foster'
53
69
  username: 'mc_rubs'
@@ -74,6 +90,8 @@ records:
74
90
 
75
91
  Each seed record needs a `sprig_id` defined that must be *unique across all seed files per class*. It can be an integer, string, whatever you prefer; as long as it is unique, Sprig can sort your seeds for insertion and detect any cyclic relationships.
76
92
 
93
+ ### Relationships
94
+
77
95
  Create relationships between seed records with the `sprig_record` helper:
78
96
 
79
97
  ```yaml
@@ -85,6 +103,28 @@ records:
85
103
  body: "Yaml Comment body"
86
104
  ```
87
105
 
106
+ #### Has and Belongs to Many
107
+ For `has_and_belongs_to_many` (HABTM) relationships, you may define relation ids in array format. So if `Post` `has_and_belongs_to_many :tags`, you could write:
108
+ ```yaml
109
+ #posts.yml
110
+
111
+ records:
112
+ - sprig_id: 42
113
+ title: 'All About Brains'
114
+ content: 'Lorem ipsum...'
115
+ tag_ids:
116
+ - '<%= sprig_record(Tag, 1).id %>'
117
+ - '<%= sprig_record(Tag, 2).id %>'
118
+ ```
119
+ ```yaml
120
+ #tags.yml
121
+
122
+ records:
123
+ - sprig_id: 'bio'
124
+ name: 'Biology'
125
+ - sprig_id: 'neuro'
126
+ name: 'Neuroscience'
127
+ ```
88
128
  **Note: For namespaced or STI classes, you'll need to include the namespace with the class name in the seed file name. For example `Users::HeadManager` would need to be `users_head_managers.yml`**
89
129
 
90
130
  ### Special Options
@@ -119,15 +159,17 @@ records:
119
159
  published_at: "<%= 1.week.ago %>"
120
160
  ```
121
161
 
122
- ##Custom Sources and Parsers
162
+ ## Custom Sources and Parsers
123
163
 
124
164
  If all your data is in `.wat` files, fear not. You can tell Sprig where to look for your data, and point it toward a custom parser class for turning your data into records. The example below tells Sprig to read `User` seed data from a Google Spreadsheet, and parse it accordingly.
125
165
 
126
166
  ```ruby
167
+ require 'open-uri'
168
+
127
169
  fanciness = {
128
170
  :class => User,
129
171
  :source => open('https://spreadsheets.google.com/feeds/list/somerandomtoken/1/public/values?alt=json'),
130
- :parser => Sprig::Data::Parser::GoogleSpreadsheetJson
172
+ :parser => Sprig::Parser::GoogleSpreadsheetJson
131
173
  }
132
174
 
133
175
  sprig [
@@ -137,23 +179,32 @@ sprig [
137
179
  ]
138
180
  ```
139
181
 
140
- ##Configuration
182
+ ## Configuration
141
183
 
142
184
  When Sprig conventions don't suit, just add a configuration block to your seed file.
143
185
 
144
186
  ```ruby
145
187
  Sprig.configure do |c|
146
188
  c.directory = 'seed_files'
189
+ c.shared_directory = 'shared'
147
190
  end
148
191
  ```
149
192
 
150
193
  ## Populate Seed Files from Database
151
194
 
152
195
  Want to create Sprig seed files from the records in your database? Well,
153
- [Sprig::Reap](http://www.rubygems.org/sprig-reap) can create them for you! Check out the gem's
196
+ [Sprig::Reap](https://rubygems.org/gems/sprig-reap) can create them for you! Check out the gem's
154
197
  [README](https://github.com/vigetlabs/sprig-reap#sprigreap) for installation instructions and
155
198
  details on usage.
156
199
 
157
200
  ## License
158
201
 
159
202
  This project rocks and uses MIT-LICENSE.
203
+
204
+ ***
205
+
206
+ <a href="http://code.viget.com">
207
+ <img src="http://code.viget.com/github-banner.png" alt="Code At Viget">
208
+ </a>
209
+
210
+ Visit [code.viget.com](http://code.viget.com) to see more projects from [Viget.](https://viget.com)
@@ -9,12 +9,16 @@ module Sprig
9
9
 
10
10
  def create_enviroment_directories
11
11
  empty_directory 'db/seeds'
12
-
12
+ create_shared_directory
13
13
  envs.each { |env| empty_directory "db/seeds/#{env}" }
14
14
  end
15
15
 
16
16
  private
17
17
 
18
+ def create_shared_directory
19
+ empty_directory 'db/seeds/shared'
20
+ end
21
+
18
22
  def envs
19
23
  arg_envs ? arg_envs : default_envs
20
24
  end
data/lib/sprig.rb CHANGED
@@ -19,6 +19,27 @@ module Sprig
19
19
  autoload :Seed, 'sprig/seed'
20
20
 
21
21
  class << self
22
+ attr_writer :adapter, :shared_seeding
23
+
24
+ def adapter
25
+ @adapter ||= :active_record
26
+ end
27
+
28
+ def adapter_model_class
29
+ @adapter_model_class ||= case adapter
30
+ when :active_record
31
+ ActiveRecord::Base
32
+ when :mongoid
33
+ Mongoid::Document
34
+ else
35
+ raise "Unknown model class for adapter #{adapter}"
36
+ end
37
+ end
38
+
39
+ def shared_seeding
40
+ @shared_seeding ||= false
41
+ end
42
+
22
43
  def configuration
23
44
  @@configuration ||= Sprig::Configuration.new
24
45
  end
@@ -1,10 +1,10 @@
1
1
  module Sprig
2
2
  class Configuration
3
3
 
4
- attr_writer :directory, :logger
4
+ attr_writer :directory, :shared_directory, :logger
5
5
 
6
6
  def directory
7
- Rails.root.join(@directory || default_directory, Rails.env)
7
+ Rails.root.join(@directory || default_directory, seeds_directory)
8
8
  end
9
9
 
10
10
  def logger
@@ -16,5 +16,22 @@ module Sprig
16
16
  def default_directory
17
17
  'db/seeds'
18
18
  end
19
+
20
+ def seeds_directory
21
+ return shared_seeds_directory if Sprig.shared_seeding
22
+ env_seeds_directory
23
+ end
24
+
25
+ def env_seeds_directory
26
+ Rails.env
27
+ end
28
+
29
+ def shared_seeds_directory
30
+ @shared_directory || default_shared_directory
31
+ end
32
+
33
+ def default_shared_directory
34
+ 'shared'
35
+ end
19
36
  end
20
37
  end
@@ -7,7 +7,7 @@ module Sprig
7
7
  case
8
8
  when args.is_a?(Hash)
9
9
  args
10
- when args.is_a?(Class) && args < ActiveRecord::Base
10
+ when args.is_a?(Class) && args < Sprig.adapter_model_class
11
11
  { :class => args }
12
12
  else
13
13
  raise ArgumentError, argument_error_message
@@ -30,8 +30,8 @@ module Sprig
30
30
  private
31
31
 
32
32
  def argument_error_message
33
- 'Sprig::Directive must be instantiated with an '\
34
- 'ActiveRecord subclass or a Hash with :class defined'
33
+ 'Sprig::Directive must be instantiated with a(n) '\
34
+ "#{Sprig.adapter_model_class} class or a Hash with :class defined"
35
35
  end
36
36
  end
37
37
  end
data/lib/sprig/helpers.rb CHANGED
@@ -5,9 +5,13 @@ module Sprig
5
5
  end
6
6
 
7
7
  def sprig(directive_definitions)
8
- hopper = []
9
- DirectiveList.new(directive_definitions).add_seeds_to_hopper(hopper)
10
- Planter.new(hopper).sprig
8
+ Sprig.shared_seeding = false
9
+ plant_records(directive_definitions)
10
+ end
11
+
12
+ def sprig_shared(directive_definitions)
13
+ Sprig.shared_seeding = true
14
+ plant_records(directive_definitions)
11
15
  end
12
16
 
13
17
  def sprig_record(klass, seed_id)
@@ -19,5 +23,13 @@ module Sprig
19
23
  def sprig_file(relative_path)
20
24
  File.new(seed_directory.join('files', relative_path))
21
25
  end
26
+
27
+ private
28
+
29
+ def plant_records(directive_definitions)
30
+ hopper = []
31
+ DirectiveList.new(directive_definitions).add_seeds_to_hopper(hopper)
32
+ Planter.new(hopper).sprig
33
+ end
22
34
  end
23
35
  end
data/lib/sprig/planter.rb CHANGED
@@ -25,7 +25,7 @@ module Sprig
25
25
  end
26
26
 
27
27
  def plant(seed)
28
- notifier.in_progress
28
+ notifier.in_progress(seed)
29
29
  seed.before_save
30
30
 
31
31
  if seed.save_record
@@ -10,6 +10,10 @@ module Sprig
10
10
  @errors = []
11
11
  end
12
12
 
13
+ def in_progress(seed)
14
+ log_debug seed.in_progress_text
15
+ end
16
+
13
17
  def success(seed)
14
18
  log_info seed.success_log_text
15
19
  @success_count += 1
@@ -42,10 +46,6 @@ module Sprig
42
46
  end
43
47
  end
44
48
 
45
- def in_progress
46
- log_debug "Planting those seeds...\r"
47
- end
48
-
49
49
  private
50
50
 
51
51
  def success_summary
@@ -54,7 +54,7 @@ module Sprig
54
54
  end
55
55
 
56
56
  def computed_value_regex
57
- /<%[=]?(.*)%>/
57
+ /(<%=?(.*?)%>)/
58
58
  end
59
59
 
60
60
  def compute_value(value)
@@ -73,9 +73,33 @@ module Sprig
73
73
  end
74
74
  end
75
75
 
76
+ def completely_dynamic_value?(string, matches)
77
+ return false if matches.count > 1
78
+
79
+ test_string = string.clone
80
+
81
+ matches.each do |match|
82
+ test_string = test_string.sub(match[0], "")
83
+ end
84
+
85
+ test_string.strip.length == 0
86
+ end
87
+
76
88
  def compute_string_value(string)
77
- matches = computed_value_regex.match(string)
78
- eval(matches[1])
89
+ matches = string.scan(computed_value_regex)
90
+
91
+ if completely_dynamic_value?(string, matches)
92
+ # If the dynamic portion is the entire value, return the result of the eval
93
+ # (This allows for the return of non-string types.)
94
+ eval(matches.first[1])
95
+ else
96
+ # Otherwise return the dynamic portion within the larger string.
97
+ string.clone.tap do |return_string|
98
+ matches.each do |match|
99
+ return_string.sub!(match[0], eval(match[1]).to_s)
100
+ end
101
+ end
102
+ end
79
103
  end
80
104
 
81
105
  end
@@ -34,12 +34,16 @@ module Sprig
34
34
  SprigRecordStore.instance.save(record.orm_record, sprig_id)
35
35
  end
36
36
 
37
- def success_log_text
38
- "#{klass.name} with sprig_id #{sprig_id} successfully #{success_log_status_text}."
37
+ def in_progress_text
38
+ "Planting #{klass.name} with sprig_id #{sprig_id}"
39
39
  end
40
40
 
41
- def success_log_status_text
42
- record.existing? ? "updated" : "saved"
41
+ def success_log_text
42
+ if record.existing?
43
+ "Updated"
44
+ else
45
+ "Saved"
46
+ end
43
47
  end
44
48
 
45
49
  def error_log_text
@@ -30,7 +30,7 @@ module Sprig
30
30
  def klass=(klass)
31
31
  raise ArgumentError, 'Must provide a Class as first argument' unless klass.is_a? Class
32
32
 
33
- klass.reset_column_information
33
+ klass.reset_column_information if defined?(ActiveRecord) && klass < ActiveRecord::Base
34
34
  @klass = klass
35
35
  end
36
36
 
data/lib/sprig/source.rb CHANGED
@@ -67,7 +67,7 @@ module Sprig
67
67
  end
68
68
 
69
69
  def file
70
- File.new(seed_directory.join(filename))
70
+ File.new(filepath)
71
71
  end
72
72
 
73
73
  private
@@ -78,6 +78,15 @@ module Sprig
78
78
  available_files.detect {|name| name =~ /^#{table_name}\./ } || file_not_found
79
79
  end
80
80
 
81
+ def filepath
82
+ path = seed_directory.join(filename)
83
+ if File.symlink?(path)
84
+ File.readlink(path)
85
+ else
86
+ path
87
+ end
88
+ end
89
+
81
90
  def available_files
82
91
  Dir.entries(seed_directory)
83
92
  end
data/lib/sprig/version.rb CHANGED
@@ -1,3 +1,10 @@
1
1
  module Sprig
2
- VERSION = "0.1.6"
2
+
3
+ #:nocov:
4
+ VERSION = [
5
+ 0, # major
6
+ 3, # minor
7
+ 1 # patch
8
+ ].join('.')
9
+ #:nocov:
3
10
  end