bullet_train-super_scaffolding 1.2.9 → 1.2.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/account/scaffolding/completely_concrete/tangible_things_controller.rb +1 -1
- data/lib/bullet_train/super_scaffolding/version.rb +1 -1
- data/lib/scaffolding/block_manipulator.rb +213 -180
- data/lib/scaffolding/file_manipulator.rb +1 -6
- data/lib/scaffolding/oauth_providers.rb +0 -5
- data/lib/scaffolding/routes_file_manipulator.rb +26 -8
- data/lib/scaffolding/transformer.rb +79 -14
- metadata +3 -9
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.json.jbuilder +0 -8
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/_collaborator.json.jbuilder +0 -9
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/index.json.jbuilder +0 -1
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/show.json.jbuilder +0 -1
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/index.json.jbuilder +0 -1
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.json.jbuilder +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 175742fbb3b9512721c4250562fc533f6c43cf630f3c277345d59d61538a3364
|
4
|
+
data.tar.gz: 83933564920e87dc260767af664fcba01894f1484d76ed93c8288742705071f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e9a5613d412175f70bd8cdedd9a2aa91cee42a96fefdf0b16ec5862276ef09f0f0f664062b0968d197a5a1b986b7b7f25e154422736f1c3fd5d4026cafe1784
|
7
|
+
data.tar.gz: 1d004de2a792cdd6d0d39f65842aa5ef161c4018d681beb5579737c1191b95411bcea4b2adeeb3561c14b34b69b389bcf8dc01025d2f6612b96d6f300445871a
|
@@ -26,7 +26,7 @@ class Account::Scaffolding::CompletelyConcrete::TangibleThingsController < Accou
|
|
26
26
|
def create
|
27
27
|
respond_to do |format|
|
28
28
|
if @tangible_thing.save
|
29
|
-
format.html { redirect_to [:account, @
|
29
|
+
format.html { redirect_to [:account, @tangible_thing], notice: I18n.t("scaffolding/completely_concrete/tangible_things.notifications.created") }
|
30
30
|
format.json { render :show, status: :created, location: [:account, @tangible_thing] }
|
31
31
|
else
|
32
32
|
format.html { render :new, status: :unprocessable_entity }
|
@@ -1,209 +1,242 @@
|
|
1
1
|
require "scaffolding/file_manipulator"
|
2
2
|
|
3
|
-
module Scaffolding
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
3
|
+
module Scaffolding
|
4
|
+
class BlockManipulator
|
5
|
+
class << self
|
6
|
+
#
|
7
|
+
# Wrap a block of ruby code with another block on the outside.
|
8
|
+
#
|
9
|
+
# @param [String] `starting` A string to search for at the start of the block. Eg "<%= updates_for context, collection do"
|
10
|
+
# @param [Array] `with` An array with two String elements. The text that should wrap the block. Eg ["<%= action_model_select_controller do %>", "<% end %>"]
|
11
|
+
#
|
12
|
+
def wrap_block(starting:, with:, lines:)
|
13
|
+
with[0] += "\n" unless with[0].match?(/\n$/)
|
14
|
+
with[1] += "\n" unless with[1].match?(/\n$/)
|
15
|
+
starting_line = find_block_start(starting_from: starting, lines: lines)
|
16
|
+
end_line = find_block_end(starting_from: starting_line, lines: lines)
|
17
|
+
|
18
|
+
final = []
|
19
|
+
block_indent = ""
|
20
|
+
spacer = " "
|
21
|
+
lines.each_with_index do |line, index|
|
22
|
+
line += "\n" unless line.match?(/\n$/)
|
23
|
+
if index < starting_line
|
24
|
+
final << line
|
25
|
+
elsif index == starting_line
|
26
|
+
block_indent = line.match(/^\s*/).to_s
|
27
|
+
final << block_indent + with[0]
|
28
|
+
final << (line.blank? ? "\n" : "#{spacer}#{line}")
|
29
|
+
elsif index > starting_line && index < end_line
|
30
|
+
final << (line.blank? ? "\n" : "#{spacer}#{line}")
|
31
|
+
elsif index == end_line
|
32
|
+
final << (line.blank? ? "\n" : "#{spacer}#{line}")
|
33
|
+
final << block_indent + with[1]
|
34
|
+
else
|
35
|
+
final << line
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
lines = final
|
40
|
+
unless lines.last.match?(/\n$/)
|
41
|
+
lines[-1] += "\n"
|
42
|
+
end
|
43
|
+
lines
|
34
44
|
end
|
35
|
-
end
|
36
45
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
# This method unwraps the block from the perspective of the child.
|
47
|
+
#
|
48
|
+
# 2.times do
|
49
|
+
# 3.times do
|
50
|
+
# puts "foo"
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# Here we would pass the index of `"3.times do\n"` to
|
55
|
+
# `block_start` which would result in removing the outer block.
|
56
|
+
def unwrap_block(lines:, block_start:)
|
57
|
+
block_start = if block_start.is_a? String
|
58
|
+
block_start_line = lines.find { |line| line.match?(block_start) }
|
59
|
+
lines.index(block_start_line)
|
60
|
+
end
|
43
61
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
# 3.times do
|
48
|
-
# puts "foo"
|
49
|
-
# end
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# Here we would pass the index of `"3.times do\n"` to
|
53
|
-
# `block_start` which would result in removing the outer block.
|
54
|
-
def self.unwrap_block(lines:, block_start:)
|
55
|
-
block_start = if block_start.is_a? String
|
56
|
-
block_start_line = lines.find { |line| line.match?(block_start) }
|
57
|
-
lines.index(block_start_line)
|
58
|
-
end
|
62
|
+
# Find the proper indices for both child and parent blocks.
|
63
|
+
block_parent_start = find_block_parent(block_start, lines)
|
64
|
+
block_parent_end = find_block_end(starting_from: block_parent_start, lines: lines)
|
59
65
|
|
60
|
-
|
61
|
-
|
62
|
-
|
66
|
+
new_lines = shift_block(lines: lines, block_start: block_start)
|
67
|
+
new_lines.reject.with_index { |lines, idx| idx == block_parent_start || idx == block_parent_end }
|
68
|
+
end
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
end
|
70
|
+
def insert(content, lines:, within: nil, after: nil, before: nil, after_block: nil, append: false)
|
71
|
+
content = prepare_content_array(content)
|
67
72
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
if after_block.present?
|
83
|
-
block_start = find_block_start(starting_from: after_block, lines: lines)
|
84
|
-
block_end = find_block_end(starting_from: block_start, lines: lines)
|
85
|
-
start_line = block_end
|
86
|
-
end_line = lines.count - 1
|
87
|
-
end
|
88
|
-
index = start_line
|
89
|
-
match = false
|
90
|
-
while index < end_line && !match
|
91
|
-
line = lines[index]
|
92
|
-
if after.nil? || line.match?(after)
|
93
|
-
unless append
|
94
|
-
match = true
|
95
|
-
# We adjust the injection point if we really wanted to insert before.
|
96
|
-
lines = insert_line(content, index - (before ? 1 : 0), lines)
|
73
|
+
# We initialize the search with the entire file's lines and look for the block below.
|
74
|
+
start_line = 0
|
75
|
+
end_line = lines.count - 1
|
76
|
+
|
77
|
+
# Search for before like we do after, we'll just inject before it.
|
78
|
+
after ||= before
|
79
|
+
|
80
|
+
# If within is given, find the start and end lines of the block
|
81
|
+
if within.present?
|
82
|
+
start_line = find_block_start(starting_from: within, lines: lines)
|
83
|
+
end_line = find_block_end(starting_from: start_line, lines: lines)
|
84
|
+
# start_line += 1 # ensure we actually insert the content _within_ the given block
|
85
|
+
# end_line += 1 if end_line == start_line
|
97
86
|
end
|
98
|
-
end
|
99
|
-
index += 1
|
100
|
-
end
|
101
87
|
|
102
|
-
|
88
|
+
if after_block.present?
|
89
|
+
block_start = find_block_start(starting_from: after_block, lines: lines)
|
90
|
+
block_end = find_block_end(starting_from: block_start, lines: lines)
|
91
|
+
start_line = block_end
|
92
|
+
end_line = lines.count - 1
|
93
|
+
end
|
103
94
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
95
|
+
index = start_line
|
96
|
+
match = false
|
97
|
+
while index < end_line && !match
|
98
|
+
line = lines[index]
|
99
|
+
if after.nil? || line.match?(after)
|
100
|
+
unless append
|
101
|
+
match = true
|
102
|
+
indent = !(before.present? || after.present? || after_block.present?)
|
103
|
+
|
104
|
+
# We adjust the injection point if we really wanted to insert before.
|
105
|
+
lines = insert_lines(content, index - (before ? 1 : 0), lines, indent)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
index += 1
|
109
|
+
end
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
final << indent + content
|
111
|
+
return lines if match
|
112
|
+
|
113
|
+
# Match should always be false here.
|
114
|
+
if append && !match
|
115
|
+
lines = insert_lines(content, index - 1, lines)
|
116
|
+
end
|
117
|
+
lines
|
119
118
|
end
|
120
|
-
end
|
121
|
-
final
|
122
|
-
end
|
123
119
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
120
|
+
def insert_lines(content, insert_at_index, lines, indent)
|
121
|
+
final = []
|
122
|
+
lines.each_with_index do |line, index|
|
123
|
+
indentation = line.match(/^\s*/).to_s
|
124
|
+
indentation += "\s" * 2 if indent
|
125
|
+
|
126
|
+
final << line
|
127
|
+
content.each { |new_line| final << indentation + new_line } if index == insert_at_index
|
128
|
+
end
|
129
|
+
final
|
130
|
+
end
|
130
131
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
unless lines[cursor].match?(/^#{indentation_of(starting_line_number, lines)}/) || !lines[cursor].present?
|
136
|
-
return cursor
|
132
|
+
# TODO: We should eventually replace this with `insert_lines``,
|
133
|
+
# I just want to make sure everything doesn't break first.
|
134
|
+
def insert_line(content, insert_at_index, lines, indent = true)
|
135
|
+
insert_lines(prepare_content_array(content), insert_at_index, lines, indent)
|
137
136
|
end
|
138
|
-
cursor -= 1
|
139
|
-
end
|
140
|
-
nil
|
141
|
-
end
|
142
137
|
|
143
|
-
|
144
|
-
|
145
|
-
|
138
|
+
def insert_block(block_content, after_block:, lines:)
|
139
|
+
# Since `after_block` must be present for this method to work,
|
140
|
+
# the assumption is we never inseart a block inside an empty block, but
|
141
|
+
# always after the end of one. For that reason, ident defaults to false.
|
142
|
+
indent = false
|
143
|
+
block_start = find_block_start(starting_from: after_block, lines: lines)
|
144
|
+
block_end = find_block_end(starting_from: block_start, lines: lines)
|
145
|
+
lines = insert_line(block_content[0], block_end, lines, indent)
|
146
|
+
insert_line(block_content[1], block_end + 1, lines, indent)
|
147
|
+
end
|
146
148
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
def find_block_parent(starting_line_number, lines)
|
150
|
+
return nil unless indentation_of(starting_line_number, lines)
|
151
|
+
cursor = starting_line_number
|
152
|
+
while cursor >= 0
|
153
|
+
unless lines[cursor].match?(/^#{indentation_of(starting_line_number, lines)}/) || !lines[cursor].present?
|
154
|
+
return cursor
|
155
|
+
end
|
156
|
+
cursor -= 1
|
157
|
+
end
|
158
|
+
nil
|
151
159
|
end
|
152
|
-
end
|
153
|
-
starting_line
|
154
|
-
end
|
155
160
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
161
|
+
def find_block_start(starting_from:, lines:)
|
162
|
+
matcher = Regexp.escape(starting_from)
|
163
|
+
starting_line = 0
|
164
|
+
|
165
|
+
lines.each_with_index do |line, index|
|
166
|
+
if line.match?(matcher)
|
167
|
+
starting_line = index
|
168
|
+
break
|
169
|
+
end
|
170
|
+
end
|
171
|
+
starting_line
|
162
172
|
end
|
163
|
-
end
|
164
173
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
break current_line if depth == 0
|
174
|
-
end
|
175
|
-
current_line
|
176
|
-
end
|
174
|
+
def find_block_end(starting_from:, lines:)
|
175
|
+
# This loop was previously in the RoutesFileManipulator.
|
176
|
+
lines.each_with_index do |line, line_number|
|
177
|
+
next unless line_number > starting_from
|
178
|
+
if /^#{indentation_of(starting_from, lines)}end\s*/.match?(line)
|
179
|
+
return line_number
|
180
|
+
end
|
181
|
+
end
|
177
182
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
183
|
+
depth = 0
|
184
|
+
current_line = starting_from
|
185
|
+
lines[starting_from..lines.count].each_with_index do |line, index|
|
186
|
+
current_line = starting_from + index
|
187
|
+
depth += 1 if line.match?(/\s*<%.+ do .*%>/)
|
188
|
+
depth += 1 if line.match?(/\s*<% if .*%>/)
|
189
|
+
depth += 1 if line.match?(/\s*<% unless .*%>/)
|
190
|
+
depth -= 1 if line.match?(/\s*<%.* end .*%>/)
|
191
|
+
break current_line if depth == 0
|
192
|
+
end
|
193
|
+
current_line
|
194
|
+
end
|
186
195
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
if
|
199
|
-
|
200
|
-
|
201
|
-
|
196
|
+
# TODO: We shouldn't need this second argument, but since
|
197
|
+
# we have `lines` here and in the RoutesFileManipulator,
|
198
|
+
# the lines diverge from one another when we edit them individually.
|
199
|
+
def indentation_of(line_number, lines)
|
200
|
+
lines[line_number].match(/^( +)/)[1]
|
201
|
+
rescue
|
202
|
+
nil
|
203
|
+
end
|
204
|
+
|
205
|
+
# Shifts the block either to the left or right.
|
206
|
+
def shift_block(lines:, block_start:, direction: :left, amount: 2, shift_contents_only: false)
|
207
|
+
block_start = lines.index(block_start) if block_start.is_a? String
|
208
|
+
block_range = (block_start..(find_block_end(starting_from: block_start, lines: lines)))
|
209
|
+
block_range = (block_range.first + 1)..(block_range.last - 1) if shift_contents_only
|
210
|
+
new_lines = []
|
211
|
+
|
212
|
+
lines.each_with_index do |line, line_number|
|
213
|
+
if block_range.cover?(line_number)
|
214
|
+
# If we're shifting a block to the left, we want to safeguard
|
215
|
+
# the String so it doesn't delete any excess characters.
|
216
|
+
if direction == :left
|
217
|
+
amount.times { line = line.gsub(/^ /, "") }
|
218
|
+
elsif direction == :right
|
219
|
+
line = "\s" * amount + line
|
220
|
+
end
|
221
|
+
end
|
222
|
+
new_lines << line
|
202
223
|
end
|
224
|
+
|
225
|
+
new_lines
|
203
226
|
end
|
204
|
-
new_lines << line
|
205
|
-
end
|
206
227
|
|
207
|
-
|
228
|
+
private
|
229
|
+
|
230
|
+
def prepare_content_array(content)
|
231
|
+
# Ensure content is an Array
|
232
|
+
content = [content].flatten
|
233
|
+
|
234
|
+
# Ensure there are no stray new lines within each string
|
235
|
+
content = content.map { |line| line.split("\n") }.flatten
|
236
|
+
|
237
|
+
# Ensure each new line has a line break at the end.
|
238
|
+
content.map { |line| line.match?(/\n$/) ? line : "#{line}\n" }
|
239
|
+
end
|
240
|
+
end
|
208
241
|
end
|
209
242
|
end
|
@@ -3,7 +3,7 @@ require "scaffolding/block_manipulator"
|
|
3
3
|
# TODO: If we move this and the BlockManipulator into their own gems,
|
4
4
|
# we can probably call these methods with something shorter without `Scaffolding::`.
|
5
5
|
module Scaffolding::FileManipulator
|
6
|
-
def self.find(lines, needle, within =
|
6
|
+
def self.find(lines, needle, within = 0)
|
7
7
|
lines_within(lines, within).each_with_index do |line, line_number|
|
8
8
|
return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
|
9
9
|
end
|
@@ -15,11 +15,6 @@ module Scaffolding::FileManipulator
|
|
15
15
|
lines[(within + 1)..(Scaffolding::BlockManipulator.find_block_end(starting_from: within, lines: lines) + 1)]
|
16
16
|
end
|
17
17
|
|
18
|
-
# TODO I was running into an error in a downstream application where it couldn't find silence_logs? We should implement it in this package.
|
19
|
-
def self.silence_logs?
|
20
|
-
ENV["SILENCE_LOGS"].present?
|
21
|
-
end
|
22
|
-
|
23
18
|
def self.replace_line_in_file(file, content, in_place_of, options = {})
|
24
19
|
begin
|
25
20
|
target_file_content = File.read(file)
|
@@ -10,11 +10,6 @@ def legacy_resolve_template_path(file)
|
|
10
10
|
end.compact.first || raise("Couldn't find the Super Scaffolding template for `#{file}` in any of the following locations:\n\n#{BulletTrain::SuperScaffolding.template_paths.join("\n")}")
|
11
11
|
end
|
12
12
|
|
13
|
-
# TODO I was running into an error in a downstream application where it couldn't find silence_logs? We should implement it in this package.
|
14
|
-
def silence_logs?
|
15
|
-
ENV["SILENCE_LOGS"].present?
|
16
|
-
end
|
17
|
-
|
18
13
|
def legacy_replace_in_file(file, before, after)
|
19
14
|
puts "Replacing in '#{file}'." unless silence_logs?
|
20
15
|
target_file_content = File.read(file)
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require "scaffolding/block_manipulator"
|
2
2
|
|
3
3
|
class Scaffolding::RoutesFileManipulator
|
4
|
-
attr_accessor :child, :parent, :lines, :transformer_options
|
4
|
+
attr_accessor :child, :parent, :lines, :transformer_options, :concerns
|
5
5
|
|
6
6
|
def initialize(filename, child, parent, transformer_options = {})
|
7
|
+
@concerns = []
|
7
8
|
self.child = child
|
8
9
|
self.parent = parent
|
9
10
|
@filename = filename
|
@@ -375,17 +376,34 @@ class Scaffolding::RoutesFileManipulator
|
|
375
376
|
within = find_or_convert_resource_block(parent_resource, options: "except: collection_actions", within: within)
|
376
377
|
end
|
377
378
|
|
378
|
-
|
379
|
+
add_concern(:sortable) if transformer_options["sortable"]
|
380
|
+
find_or_create_resource(child_namespaces + [child_resource], options: formatted_concerns, within: within)
|
379
381
|
|
380
382
|
end
|
381
383
|
end
|
382
384
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
385
|
+
def add_concern(concern)
|
386
|
+
@concerns.push(concern)
|
387
|
+
end
|
388
|
+
|
389
|
+
def formatted_concerns
|
390
|
+
return if @concerns.empty?
|
391
|
+
"concerns: #{@concerns}"
|
392
|
+
end
|
387
393
|
|
388
|
-
|
389
|
-
|
394
|
+
# Adds a concern to an existing resource at the given line number. (used by the audit logs gem)
|
395
|
+
def add_concern_at_line(concern, line_number)
|
396
|
+
line = lines[line_number]
|
397
|
+
existing_concerns = line.match(/concerns: \[(.*)\]/).to_a[1].to_s.split(",")
|
398
|
+
existing_concerns.map! { |e| e.tr(":", "").tr("\"", "").squish&.to_sym }
|
399
|
+
existing_concerns.filter! { |e| e.present? }
|
400
|
+
existing_concerns << concern
|
401
|
+
if line.include?("concerns:")
|
402
|
+
lines[line_number].gsub!(/concerns: \[(.*)\]/, "concerns: [#{existing_concerns.map { |e| ":#{e}" }.join(", ")}]")
|
403
|
+
elsif line.ends_with?(" do")
|
404
|
+
lines[line_number].gsub!(/ do$/, " concerns: [#{existing_concerns.map { |e| ":#{e}" }.join(", ")}] do")
|
405
|
+
else
|
406
|
+
lines[line_number].gsub!(/resources :(.*)$/, "resources :\\1, concerns: [#{existing_concerns.map { |e| ":#{e}" }.join(", ")}]")
|
407
|
+
end
|
390
408
|
end
|
391
409
|
end
|
@@ -23,6 +23,16 @@ class Scaffolding::Transformer
|
|
23
23
|
"Team"
|
24
24
|
end
|
25
25
|
|
26
|
+
def top_level_model?
|
27
|
+
parent == "Team" || no_parent?
|
28
|
+
end
|
29
|
+
|
30
|
+
# We write an explicit method here so we know we
|
31
|
+
# aren't handling `parent` in this situation as `nil`.
|
32
|
+
def no_parent?
|
33
|
+
parent == "None"
|
34
|
+
end
|
35
|
+
|
26
36
|
def update_action_models_abstract_class(targets_n)
|
27
37
|
end
|
28
38
|
|
@@ -41,7 +51,9 @@ class Scaffolding::Transformer
|
|
41
51
|
RUBY_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will insert new fields above this line."
|
42
52
|
RUBY_ADDITIONAL_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will also insert new fields above this line."
|
43
53
|
RUBY_EVEN_MORE_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will additionally insert new fields above this line."
|
54
|
+
RUBY_NEW_API_VERSION_HOOK = "# 🚅 super scaffolding will insert new api versions above this line."
|
44
55
|
RUBY_FILES_HOOK = "# 🚅 super scaffolding will insert file-related logic above this line."
|
56
|
+
RUBY_FACTORY_SETUP_HOOK = "# 🚅 super scaffolding will insert factory setup in place of this line."
|
45
57
|
ERB_NEW_FIELDS_HOOK = "<%#{RUBY_NEW_FIELDS_HOOK} %>"
|
46
58
|
CONCERNS_HOOK = "# 🚅 add concerns above."
|
47
59
|
ATTR_ACCESSORS_HOOK = "# 🚅 add attribute accessors above."
|
@@ -251,11 +263,6 @@ class Scaffolding::Transformer
|
|
251
263
|
transformed_file_content.join
|
252
264
|
end
|
253
265
|
|
254
|
-
# TODO I was running into an error in a downstream application where it couldn't find silence_logs? We should implement it in this package.
|
255
|
-
def silence_logs?
|
256
|
-
ENV["SILENCE_LOGS"].present?
|
257
|
-
end
|
258
|
-
|
259
266
|
def scaffold_file(file, overrides: false)
|
260
267
|
transformed_file_content = get_transformed_file_content(file)
|
261
268
|
transformed_file_name = transform_string(file)
|
@@ -290,6 +297,9 @@ class Scaffolding::Transformer
|
|
290
297
|
|
291
298
|
Dir.foreach(resolve_template_path(directory)) do |file|
|
292
299
|
file = "#{directory}/#{file}"
|
300
|
+
|
301
|
+
next if file.match?("/_menu_item.html.erb") && !top_level_model?
|
302
|
+
|
293
303
|
unless File.directory?(resolve_template_path(file))
|
294
304
|
scaffold_file(file)
|
295
305
|
end
|
@@ -305,6 +315,9 @@ class Scaffolding::Transformer
|
|
305
315
|
if override_path
|
306
316
|
Dir.foreach(override_path) do |file|
|
307
317
|
file = "#{directory}_overrides/#{file}"
|
318
|
+
|
319
|
+
next if file.match?("/_menu_item.html.erb") && !top_level_model?
|
320
|
+
|
308
321
|
unless File.directory?(resolve_template_path(file))
|
309
322
|
scaffold_file(file, overrides: true)
|
310
323
|
end
|
@@ -571,15 +584,15 @@ class Scaffolding::Transformer
|
|
571
584
|
def add_has_many_association
|
572
585
|
has_many_line = ["has_many :completely_concrete_tangible_things"]
|
573
586
|
|
574
|
-
#
|
575
|
-
|
587
|
+
# Specify the class name if the model is namespaced.
|
588
|
+
if child.match?("::")
|
576
589
|
has_many_line << "class_name: \"Scaffolding::CompletelyConcrete::TangibleThing\""
|
577
590
|
end
|
578
591
|
|
579
592
|
has_many_line << "dependent: :destroy"
|
580
593
|
|
581
|
-
#
|
582
|
-
|
594
|
+
# Specify the foreign key if the parent is namespaced.
|
595
|
+
if parent.match?("::")
|
583
596
|
has_many_line << "foreign_key: :absolutely_abstract_creative_concept_id"
|
584
597
|
|
585
598
|
# And if we need `foreign_key`, we should also specify `inverse_of`.
|
@@ -914,7 +927,8 @@ class Scaffolding::Transformer
|
|
914
927
|
field_content.gsub!(/\s%>/, ", options: { password: true } %>")
|
915
928
|
end
|
916
929
|
|
917
|
-
|
930
|
+
show_page_doesnt_exist = child == "User"
|
931
|
+
scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/show.html.erb", field_content.strip, ERB_NEW_FIELDS_HOOK, prepend: true, suppress_could_not_find: show_page_doesnt_exist)
|
918
932
|
|
919
933
|
end
|
920
934
|
|
@@ -931,6 +945,20 @@ class Scaffolding::Transformer
|
|
931
945
|
scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/_index.html.erb", field_content, "<%# 🚅 super scaffolding will insert new field headers above this line. %>", prepend: true)
|
932
946
|
end
|
933
947
|
|
948
|
+
# If these strings are the same, we get duplicate variable names in the _index.html.erb partial,
|
949
|
+
# so we account for that here. Run the Super Scaffolding test setup script and check the index partial
|
950
|
+
# of models with namespaced parents for reference (i.e. - Objective, Projects::Step).
|
951
|
+
transformed_abstract_str = transform_string("absolutely_abstract_creative_concept")
|
952
|
+
transformed_concept_str = transform_string("creative_concept")
|
953
|
+
transformed_file_name = transform_string("./app/views/account/scaffolding/completely_concrete/tangible_things/_index.html.erb")
|
954
|
+
if (transformed_abstract_str == transformed_concept_str) && File.exist?(transformed_file_name)
|
955
|
+
replace_in_file(
|
956
|
+
transformed_file_name,
|
957
|
+
"#{transformed_abstract_str} = @#{transformed_abstract_str} || @#{transformed_concept_str}",
|
958
|
+
"#{transformed_abstract_str} = @#{transformed_concept_str}"
|
959
|
+
)
|
960
|
+
end
|
961
|
+
|
934
962
|
table_cell_options = []
|
935
963
|
|
936
964
|
if first_table_cell
|
@@ -1393,8 +1421,21 @@ class Scaffolding::Transformer
|
|
1393
1421
|
add_ability_line_to_roles_yml
|
1394
1422
|
end
|
1395
1423
|
|
1424
|
+
# Add factory setup in API controller test.
|
1396
1425
|
unless cli_options["skip-api"]
|
1397
|
-
|
1426
|
+
test_name = transform_string("./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_controller_test.rb")
|
1427
|
+
test_lines = File.open(test_name).readlines
|
1428
|
+
|
1429
|
+
# Shift contents of controller test after skipping `unless scaffolding_things_disabled?` block.
|
1430
|
+
class_block_index = Scaffolding::FileManipulator.find(test_lines, "class #{transform_string("Api::V1::Scaffolding::CompletelyConcrete::TangibleThingsControllerTest")}")
|
1431
|
+
new_lines = Scaffolding::BlockManipulator.shift_block(lines: test_lines, block_start: test_lines[class_block_index], shift_contents_only: true)
|
1432
|
+
Scaffolding::FileManipulator.write(test_name, new_lines)
|
1433
|
+
|
1434
|
+
# Ensure variables built with factories are indented properly.
|
1435
|
+
factory_hook_index = Scaffolding::FileManipulator.find(new_lines, RUBY_FACTORY_SETUP_HOOK)
|
1436
|
+
factory_hook_indentation = Scaffolding::BlockManipulator.indentation_of(factory_hook_index, new_lines)
|
1437
|
+
indented_factory_lines = build_factory_setup.map { |line| "#{factory_hook_indentation}#{line}\n" }
|
1438
|
+
scaffold_replace_line_in_file(test_name, indented_factory_lines.join, new_lines[factory_hook_index])
|
1398
1439
|
end
|
1399
1440
|
|
1400
1441
|
# add children to the show page of their parent.
|
@@ -1490,7 +1531,7 @@ class Scaffolding::Transformer
|
|
1490
1531
|
collection_actions = [:index, :new, :create]
|
1491
1532
|
|
1492
1533
|
# 🚅 Don't remove this block, it will break Super Scaffolding.
|
1493
|
-
begin
|
1534
|
+
begin
|
1494
1535
|
namespace :#{routes_namespace} do
|
1495
1536
|
shallow do
|
1496
1537
|
resources :teams do
|
@@ -1505,11 +1546,35 @@ class Scaffolding::Transformer
|
|
1505
1546
|
|
1506
1547
|
begin
|
1507
1548
|
routes_manipulator.apply([routes_namespace])
|
1508
|
-
Scaffolding::FileManipulator.write(
|
1549
|
+
Scaffolding::FileManipulator.write(routes_path, routes_manipulator.lines)
|
1509
1550
|
rescue => _
|
1510
1551
|
add_additional_step :red, "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/ ."
|
1511
1552
|
end
|
1512
1553
|
|
1554
|
+
# If we're using a custom namespace, we have to make sure the newly
|
1555
|
+
# scaffolded routes are drawn in the `config/routes.rb` and API routes files.
|
1556
|
+
if cli_options["namespace"]
|
1557
|
+
draw_line = "draw \"#{routes_namespace}\""
|
1558
|
+
|
1559
|
+
[
|
1560
|
+
"config/routes.rb",
|
1561
|
+
"config/routes/api/#{BulletTrain::Api.current_version}.rb"
|
1562
|
+
].each do |routes_file|
|
1563
|
+
original_lines = File.readlines(routes_file)
|
1564
|
+
|
1565
|
+
# Define which line we want to place the draw line under in the original routes files.
|
1566
|
+
insert_line = if routes_file.match?("api")
|
1567
|
+
draw_line = " #{draw_line}" # Add necessary indentation.
|
1568
|
+
"namespace :v1 do"
|
1569
|
+
else
|
1570
|
+
"draw \"sidekiq\""
|
1571
|
+
end
|
1572
|
+
|
1573
|
+
new_lines = Scaffolding::BlockManipulator.insert(draw_line, lines: original_lines, within: insert_line)
|
1574
|
+
Scaffolding::FileManipulator.write(routes_file, new_lines)
|
1575
|
+
end
|
1576
|
+
end
|
1577
|
+
|
1513
1578
|
unless cli_options["skip-api"]
|
1514
1579
|
begin
|
1515
1580
|
api_routes_manipulator = Scaffolding::RoutesFileManipulator.new("config/routes/api/#{BulletTrain::Api.current_version}.rb", child, parent, cli_options)
|
@@ -1523,7 +1588,7 @@ class Scaffolding::Transformer
|
|
1523
1588
|
|
1524
1589
|
unless cli_options["skip-parent"]
|
1525
1590
|
|
1526
|
-
if
|
1591
|
+
if top_level_model?
|
1527
1592
|
icon_name = nil
|
1528
1593
|
if cli_options["sidebar"].present?
|
1529
1594
|
icon_name = cli_options["sidebar"]
|
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.2.
|
4
|
+
version: 1.2.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: standard
|
@@ -101,27 +101,21 @@ files:
|
|
101
101
|
- app/models/scaffolding/completely_concrete/tangible_things/assignment.rb
|
102
102
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_breadcrumbs.html.erb
|
103
103
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.html.erb
|
104
|
-
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.json.jbuilder
|
105
104
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_form.html.erb
|
106
105
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_index.html.erb
|
107
106
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_menu_item.html.erb
|
108
107
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/_breadcrumbs.html.erb
|
109
|
-
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/_collaborator.json.jbuilder
|
110
108
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/_form.html.erb
|
111
109
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/_index.html.erb
|
112
110
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/_menu_item.html.erb
|
113
111
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/edit.html.erb
|
114
112
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/index.html.erb
|
115
|
-
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/index.json.jbuilder
|
116
113
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/new.html.erb
|
117
114
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/show.html.erb
|
118
|
-
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/collaborators/show.json.jbuilder
|
119
115
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/edit.html.erb
|
120
116
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/index.html.erb
|
121
|
-
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/index.json.jbuilder
|
122
117
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/new.html.erb
|
123
118
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.html.erb
|
124
|
-
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.json.jbuilder
|
125
119
|
- app/views/account/scaffolding/completely_concrete/tangible_things/_breadcrumbs.html.erb
|
126
120
|
- app/views/account/scaffolding/completely_concrete/tangible_things/_form.html.erb
|
127
121
|
- app/views/account/scaffolding/completely_concrete/tangible_things/_index.html.erb
|
@@ -198,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
198
192
|
- !ruby/object:Gem::Version
|
199
193
|
version: '0'
|
200
194
|
requirements: []
|
201
|
-
rubygems_version: 3.
|
195
|
+
rubygems_version: 3.4.1
|
202
196
|
signing_key:
|
203
197
|
specification_version: 4
|
204
198
|
summary: Bullet Train Super Scaffolding
|
@@ -1,9 +0,0 @@
|
|
1
|
-
json.extract! collaborator,
|
2
|
-
:id,
|
3
|
-
:creative_concept_id,
|
4
|
-
:membership_id,
|
5
|
-
:roles,
|
6
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
7
|
-
:created_at,
|
8
|
-
:updated_at
|
9
|
-
json.url account_scaffolding_absolutely_abstract_creative_concepts_collaborator_url(collaborator, format: :json)
|
@@ -1 +0,0 @@
|
|
1
|
-
json.array! @collaborators, partial: "scaffolding/absolutely_abstract/creative_concepts/collaborators/collaborator", as: :collaborator
|
@@ -1 +0,0 @@
|
|
1
|
-
json.partial! "scaffolding/absolutely_abstract/creative_concepts/collaborators/collaborator", collaborator: @collaborator
|
data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/index.json.jbuilder
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
json.array! @creative_concepts, partial: "scaffolding/absolutely_abstract/creative_concepts/creative_concept", as: :creative_concept
|
@@ -1 +0,0 @@
|
|
1
|
-
json.partial! "scaffolding/absolutely_abstract/creative_concepts/creative_concept", creative_concept: @creative_concept
|