bullet_train-super_scaffolding 1.0.28 → 1.0.29
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 +4 -4
- data/lib/bullet_train/super_scaffolding/version.rb +1 -1
- data/lib/scaffolding/block_manipulator.rb +4 -0
- data/lib/scaffolding/routes_file_manipulator.rb +66 -14
- data/lib/scaffolding/script.rb +6 -0
- data/lib/scaffolding/transformer.rb +23 -3
- data/lib/scaffolding.rb +19 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05b68451045068aa2ec97bb4198826333c702d2af995005b9cf0090e58254ed4
|
4
|
+
data.tar.gz: 1ea761bfa6ec36306bedae27ecbb51176fb03ff35581b0c5f66dbcf722f4f69e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09dbb3f20dcb25d5f1abab3d5a009686f415799b43575e31738695809a882e3a26e8aa5cdb29951b882c66bd75af3f26abddf8006b053404eb8fafe3038ff5db'
|
7
|
+
data.tar.gz: f3b55698e2feb4425bf56d855b82570ec59c7ce51a867b7c447e7386a4c88245534bb54513f638b5b3fd60e2a390d374fd53c6199d0bf761ce5c91ff6186e600
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Scaffolding::RoutesFileManipulator
|
2
|
-
attr_accessor :child, :parent, :lines, :transformer_options
|
2
|
+
attr_accessor :child, :parent, :lines, :transformer_options, :block_manipulator
|
3
3
|
|
4
4
|
def initialize(filename, child, parent, transformer_options = {})
|
5
5
|
self.child = child
|
@@ -7,6 +7,7 @@ class Scaffolding::RoutesFileManipulator
|
|
7
7
|
@filename = filename
|
8
8
|
self.lines = File.readlines(@filename)
|
9
9
|
self.transformer_options = transformer_options
|
10
|
+
self.block_manipulator = Scaffolding::BlockManipulator.new(@filename)
|
10
11
|
end
|
11
12
|
|
12
13
|
def child_parts
|
@@ -141,7 +142,12 @@ class Scaffolding::RoutesFileManipulator
|
|
141
142
|
current_namespace = nil
|
142
143
|
while namespaces.any?
|
143
144
|
current_namespace = namespaces.shift
|
144
|
-
namespace_lines =
|
145
|
+
namespace_lines = if within.nil?
|
146
|
+
find_namespaces(created_namespaces + [current_namespace], within)
|
147
|
+
else
|
148
|
+
scope_namespace_to_parent(current_namespace, within)
|
149
|
+
end
|
150
|
+
|
145
151
|
unless namespace_lines[current_namespace]
|
146
152
|
lines_to_add = ["namespace :#{current_namespace} do", "end"]
|
147
153
|
if created_namespaces.any?
|
@@ -156,6 +162,35 @@ class Scaffolding::RoutesFileManipulator
|
|
156
162
|
namespace_lines ? namespace_lines[current_namespace] : nil
|
157
163
|
end
|
158
164
|
|
165
|
+
# Since it's possible for multiple namespaces to exist on different levels,
|
166
|
+
# We scope the namespace we're trying to scaffold to its proper parent before processing it.
|
167
|
+
#
|
168
|
+
# i.e:
|
169
|
+
# Parent: Insight => Child: Personality::CharacterTrait
|
170
|
+
# Parent: Team => Child: Personality::Disposition
|
171
|
+
# In this case, the :personality namespace under :insights should be
|
172
|
+
# ignored when Super Scaffolding Personality::Dispositon.
|
173
|
+
#
|
174
|
+
# resources do :insights do
|
175
|
+
# namespace :personality do
|
176
|
+
# resources :character_traits
|
177
|
+
# end
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# namespace :personality do
|
181
|
+
# resources :dispositions
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
# In this case, Personality::CharacterTrait is under Team just like Personality::Disposition,
|
185
|
+
# but Personality::CharacterTrait's DIRECT parent is Insight so we shouldn't scaffold its routes there.
|
186
|
+
def scope_namespace_to_parent(namespace, within)
|
187
|
+
namespace_block_start = namespace_blocks_directly_under_parent(within).map do |namespace_block|
|
188
|
+
namespace_line_number = namespace_block.begin
|
189
|
+
namespace_line_number if lines[namespace_line_number].match?(/ +namespace :#{namespace}/)
|
190
|
+
end.compact
|
191
|
+
namespace_block_start.present? ? {namespace => namespace_block_start} : {}
|
192
|
+
end
|
193
|
+
|
159
194
|
def find(needle, within = nil)
|
160
195
|
lines_within(within).each_with_index do |line, line_number|
|
161
196
|
return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
|
@@ -220,6 +255,8 @@ class Scaffolding::RoutesFileManipulator
|
|
220
255
|
result
|
221
256
|
end
|
222
257
|
|
258
|
+
# Finds namespace blocks no matter how many levels deep they are nested in resource blocks, etc.
|
259
|
+
# However, will not find namespace blocks inside namespace blocks.
|
223
260
|
def top_level_namespace_block_lines(within)
|
224
261
|
local_namespace_blocks = []
|
225
262
|
lines_within(within).each do |line|
|
@@ -253,6 +290,24 @@ class Scaffolding::RoutesFileManipulator
|
|
253
290
|
local_namespace_blocks
|
254
291
|
end
|
255
292
|
|
293
|
+
# Whereas top_level_namespace_block_lines grabs all namespace blocks that
|
294
|
+
# appear first no matter how many resource blocks they're nested in,
|
295
|
+
# this method grabs namespace blocks that are only indented one level deep.
|
296
|
+
def namespace_blocks_directly_under_parent(within)
|
297
|
+
blocks = []
|
298
|
+
if lines[within].match?(/do$/)
|
299
|
+
parent_indentation_size = block_manipulator.block_indentation_size(within)
|
300
|
+
within_block_end = find_block_end(within)
|
301
|
+
within.upto(within_block_end) do |line_number|
|
302
|
+
if lines[line_number].match?(/^#{" " * (parent_indentation_size + 2)}namespace/)
|
303
|
+
namespace_block_lines = line_number..find_block_end(line_number)
|
304
|
+
blocks << namespace_block_lines
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
blocks
|
309
|
+
end
|
310
|
+
|
256
311
|
def find_or_create_resource_block(parts, options = {})
|
257
312
|
find_or_create_resource(parts, options)
|
258
313
|
find_or_convert_resource_block(parts.last, options)
|
@@ -300,7 +355,6 @@ class Scaffolding::RoutesFileManipulator
|
|
300
355
|
child_namespaces, child_resource, parent_namespaces, parent_resource = divergent_parts
|
301
356
|
|
302
357
|
within = find_or_create_namespaces(base_namespaces)
|
303
|
-
within = find_or_create_namespaces(common_namespaces, within) if common_namespaces.any?
|
304
358
|
|
305
359
|
# e.g. Project and Projects::Deliverable
|
306
360
|
if parent_namespaces.empty? && child_namespaces.one? && parent_resource == child_namespaces.first
|
@@ -326,33 +380,31 @@ class Scaffolding::RoutesFileManipulator
|
|
326
380
|
# resources :deliverables, except: collection_actions
|
327
381
|
# end
|
328
382
|
|
383
|
+
# We want to see if there are any namespaces one level above the parent itself,
|
384
|
+
# because namespaces with the same name as the resource can exist on the same level.
|
385
|
+
parent_block_start = find_block_parent(parent_within)
|
386
|
+
namespace_line_within = find_or_create_namespaces(child_namespaces, parent_block_start)
|
387
|
+
find_or_create_resource([child_resource], options: "except: collection_actions", within: namespace_line_within)
|
329
388
|
unless find_namespaces(child_namespaces, within)[child_namespaces.last]
|
330
|
-
|
331
|
-
unless find_namespaces(child_namespaces, within)[child_namespaces.last]
|
332
|
-
raise "tried to insert `namespace :#{child_namespaces.last}` but it seems we failed"
|
333
|
-
end
|
389
|
+
raise "tried to insert `namespace :#{child_namespaces.last}` but it seems we failed"
|
334
390
|
end
|
335
391
|
|
336
|
-
find_or_create_resource(child_namespaces + [child_resource], options: "except: collection_actions", within: within)
|
337
|
-
|
338
392
|
# e.g. Projects::Deliverable and Objective Under It, Abstract::Concept and Concrete::Thing
|
339
393
|
elsif parent_namespaces.any?
|
340
394
|
|
341
395
|
# namespace :projects do
|
342
396
|
# resources :deliverables
|
343
397
|
# end
|
344
|
-
|
398
|
+
top_parent_namespace = find_namespaces(parent_namespaces, within)[parent_namespaces.first]
|
399
|
+
find_or_create_resource(child_namespaces + [child_resource], within: top_parent_namespace)
|
400
|
+
|
345
401
|
# resources :projects_deliverables, path: 'projects/deliverables' do
|
346
402
|
# resources :objectives
|
347
403
|
# end
|
348
|
-
|
349
|
-
find_resource(parent_namespaces + [parent_resource], within: within)
|
350
|
-
top_parent_namespace = find_namespaces(parent_namespaces, within)[parent_namespaces.first]
|
351
404
|
block_parent_within = find_block_parent(top_parent_namespace)
|
352
405
|
parent_namespaces_and_resource = (parent_namespaces + [parent_resource]).join("_")
|
353
406
|
parent_within = find_or_create_resource_block([parent_namespaces_and_resource], options: "path: '#{parent_namespaces_and_resource.tr("_", "/")}'", within: block_parent_within)
|
354
407
|
find_or_create_resource(child_namespaces + [child_resource], within: parent_within)
|
355
|
-
|
356
408
|
else
|
357
409
|
|
358
410
|
begin
|
data/lib/scaffolding/script.rb
CHANGED
@@ -37,6 +37,12 @@ def check_required_options_for_attributes(scaffolding_type, attributes, child, p
|
|
37
37
|
name = parts.shift
|
38
38
|
type = parts.join(":")
|
39
39
|
|
40
|
+
unless Scaffolding.valid_attribute_type?(type)
|
41
|
+
raise "You have entered an invalid attribute type: #{type}. General data types are used when creating new models, but Bullet Train " +
|
42
|
+
"uses field partials when Super Scaffolding, i.e. - `name:text_field` as opposed to `name:string`. " +
|
43
|
+
"Please refer to the Field Partial documentation to view which attribute types are available."
|
44
|
+
end
|
45
|
+
|
40
46
|
# extract any options they passed in with the field.
|
41
47
|
type, attribute_options = type.scan(/^(.*){(.*)}/).first || type
|
42
48
|
|
@@ -655,8 +655,14 @@ class Scaffolding::Transformer
|
|
655
655
|
"email"
|
656
656
|
when "color_picker"
|
657
657
|
"code"
|
658
|
-
|
658
|
+
when "text_field"
|
659
|
+
"text"
|
660
|
+
when "text_area"
|
661
|
+
"text"
|
662
|
+
when "file_field"
|
659
663
|
"text"
|
664
|
+
else
|
665
|
+
raise "Invalid attribute type: #{type}."
|
660
666
|
end
|
661
667
|
|
662
668
|
cell_attributes = if boolean_buttons
|
@@ -1030,10 +1036,14 @@ class Scaffolding::Transformer
|
|
1030
1036
|
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)
|
1031
1037
|
scaffold_add_line_to_file("./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true)
|
1032
1038
|
|
1033
|
-
assertion =
|
1039
|
+
assertion = case type
|
1040
|
+
when "date_field"
|
1034
1041
|
"assert_equal Date.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
|
1035
|
-
|
1042
|
+
when "date_and_time_field"
|
1036
1043
|
"assert_equal DateTime.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
|
1044
|
+
when "file_field"
|
1045
|
+
# TODO: If we want to use Cloudinary to handle our files, we should make sure we're getting a URL.
|
1046
|
+
"assert_equal tangible_thing_data['#{name}']['record']['id'], tangible_thing.#{name}.record.id"
|
1037
1047
|
else
|
1038
1048
|
"assert_equal tangible_thing_data['#{name}'], tangible_thing.#{name}"
|
1039
1049
|
end
|
@@ -1276,10 +1286,20 @@ class Scaffolding::Transformer
|
|
1276
1286
|
else
|
1277
1287
|
transform_string("association :absolutely_abstract_creative_concept, factory: :scaffolding_absolutely_abstract_creative_concept")
|
1278
1288
|
end
|
1289
|
+
|
1279
1290
|
scaffold_replace_line_in_file("./test/factories/scaffolding/completely_concrete/tangible_things.rb", content, "absolutely_abstract_creative_concept { nil }")
|
1280
1291
|
|
1281
1292
|
add_has_many_association
|
1282
1293
|
|
1294
|
+
# Adds file attachment to factory
|
1295
|
+
attributes.each do |attribute|
|
1296
|
+
attribute_name, partial_type = attribute.split(":")
|
1297
|
+
if partial_type == "file_field"
|
1298
|
+
content = "#{attribute_name} { Rack::Test::UploadedFile.new(\"test/support/foo.txt\") }"
|
1299
|
+
scaffold_replace_line_in_file("./test/factories/scaffolding/completely_concrete/tangible_things.rb", content, "#{attribute_name} { nil }")
|
1300
|
+
end
|
1301
|
+
end
|
1302
|
+
|
1283
1303
|
if class_names_transformer.belongs_to_needs_class_definition?
|
1284
1304
|
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"))
|
1285
1305
|
end
|
data/lib/scaffolding.rb
CHANGED
@@ -1,2 +1,21 @@
|
|
1
1
|
module Scaffolding
|
2
|
+
def self.valid_attribute_type?(type)
|
3
|
+
[
|
4
|
+
"boolean",
|
5
|
+
"button",
|
6
|
+
"cloudinary_image",
|
7
|
+
"color_picker",
|
8
|
+
"date_and_time_field",
|
9
|
+
"date_field",
|
10
|
+
"email_field",
|
11
|
+
"file_field",
|
12
|
+
"options",
|
13
|
+
"password_field",
|
14
|
+
"phone_field",
|
15
|
+
"super_select",
|
16
|
+
"text_area",
|
17
|
+
"text_field",
|
18
|
+
"trix_editor"
|
19
|
+
].include?(type.gsub(/{.*}/, "")) # Pop off curly brackets such as `super_select{class_name=Membership}`
|
20
|
+
end
|
2
21
|
end
|
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.
|
4
|
+
version: 1.0.29
|
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-
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: standard
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: spring
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: indefinite_article
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|