bullet_train-super_scaffolding 1.0.34 → 1.0.35

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e89abdab9630d8af6498af03edec21ce70c456c1579d5c35bf7e16ed3a0383c3
4
- data.tar.gz: 57f3be888b988cc3d0ff747776cb319ec1bc3399f9e55209d94f132c2ef3d6f1
3
+ metadata.gz: 329a1d276e3bc2b2a89c230d35b8ea6613abc957d34de2319455458e88658ca2
4
+ data.tar.gz: 27994643a5a47719703a204d849732a9c67382fab553a4decad9984b2b5f08d0
5
5
  SHA512:
6
- metadata.gz: cf98aac64c6ee99b4b9778b8d371a770c26d8a1d89925e8e3144aa5b6eee2180890cff7732e700b78c764ff9871a4dc1543db7b3e69e25cc763eb9a16cb34a98
7
- data.tar.gz: d7d0935c5280a7b482e260fe857fba7b7a1dd99076505978ff7d47505921d61abfb041fed3737295f96fb1ffcddc1d368703acd67e2799e01538ac7798887d65
6
+ metadata.gz: 4956a720055fb48e9d26dba793a131b12291cc338bfd025743c34d78fd0f6d6c1f36a702f98ce46c49d10930448b6c87faa8c75d3a8b021d47552c95f2aecbf2
7
+ data.tar.gz: 783996a02a3482d95714a3d66c0b3119b54b3dd0d7cbbcb58b8f44af403be5c4b2f6524c3a8df7ccb5034f1f3a82ba45f8673f49521b206db9164164d7410748
@@ -16,6 +16,7 @@ class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingsEndpoint < Api::V1
16
16
  optional :date_field_value, type: Date, allow_blank: true, desc: Api.heading(:date_field_value)
17
17
  optional :date_and_time_field_value, type: DateTime, allow_blank: true, desc: Api.heading(:date_and_time_field_value)
18
18
  optional :email_field_value, type: String, allow_blank: true, desc: Api.heading(:email_field_value)
19
+ optional :file_field_value, type: String, allow_blank: true, desc: Api.heading(:file_field_value)
19
20
  optional :password_field_value, type: String, allow_blank: true, desc: Api.heading(:password_field_value)
20
21
  optional :phone_field_value, type: String, allow_blank: true, desc: Api.heading(:phone_field_value)
21
22
  optional :option_value, type: String, allow_blank: true, desc: Api.heading(:option_value)
@@ -1,5 +1,6 @@
1
1
  class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingSerializer < Api::V1::ApplicationSerializer
2
2
  set_type "scaffolding/completely_concrete/tangible_thing"
3
+ singleton_class.include Rails.application.routes.url_helpers
3
4
 
4
5
  attributes :id,
5
6
  :absolutely_abstract_creative_concept_id,
@@ -25,5 +26,12 @@ class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingSerializer < Api::V
25
26
  :created_at,
26
27
  :updated_at
27
28
 
29
+ # 🚅 skip this section when scaffolding.
30
+ attribute :file_field_value do |object|
31
+ rails_blob_path(object.file_field_value, disposition: "attachment", only_path: true) if object.file_field_value.attached?
32
+ end
33
+ # 🚅 stop any skipping we're doing now.
34
+ # 🚅 super scaffolding will insert file-related logic above this line.
35
+
28
36
  belongs_to :absolutely_abstract_creative_concept, serializer: Api::V1::Scaffolding::AbsolutelyAbstract::CreativeConceptSerializer
29
37
  end
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module SuperScaffolding
3
- VERSION = "1.0.34"
3
+ VERSION = "1.0.35"
4
4
  end
5
5
  end
@@ -107,6 +107,7 @@ class Scaffolding::BlockManipulator
107
107
  insert_line(block_content[1], block_end + 1)
108
108
  end
109
109
 
110
+ # TODO: Delete this because it only really needs to be in the FileManipulator
110
111
  def write
