planter 1.0.0 → 1.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b66f9b16f720b193d4dee6e0a23382b22a073982634bccbad2d52092516090eb
4
- data.tar.gz: 5d66d7905379b7b148586b52b85afb2d715501543e88f0d84a88973b734d9f6b
3
+ metadata.gz: b2283785564306f87b6399b8af3e5343930b451e4bd64a10d8ac66acb0a7a7fa
4
+ data.tar.gz: ee9993b9e3d076dd5ecee3bbb61135904b0f1e8467bf11feadf043d89c47b42f
5
5
  SHA512:
6
- metadata.gz: dde579bb6c055ce0c819148d1d818b39bf44ef9e75c692799dd760c7f9a96a0828d959f3204e6741fa55c41a6b9c2d8045f746142c139b5f20f1ea450ba7b259
7
- data.tar.gz: 9f208c04796ae9f80ce6d46b4ec94e56da4fc2c62c36abf3198d806621bf2c7d79d9f52fd2d30ad0ee73c94206e7f0997b953ff93dbc93b83ff8064ee7ab85ed
6
+ metadata.gz: 8fda738209e6d82abff3d7bc8c3db1d29206924f63d95799d61265b228b09d48d2bded51e0997655225f509e2b70c4b2a3666e6d1ff766f4d7f321951ed7136d
7
+ data.tar.gz: 7e080b039a593a04e2f278a74aad865db841c8235d1921f47b2ba28da4be7ccf75ec7eb562d5ea7b5ab12b30ba46093ba7952503e39fd44b22d1298c511604da
data/README.md CHANGED
@@ -58,8 +58,8 @@ Planter.configure do |config|
58
58
  # config.seeders_directory, which can be changed below. When a new
59
59
  # seeder is generated, it will be appended to the bottom of this
60
60
  # list. If the order is incorrect, you'll need to adjust it.
61
- # Just be sure to keep the ending bracket on its own line, or the
62
- # generator won't know where to put new elements.
61
+ # The generator can append to either multiline or inline %i[...]
62
+ # arrays.
63
63
  config.seeders = %i[
64
64
  ]
65
65
 
@@ -75,6 +75,11 @@ Planter.configure do |config|
75
75
  # When true, don't print output when seeding.
76
76
  config.quiet = false
77
77
 
78
+ ##
79
+ # When false, don't print progress bars while seeding.
80
+ # This is ignored when config.quiet is true.
81
+ config.progress_bar = true
82
+
78
83
  ##
79
84
  # The default trim mode for ERB. Valid modes are:
80
85
  # '%' enables Ruby code processing for lines beginning with %
@@ -136,8 +141,8 @@ things to note.
136
141
 
137
142
  - The seeder will always be appended at the end of the array. If this is not the
138
143
  correct order, you'll need to adjust the array manually.
139
- - When adjusting the array, always keep the closing bracket on its own line, or
140
- the generator won't know where to put the new seeders.
144
+ - The generator can append to either multiline or inline `%i[...]` seeders
145
+ arrays.
141
146
 
142
147
  You can also tell the generator which seeding style to use.
143
148
 
@@ -26,8 +26,8 @@ module Planter
26
26
  # config.seeders_directory, which can be changed below. When a new
27
27
  # seeder is generated, it will be appended to the bottom of this
28
28
  # list. If the order is incorrect, you'll need to adjust it.
29
- # Just be sure to keep the ending bracket on its own line, or the
30
- # generator won't know where to put new elements.
29
+ # The generator can append to either multiline or inline %i[...]
30
+ # arrays.
31
31
  config.seeders = %i[
32
32
  ]
33
33
 
@@ -43,6 +43,11 @@ module Planter
43
43
  # When true, don't print output when seeding.
44
44
  config.quiet = false
45
45
 
46
+ ##
47
+ # When false, don't print progress bars while seeding.
48
+ # This is ignored when config.quiet is true.
49
+ config.progress_bar = true
50
+
46
51
  ##
47
52
  # The default trim mode for ERB. Valid modes are:
48
53
  # '%' enables Ruby code processing for lines beginning with %
@@ -50,9 +50,7 @@ module Planter
50
50
 
51
51
  create_csv(seeder) if selected_seeding_method == :csv
52
52
 
53
- inject_into_file "config/initializers/planter.rb",
54
- " #{seeder}\n",
55
- before: /^\s*\]\s*$/
53
+ register_seeder(seeder)
56
54
  end