111
112
  File.write(@filepath, @lines.join)
112
113
  end
@@ -0,0 +1,71 @@
1
+ require "scaffolding/block_manipulator"
2
+
3
+ # TODO: If we move this and the BlockManipulator into their own gems,
4
+ # we can probably call these methods with something shorter without `Scaffolding::`.
5
+ module Scaffolding::FileManipulator
6
+ # TODO: The block_manipulator shouldn't be an instance variable.
7
+ def self.find(lines, needle, within = nil, block_manipulator)
8
+ lines_within(lines, within, block_manipulator).each_with_index do |line, line_number|
9
+ return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
10
+ end
11
+ nil
12
+ end
13
+
14
+ # TODO: The block_manipulator shouldn't be an instance variable.
15
+ def self.lines_within(lines, within, block_manipulator)
16
+ return lines unless within
17
+ lines[(within + 1)..(block_manipulator.find_block_end(starting_from: within, lines: lines) + 1)]
18
+ end
19
+
20
+ def self.replace_line_in_file(file, content, in_place_of)
21
+ target_file_content = File.read(file)
22
+
23
+ if target_file_content.include?(content)
24
+ puts "No need to update '#{file}'. It already has '#{content}'."
25
+ else
26
+ puts "Updating '#{file}'."
27
+ target_file_content.gsub!(in_place_of, content)
28
+ File.write(file, target_file_content)
29
+ end
30
+ end
31
+
32
+ # Pass in an array where this content should be inserted within the yml file.
33
+ # For example, to add content to admin.models pass in [:admin, :models]
34
+ def self.add_line_to_yml_file(file, content, location_array)
35
+ # First check that the given location array actually exists in the yml file:
36
+ yml = YAML.safe_load(File.read(file))
37
+ location_array.map!(&:to_s)
38
+
39
+ # TODO: Raise an error if we're returning nil.
40
+ return nil if yml.dig(*location_array).nil?
41
+
42
+ content += "\n" unless content[-1] == "\n"
43
+ # Find the location in the file where the location_array is
44
+ lines = File.readlines(file)
45
+ current_needle = location_array.shift.to_s
46
+ current_space = ""
47
+ insert_after = 1
48
+ lines.each_with_index do |line, index|
49
+ break if current_needle.nil?
50
+ if line.strip == current_needle + ":"
51
+ current_needle = location_array.shift.to_s
52
+ insert_after = index
53
+ current_space = line.match(/\s+/).to_s
54
+ end
55
+ end
56
+ new_lines = []
57
+ current_space += " "
58
+ lines.each_with_index do |line, index|
59
+ new_lines << line
60
+ new_lines << current_space + content if index == insert_after
61
+ end
62
+ File.write(file, new_lines.join)
63
+ end
64
+
65
+ def self.write(file_name, lines)
66
+ puts "Updating '#{file_name}'."
67
+ File.open(file_name, "w+") do |file|
68
+ file.puts(lines.join.strip + "\n")
69
+ end
70
+ end
71
+ end
@@ -82,6 +82,7 @@ class Scaffolding::RoutesFileManipulator
82
82
  results
83
83
  end
84
84
 
85
+ # TODO: Remove this and use the BlockManipulator
85
86
  def insert_before(new_lines, line_number, options = {})
86
87
  options[:indent] ||= false
87
88
  before = lines[0..(line_number - 1)]
@@ -90,6 +91,7 @@ class Scaffolding::RoutesFileManipulator
90
91
  self.lines = before + (options[:prepend_newline] ? ["\n"] : []) + new_lines + after
91
92
  end
92
93
 
94
+ # TODO: Remove this and use the BlockManipulator
93
95
  def insert_after(new_lines, line_number, options = {})
94
96
  options[:indent] ||= false
95
97
  before = lines[0..line_number]
@@ -164,21 +166,13 @@ class Scaffolding::RoutesFileManipulator
164
166
  namespace_block_start.present? ? {namespace => namespace_block_start} : {}
165
167
  end
166
168
 
167
- def find(needle, within = nil)
168
- lines_within(within).each_with_index do |line, line_number|
169
- return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
170
- end
171
-
172
- nil
173
- end
174
-
175
169
  def find_in_namespace(needle, namespaces, within = nil, ignore = nil)
176
170
  if namespaces.any?
177
171
  namespace_lines = find_namespaces(namespaces, within)
178
172
  within = namespace_lines[namespaces.last]
179
173
  end
180
174
 
181
- lines_within(within).each_with_index do |line, line_number|
175
+ Scaffolding::FileManipulator.lines_within(lines, within, block_manipulator).each_with_index do |line, line_number|
182
176
  # + 2 because line_number starts from 0, and within starts one line after
183
177
  actual_line_number = (within + line_number + 2)
184
178
 
@@ -232,7 +226,7 @@ class Scaffolding::RoutesFileManipulator
232
226
  # However, will not find namespace blocks inside namespace blocks.
233
227
  def top_level_namespace_block_lines(within)
234
228
  local_namespace_blocks = []
235
- lines_within(within).each do |line|
229
+ Scaffolding::FileManipulator.lines_within(lines, within, block_manipulator).each do |line|
236
230
  # i.e. - Retrieve "foo" from "namespace :foo do"
237
231
  match_data = line.match(/(\s*namespace\s:)(.*)(\sdo$)/)
238
232
 
@@ -286,11 +280,6 @@ class Scaffolding::RoutesFileManipulator
286
280
  find_or_convert_resource_block(parts.last, options)
287
281
  end
288
282
 
289
- def lines_within(within)
290
- return lines unless within
291
- lines[(within + 1)..(block_manipulator.find_block_end(starting_from: within, lines: lines) + 1)]
292
- end
293
-
294
283
  def find_or_convert_resource_block(parent_resource, options = {})
295
284
  unless find_resource_block([parent_resource], options)
296
285
  if (resource_line_number = find_resource([parent_resource], options))
@@ -310,6 +299,7 @@ class Scaffolding::RoutesFileManipulator
310
299
  within
311
300
  end
312
301
 
302
+ # TODO: Remove this and use the BlockManipulator
313
303
  def insert(lines_to_add, within)
314
304
  insertion_line = block_manipulator.find_block_end(starting_from: within, lines: lines)
315
305
  result_line = insertion_line
@@ -343,7 +333,7 @@ class Scaffolding::RoutesFileManipulator
343
333
  # add the new resource within that namespace.
344
334
  line = "scope module: '#{parent_resource}' do"
345
335
  # TODO you haven't tested this yet.