57
55
 
58
56
  def seeder_contents
@@ -94,6 +92,110 @@ module Planter
94
92
  end.join
95
93
  end
96
94
 
95
+ def register_seeder(seeder)
96
+ contents = ::File.read(initializer_full_path)
97
+ ::File.write(initializer_full_path, add_seeder_to_initializer(contents, seeder))
98
+ end
99
+
100
+ def add_seeder_to_initializer(contents, seeder)
101
+ assignment = contents.match(seeders_assignment_pattern)
102
+ unless assignment
103
+ raise Thor::Error, "Could not find config.seeders = %i[...] in #{initializer_path}"
104
+ end
105
+
106
+ opening_bracket_index = assignment.end(0) - 1
107
+ closing_bracket_index = closing_bracket_index_for(contents, opening_bracket_index)
108
+ unless closing_bracket_index
109
+ raise Thor::Error,
110
+ "Could not find the closing bracket for config.seeders in #{initializer_path}"
111
+ end
112
+
113
+ insert_seeder(contents, seeder, assignment[1], opening_bracket_index, closing_bracket_index)
114
+ end
115
+
116
+ def insert_seeder(
117
+ contents,
118
+ seeder,
119
+ assignment_indent,
120
+ opening_bracket_index,
121
+ closing_bracket_index
122
+ )
123
+ body = contents[(opening_bracket_index + 1)...closing_bracket_index]
124
+ updated = contents.dup
125
+
126
+ if body.include?("\n")
127
+ insert_multiline_seeder(
128
+ updated,
129
+ contents,
130
+ seeder,
131
+ assignment_indent,
132
+ body,
133
+ closing_bracket_index
134
+ )
135
+ elsif body.strip.empty?
136
+ updated.insert(closing_bracket_index, seeder)
137
+ else
138
+ updated.insert(closing_bracket_index, " #{seeder}")
139
+ end
140
+
141
+ updated
142
+ end
143
+
144
+ def insert_multiline_seeder(
145
+ updated,
146
+ contents,
147
+ seeder,
148
+ assignment_indent,
149
+ body,
150
+ closing_bracket_index
151
+ )
152
+ closing_line_start = contents.rindex("\n", closing_bracket_index) + 1
153
+ closing_line_prefix = contents[closing_line_start...closing_bracket_index]
154
+
155
+ if closing_line_prefix.match?(/\A[ \t]*\z/)
156
+ updated.insert(closing_line_start, "#{seeder_indent(body, assignment_indent)}#{seeder}\n")
157
+ else
158
+ updated.insert(closing_bracket_index, " #{seeder}")
159
+ end
160
+ end
161
+
162
+ def seeder_indent(body, assignment_indent)
163
+ item_line = body.lines.find { |line| line.match?(/\S/) }
164
+ indent = item_line&.match(/\A[ \t]*/).to_s
165
+ indent.empty? ? "#{assignment_indent} " : indent
166
+ end
167
+
168
+ def closing_bracket_index_for(contents, opening_bracket_index)
169
+ depth = 1
170
+ index = opening_bracket_index + 1
171
+
172
+ while index < contents.length
173
+ if contents[index] == "\\"
174
+ index += 2
175
+ next
176
+ elsif contents[index] == "["
177
+ depth += 1
178
+ elsif contents[index] == "]"
179
+ depth -= 1
180
+ return index if depth.zero?
181
+ end
182
+
183
+ index += 1
184
+ end
185
+ end
186
+
187
+ def seeders_assignment_pattern
188
+ /^([ \t]*)config\.seeders\s*=\s*%i\[/
189
+ end
190
+
191
+ def initializer_path
192
+ "config/initializers/planter.rb"
193
+ end
194
+
195
+ def initializer_full_path
196
+ ::File.join(destination_root, initializer_path)
197
+ end
198
+
97
199
  def selected_seeding_method
98
200
  return unless options["seeding_method"]
99
201
 
@@ -42,6 +42,14 @@ module Planter
42
42
  # @return [Boolean]
43
43
  attr_accessor :quiet
44
44
 
45
+ ##
46
+ # When false, don't print progress bars while seeding.
47
+ #
48
+ # @param [Boolean] progress_bar
49
+ #
50
+ # @return [Boolean]
51
+ attr_accessor :progress_bar
52
+
45
53
  ##
46
54
  # The default trim mode for ERB. Must be "%", "<>", ">", or "-".
47
55
  # For more information, see documentation for +ERB::new+.
@@ -72,6 +80,7 @@ module Planter
72
80
  # Create a new instance of the config.
73
81
  def initialize
74
82
  @quiet = false
83
+ @progress_bar = true
75
84
  @seeders_directory = ::File.join("db", "seeds")
76
85
  @csv_files_directory = ::File.join("db", "seed_files")
77
86
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby-progressbar"
4
+
5
+ module Planter
6
+ ##
7
+ # Builds progress bars for seed runs.
8
+ class ProgressBar
9
+ FORMAT = "%t |%B| %p%% %c/%C"
10
+
11
+ class NullProgressBar
12
+ def increment
13
+ end
14
+ end
15
+
16
+ def self.create(title:, total:, output: $stdout)
17
+ return NullProgressBar.new unless enabled?(total)
18
+
19
+ ::ProgressBar.create(
20
+ title: title,
21
+ total: total,
22
+ output: output,
23
+ format: FORMAT
24
+ )
25
+ end
26
+
27
+ def self.enabled?(total)
28
+ total.positive? && Planter.config.progress_bar && !Planter.config.quiet
29
+ end
30
+ private_class_method :enabled?
31
+ end
32
+ end
@@ -261,17 +261,35 @@ module Planter
261
261
  ##
262
262
  # Creates records from the +data+ attribute.
263
263
  def create_records
264
- context.number_of_records.times do
265
- data.each { |record| create_record(record) }
264
+ records = data
265
+ progress_bar = progress_bar(total: context.number_of_records * records.size)
266
+
267
+ context.number_of_records.times do |index|
268
+ records = data if index.positive?
269
+ records.each do |record|
270
+ create_record(record)
271
+ progress_bar.increment
272
+ end
266
273
  end
267
274
  end
268
275
 
269
276
  ##
270
277
  # Create records from the +data+ attribute for each record in the +parent+.
271
278
  def create_records_from_parent
272
- adapter.parent_ids(context: context).each do |parent_id|
273
- context.number_of_records.times do
274
- data.each { |record| create_record(record, parent_id: parent_id) }
279
+ parent_ids = adapter.parent_ids(context: context)
280
+ return if parent_ids.empty?
281
+
282
+ records = data
283
+ total = parent_ids.size * context.number_of_records * records.size
284
+ progress_bar = progress_bar(total: total)
285
+
286
+ parent_ids.each_with_index do |parent_id, parent_index|
287
+ context.number_of_records.times do |number_index|
288
+ records = data if parent_index.positive? || number_index.positive?
289
+ records.each do |record|
290
+ create_record(record, parent_id: parent_id)
291
+ progress_bar.increment
292
+ end
275
293
  end
276
294
  end
277
295
  end
@@ -327,5 +345,9 @@ module Planter
327
345
  def adapter
328
346
  Planter.config.adapter
329
347
  end
348
+
349
+ def progress_bar(total:)
350
+ Planter::ProgressBar.create(title: context.table_name, total: total)
351
+ end
330
352
  end
331
353
  end
@@ -21,7 +21,7 @@ module Planter
21
21
  # Patch version.
22
22
  #
23
23
  # @return [Integer]
24
- PATCH = 0
24
+ PATCH = 2
25
25
 
26
26
  module_function
27
27
 
data/lib/planter.rb CHANGED
@@ -7,6 +7,7 @@ require "planter/railtie"
7
7
  require "planter/config"
8
8
  require "planter/seed_context"
9
9
  require "planter/csv_data_source"
10
+ require "planter/progress_bar"
10
11
  require "planter/record_attributes"
11
12
  require "planter/seeder"
12
13
  require "planter/validator"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: planter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Gray
@@ -43,6 +43,20 @@ dependencies:
43
43
  - - "<"
44
44
  - !ruby/object:Gem::Version
45
45
  version: '9.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: ruby-progressbar
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '1.13'
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.13'
46
60
  - !ruby/object:Gem::Dependency
47
61
  name: parallel
48
62
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +117,7 @@ files:
103
117
  - lib/planter/adapters/active_record.rb
104
118
  - lib/planter/config.rb
105
119
  - lib/planter/csv_data_source.rb
120
+ - lib/planter/progress_bar.rb
106
121
  - lib/planter/railtie.rb
107
122
  - lib/planter/record_attributes.rb
108
123
  - lib/planter/seed_context.rb