346
- unless (scope_within = find(/#{line}/, parent_within))
336
+ unless (scope_within = Scaffolding::FileManipulator.find(lines, /#{line}/, parent_within, block_manipulator))
347
337
  scope_within = insert([line, "end"], parent_within)
348
338
  end
349
339
 
@@ -399,11 +389,4 @@ class Scaffolding::RoutesFileManipulator
399
389
  return if concerns.empty?
400
390
  "concerns: #{concerns}"
401
391
  end
402
-
403
- def write
404
- puts "Updating '#{@filename}'."
405
- File.open(@filename, "w+") do |file|
406
- file.puts(lines.join.strip + "\n")
407
- end
408
- end
409
392
  end
@@ -1,5 +1,6 @@
1
1
  require "indefinite_article"
2
2
  require "yaml"
3
+ require "scaffolding/file_manipulator"
3
4
  require "scaffolding/class_names_transformer"
4
5
 
5
6
  class Scaffolding::Transformer
@@ -20,6 +21,7 @@ class Scaffolding::Transformer
20
21
  RUBY_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will insert new fields above this line."
21
22
  RUBY_ADDITIONAL_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will also insert new fields above this line."
22
23
  RUBY_EVEN_MORE_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will additionally insert new fields above this line."
24
+ RUBY_FILES_HOOK = "# 🚅 super scaffolding will insert file-related logic above this line."
23
25
  ENDPOINTS_HOOK = "# 🚅 super scaffolding will mount new endpoints above this line."
24
26
  ERB_NEW_FIELDS_HOOK = "<%#{RUBY_NEW_FIELDS_HOOK} %>"
25
27
  CONCERNS_HOOK = "# 🚅 add concerns above."
@@ -235,36 +237,6 @@ class Scaffolding::Transformer
235
237
  end
236
238
  end
237
239
 
238
- # pass in an array where this content should be inserted within the yml file. For example, to add content
239
- # to admin.models pass in [:admin, :models]
240
- def add_line_to_yml_file(file, content, location_array)
241
- # First check that the given location array actually exists in the yml file:
242
- yml = YAML.safe_load(File.read(file))
243
- location_array.map!(&:to_s)
244
- return nil if yml.dig(*location_array).nil? # Should we raise an error?
245
- content += "\n" unless content[-1] == "\n"
246
- # Find the location in the file where the location_array is
247
- lines = File.readlines(file)
248
- current_needle = location_array.shift.to_s
249
- current_space = ""
250
- insert_after = 1
251
- lines.each_with_index do |line, index|
252
- break if current_needle.nil?
253
- if line.strip == current_needle + ":"
254
- current_needle = location_array.shift.to_s
255
- insert_after = index
256
- current_space = line.match(/\s+/).to_s
257
- end
258
- end
259
- new_lines = []
260
- current_space += " "
261
- lines.each_with_index do |line, index|
262
- new_lines << line
263
- new_lines << current_space + content if index == insert_after
264
- end
265
- File.write(file, new_lines.join)
266
- end
267
-
268
240
  def add_line_to_file(file, content, hook, options = {})
269
241
  increase_indent = options[:increase_indent]
270
242
  add_before = options[:add_before]
@@ -346,23 +318,11 @@ class Scaffolding::Transformer
346
318
  add_line_to_file(file, content, hook, options)
347
319
  end
348
320
 
349
- def replace_line_in_file(file, content, in_place_of)
350
- target_file_content = File.read(file)
351
-
352
- if target_file_content.include?(content)
353
- puts "No need to update '#{file}'. It already has '#{content}'."
354
- else
355
- puts "Updating '#{file}'."
356
- target_file_content.gsub!(in_place_of, content)
357
- File.write(file, target_file_content)
358
- end
359
- end
360
-
361
321
  def scaffold_replace_line_in_file(file, content, in_place_of)
362
322
  file = transform_string(file)
363
323
  # we specifically don't transform the content, we assume a builder function created this content.
364
324
  in_place_of = transform_string(in_place_of)
365
- replace_line_in_file(file, content, in_place_of)
325
+ Scaffolding::FileManipulator.replace_line_in_file(file, content, in_place_of)
366
326
  end
367
327
 
368
328
  # if class_name isn't specified, we use `child`.
@@ -451,8 +411,8 @@ class Scaffolding::Transformer
451
411
  model_names = class_names || [child]
452
412
  role_file = "./config/models/roles.yml"
453
413
  model_names.each do |model_name|
454
- add_line_to_yml_file(role_file, "#{model_name}: read", [:default, :models])
455
- add_line_to_yml_file(role_file, "#{model_name}: manage", [:admin, :models])
414
+ Scaffolding::FileManipulator.add_line_to_yml_file(role_file, "#{model_name}: read", [:default, :models])
415
+ Scaffolding::FileManipulator.add_line_to_yml_file(role_file, "#{model_name}: manage", [:admin, :models])
456
416
  end
457
417
  end
458
418
 
@@ -480,7 +440,7 @@ class Scaffolding::Transformer
480
440
  current_parent = working_parents.pop
481
441
  end
482
442
 
483
- setup_lines << current_transformer.transform_string("@tangible_thing = create(:scaffolding_completely_concrete_tangible_thing, #{previous_assignment})")
443
+ setup_lines << current_transformer.transform_string("@tangible_thing = build(:scaffolding_completely_concrete_tangible_thing, #{previous_assignment})")
484
444
 
485
445
  setup_lines
486
446
  end
@@ -615,7 +575,9 @@ class Scaffolding::Transformer
615
575
  is_id = name.match?(/_id$/)
616
576
  is_ids = name.match?(/_ids$/)
617
577
  # if this is the first attribute of a newly scaffolded model, that field is required.
618
- is_required = attribute_options[:required] || (scaffolding_options[:type] == :crud && index == 0)
578
+ unless type == "file_field"
579
+ is_required = attribute_options[:required] || (scaffolding_options[:type] == :crud && index == 0)
580
+ end
619
581
  is_vanilla = attribute_options&.key?(:vanilla)
620
582
  is_belongs_to = is_id && !is_vanilla
621
583
  is_has_many = is_ids && !is_vanilla
@@ -653,6 +615,8 @@ class Scaffolding::Transformer
653
615
  "date_and_time"
654
616
  when "email_field"
655
617
  "email"
618
+ when "emoji_field"
619
+ "text"
656
620
  when "color_picker"
657
621
  "code"
658
622
  when "text_field"
@@ -765,13 +729,14 @@ class Scaffolding::Transformer
765
729
  # field on the form.
766
730
  field_attributes = {method: ":#{name}"}
767
731
  field_options = {}
732
+ options = {}
768
733
 
769
734
  if scaffolding_options[:type] == :crud && index == 0
770
735
  field_options[:autofocus] = "true"
771
736
  end
772
737
 
773
738
  if is_id && type == "super_select"
774
- field_options[:include_blank] = "t('.fields.#{name}.placeholder')"
739
+ options[:include_blank] = "t('.fields.#{name}.placeholder')"
775
740
  # add_additional_step :yellow, transform_string("We've added a reference to a `placeholder` to the form for the select or super_select field, but unfortunately earlier versions of the scaffolded locales Yaml don't include a reference to `fields: *fields` under `form`. Please add it, otherwise your form won't be able to locate the appropriate placeholder label.")
776
741
  end
777
742
 
@@ -796,12 +761,19 @@ class Scaffolding::Transformer
796
761
  end
797
762
 
798
763
  # https://stackoverflow.com/questions/21582464/is-there-a-ruby-hashto-s-equivalent-for-the-new-hash-syntax
799
- if field_options.any?
764
+ if field_options.any? || options.any?
800
765
  field_options_key = if ["buttons", "super_select", "options"].include?(type)
766
+ if options.any?
767
+ field_attributes[:options] = "{" + field_options.map { |key, value| "#{key}: #{value}" }.join(", ") + "}"
768
+ end
769
+
801
770
  :html_options
802
771
  else
772
+ field_options.merge!(options)
773
+
803
774
  :options
804
775
  end
776
+
805
777
  field_attributes[field_options_key] = "{" + field_options.map { |key, value| "#{key}: #{value}" }.join(", ") + "}"
806
778
  end
807
779
 
@@ -1038,7 +1010,7 @@ class Scaffolding::Transformer
1038
1010
  # TODO The serializers can't handle these `has_rich_text` attributes.
1039
1011
  unless type == "trix_editor"
1040
1012
  scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.json.jbuilder", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true, suppress_could_not_find: true)
1041
- scaffold_add_line_to_file("./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true)
1013
+ scaffold_add_line_to_file("./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true) unless type == "file_field"
1042
1014
 
1043
1015
  assertion = case type
1044
1016
  when "date_field"
@@ -1047,13 +1019,31 @@ class Scaffolding::Transformer
1047
1019
  "assert_equal DateTime.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
1048
1020
  when "file_field"
1049
1021
  # TODO: If we want to use Cloudinary to handle our files, we should make sure we're getting a URL.
1050
- "assert_equal tangible_thing_data['#{name}']['record']['id'], tangible_thing.#{name}.record.id"
1022
+ "assert tangible_thing_data['#{name}'].match?('foo.txt') unless response.status == 201"
1051
1023
  else
1052
1024
  "assert_equal tangible_thing_data['#{name}'], tangible_thing.#{name}"
1053
1025
  end
1054
1026
  scaffold_add_line_to_file("./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_endpoint_test.rb", assertion, RUBY_NEW_FIELDS_HOOK, prepend: true)
1055
1027
  end
1056
1028
 
1029
+ # File fields are handled in a specific way when using the jsonapi-serializer.
1030
+ if type == "file_field"
1031
+ file_name = "./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb"
1032
+ content = <<~RUBY
1033
+ attribute :#{name} do |object|
1034
+ rails_blob_path(object.#{name}, disposition: "attachment", only_path: true) if object.#{name}.attached?
1035
+ end
1036
+
1037
+ RUBY
1038
+ hook = RUBY_FILES_HOOK
1039
+ scaffold_add_line_to_file(file_name, content, hook, prepend: true)
1040
+
1041
+ # We also want to make sure we attach the dummy file in the endpoint test on setup
1042
+ file_name = "./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_endpoint_test.rb"
1043
+ content = "@#{child.underscore}.#{name} = Rack::Test::UploadedFile.new(\"test/support/foo.txt\")"
1044
+ scaffold_add_line_to_file(file_name, content, hook, prepend: true)
1045
+ end
1046
+
1057
1047
  # scaffold_add_line_to_file("./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_controller_test.rb", "assert_equal tangible_thing_attributes['#{name.gsub('_', '-')}'], tangible_thing.#{name}", RUBY_NEW_FIELDS_HOOK, prepend: true)
1058
1048
 
1059
1049
  if attribute_assignment
@@ -1295,15 +1285,6 @@ class Scaffolding::Transformer
1295
1285
 
1296
1286
  add_has_many_association
1297
1287
 
1298
- # Adds file attachment to factory
1299
- attributes.each do |attribute|
1300
- attribute_name, partial_type = attribute.split(":")
1301
- if partial_type == "file_field"
1302
- content = "#{attribute_name} { Rack::Test::UploadedFile.new(\"test/support/foo.txt\") }"
1303
- scaffold_replace_line_in_file("./test/factories/scaffolding/completely_concrete/tangible_things.rb", content, "#{attribute_name} { nil }")
1304
- end
1305
- end
1306
-
1307
1288
  if class_names_transformer.belongs_to_needs_class_definition?
1308
1289
  scaffold_replace_line_in_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", transform_string("belongs_to :absolutely_abstract_creative_concept, class_name: \"Scaffolding::AbsolutelyAbstract::CreativeConcept\"\n"), transform_string("belongs_to :absolutely_abstract_creative_concept\n"))
1309
1290
  end
@@ -1405,7 +1386,7 @@ class Scaffolding::Transformer
1405
1386
  add_additional_step :yellow, "We weren't able to automatically add your `#{routes_namespace}` routes for you. In theory this should be very rare, so if you could reach out on Slack, you could probably provide context that will help us fix whatever the problem was. In the meantime, to add the routes manually, we've got a guide at https://blog.bullettrain.co/nested-namespaced-rails-routing-examples/ ."
1406
1387
  end
1407
1388
 
1408
- routes_manipulator.write
1389
+ Scaffolding::FileManipulator.write("config/routes.rb", routes_manipulator.lines)
1409
1390
  end
1410
1391
 
1411
1392
  unless cli_options["skip-parent"]
@@ -1416,13 +1397,18 @@ class Scaffolding::Transformer
1416
1397
  icon_name = cli_options["sidebar"]
1417
1398
  else
1418
1399
  puts ""
1419
- puts "Hey, models that are scoped directly off of a Team (or nothing) are eligible to be added to the sidebar. Do you want to add this resource to the sidebar menu? (y/N)"
1400
+ puts "Hey, models that are scoped directly off of a Team (or nothing) are eligible to be added to the sidebar."
1401
+ puts "Do you want to add this resource to the sidebar menu? (y/N)"
1420
1402
  response = $stdin.gets.chomp
1421
1403
  if response.downcase[0] == "y"
1422
1404
  puts ""
1423
- puts "OK, great! Let's do this! By default these menu items appear with a puzzle piece, but after you hit enter I'll open two different pages where you can view other icon options. When you find one you like, hover your mouse over it and then come back here and and enter the name of the icon you want to use. (Or hit enter to skip this step.)"
1405
+ puts "OK, great! Let's do this! By default these menu items appear as a #{font_awesome? ? "puzzle piece" : "gift icon"},"
1406
+ puts "but after you hit enter I'll open #{font_awesome? ? "two different pages" : "a page"} where you can view other icon options."
1407
+ puts "When you find one you like, hover your mouse over it and then come back here and"
1408
+ puts "enter the name of the icon you want to use."
1409
+ puts "(Or hit enter when choosing to skip this step.)"
1424
1410
  $stdin.gets.chomp
1425
- if `which open`.present?
1411
+ if (TerminalCommands.macosx? && `which open`.present?) || TerminalCommands.linux?
1426
1412
  TerminalCommands.open_file_or_link("https://themify.me/themify-icons")
1427
1413
  if font_awesome?
1428
1414
  TerminalCommands.open_file_or_link("https://fontawesome.com/icons?d=gallery&s=light")
@@ -1437,8 +1423,18 @@ class Scaffolding::Transformer
1437
1423
  puts ""
1438
1424
  end
1439
1425
  puts ""
1440
- puts "Did you find an icon you wanted to use? Enter the full CSS class here (e.g. 'ti ti-world'#{" or 'fal fa-puzzle-piece'" if font_awesome?}) or hit enter to just use the puzzle piece:"
1441
- icon_name = $stdin.gets.chomp
1426
+
1427
+ loop do
1428
+ puts "Did you find an icon you wanted to use?"
1429
+ puts "Enter the full CSS class here (e.g. 'ti ti-world'#{" or 'fal fa-puzzle-piece'" if font_awesome?}) or hit enter to just use the #{font_awesome? ? "puzzle piece" : "gift icon"}:"
1430
+ icon_name = $stdin.gets.chomp
1431
+ unless icon_name.match?(/ti\s.*/) || icon_name.match?(/fal\s.*/) || icon_name.strip.empty?
1432
+ puts ""
1433
+ puts "Please enter the full CSS class or hit enter."
1434
+ next
1435
+ end
1436
+ break
1437
+ end
1442
1438
  puts ""
1443
1439
  unless icon_name.length > 0 || icon_name.downcase == "y"
1444
1440
  icon_name = "fal fa-puzzle-piece ti ti-gift"
data/lib/scaffolding.rb CHANGED
@@ -8,6 +8,7 @@ module Scaffolding
8
8
  "date_and_time_field",
9
9
  "date_field",
10
10
  "email_field",
11
+ "emoji_field",
11
12
  "file_field",
12
13
  "options",
13
14
  "password_field",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-super_scaffolding
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.34
4
+ version: 1.0.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-20 00:00:00.000000000 Z
11
+ date: 2022-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -166,6 +166,7 @@ files:
166
166
  - lib/scaffolding.rb
167
167
  - lib/scaffolding/block_manipulator.rb
168
168
  - lib/scaffolding/class_names_transformer.rb
169
+ - lib/scaffolding/file_manipulator.rb
169
170
  - lib/scaffolding/oauth_providers.rb
170
171
  - lib/scaffolding/routes_file_manipulator.rb
171
172
  - lib/scaffolding/script.rb