immosquare-cleaner 1.2.4 → 1.3.1
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/immosquare-cleaner/version.rb +1 -1
- data/linters/eslint-plugins/align-assignments.mjs +26 -38
- data/linters/rubocop/cop/custom_cops/style/align_routes.rb +308 -0
- data/linters/rubocop.yml +4 -0
- data/package.json +3 -3
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06af1c0a31ef811c54efdd4d3f845317c81f02db83112947da04390fd5c69e6c
|
|
4
|
+
data.tar.gz: d3c8617e585affa872699e5378ac6c90818d1fe0d6a3fe6f1bbcf62d727c7451
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 354c8df2a5913b65613909c4d000161aafb2fcb7ab66b09e1dd909f0df6d6b74c982f44a65c7f10bba1525ceb1a42203f1aa8df37b70eaf2a8bc327efd7b4808
|
|
7
|
+
data.tar.gz: b0df5b076458f940f997f92bd76643fa472d850c480f88cc9508eccf1fb7ab0cfd8b99429e80ce0d18c9bc85976c52423ae955e48983cfc7d58725d82fc5f641
|
|
@@ -38,8 +38,6 @@
|
|
|
38
38
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
39
39
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
40
40
|
//============================================================//
|
|
41
|
-
const hasRequire = /require\(/
|
|
42
|
-
const spaceMatcher = /(\s*)((?:\|\||&&|\?\?|\+|-|\*|\/|%|&|\^|\||<<|>>|\*\*|>>>)?=)/
|
|
43
41
|
|
|
44
42
|
const assignmentOperators = ["=", "+=", "-=", "*=", "/=", "%=", "&=", "^=", "|=", "<<=", ">>=", "**=", ">>>=", "||=", "&&=", "??="]
|
|
45
43
|
|
|
@@ -100,35 +98,31 @@ const rule = {
|
|
|
100
98
|
previousNode = groupNode
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
|
|
101
|
+
const assignmentTokenOf = (node) => {
|
|
102
|
+
const left = isAssignmentExpression(node) ? node.left : node.declarations[0]?.id
|
|
103
|
+
if (!left) return null
|
|
104
|
+
const token = sourceCode.getTokenAfter(left)
|
|
105
|
+
return token && assignmentOperators.includes(token.value) ? token : null
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
const match = source.slice(prefix).match(spaceMatcher)
|
|
112
|
-
return match ? match.index + prefix + match[2].length : null
|
|
108
|
+
const findAssignment = (node) => {
|
|
109
|
+
const token = assignmentTokenOf(node)
|
|
110
|
+
return token ? token.loc.end.column - sourceCode.getFirstToken(node).loc.start.column - 1 : null
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
const assignmentOnFirstLine = (node) => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const source = sourceCode.getText(node)
|
|
119
|
-
const lines = source.split("\n")
|
|
120
|
-
return lines[0].includes("=")
|
|
114
|
+
const token = assignmentTokenOf(node)
|
|
115
|
+
return token && !isMultiline(sourceCode.getFirstToken(node), token)
|
|
121
116
|
}
|
|
122
117
|
|
|
123
118
|
const areAligned = (maxPos, nodes) => nodes
|
|
124
119
|
.filter(assignmentOnFirstLine)
|
|
125
|
-
.
|
|
126
|
-
.every((source) => source.charAt(maxPos) === "=")
|
|
120
|
+
.every((node) => findAssignment(node) === maxPos)
|
|
127
121
|
|
|
128
122
|
const getMaxPos = (nodes) => nodes
|
|
129
123
|
.filter(assignmentOnFirstLine)
|
|
130
|
-
.map(
|
|
131
|
-
.reduce((last, current) => Math.max(last, current),
|
|
124
|
+
.map(findAssignment)
|
|
125
|
+
.reduce((last, current) => Math.max(last, current), 0)
|
|
132
126
|
|
|
133
127
|
const check = (group) => {
|
|
134
128
|
const maxPos = getMaxPos(group)
|
|
@@ -141,27 +135,21 @@ const rule = {
|
|
|
141
135
|
end: getLast(group).loc.end
|
|
142
136
|
},
|
|
143
137
|
message: "This group of assignments is not aligned",
|
|
144
|
-
fix: (fixer) => group.
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
if (lineIsAligned || !assignmentToken || isMultiline(firstToken, assignmentToken)) return fixer.replaceText(node, line)
|
|
138
|
+
fix: (fixer) => group.flatMap((node) => {
|
|
139
|
+
const firstToken = sourceCode.getFirstToken(node)
|
|
140
|
+
const assignmentToken = assignmentTokenOf(node)
|
|
141
|
+
if (!assignmentToken || isMultiline(firstToken, assignmentToken) || findAssignment(node) === maxPos) return []
|
|
142
|
+
const previousToken = sourceCode.getTokenBefore(assignmentToken)
|
|
143
|
+
const gap = [previousToken.range[1], assignmentToken.range[0]]
|
|
144
|
+
if (sourceCode.commentsExistBetween(previousToken, assignmentToken)) return []
|
|
152
145
|
|
|
153
146
|
//============================================================//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
147
|
+
// Only the spacing before the operator belongs to this rule. Replacing a declaration
|
|
148
|
+
// can cut a template processor's placeholder at an AST boundary inside that marker.
|
|
156
149
|
//============================================================//
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
const start = line.slice(0, startDelimiter).replace(/\s+$/m, "")
|
|
161
|
-
const ending = line.slice(endDelimiter).replace(/^\s+/m, "")
|
|
162
|
-
const spacesRequired = maxPos - start.length - assignmentToken.value.length + 1
|
|
163
|
-
const spaces = " ".repeat(spacesRequired)
|
|
164
|
-
return fixer.replaceText(node, `${start}${spaces}${assignmentToken.value} ${ending}`)
|
|
150
|
+
const prefixWidth = previousToken.loc.end.column - firstToken.loc.start.column
|
|
151
|
+
const spacesRequired = maxPos - prefixWidth - assignmentToken.value.length + 1
|
|
152
|
+
return [fixer.replaceTextRange(gap, " ".repeat(spacesRequired))]
|
|
165
153
|
})
|
|
166
154
|
})
|
|
167
155
|
}
|
|
@@ -169,7 +157,7 @@ const rule = {
|
|
|
169
157
|
return {
|
|
170
158
|
VariableDeclaration: (node) => {
|
|
171
159
|
const source = sourceCode.getText(node)
|
|
172
|
-
if (requiresOnly && !
|
|
160
|
+
if (requiresOnly && !source.includes("require(")) return
|
|
173
161
|
|
|
174
162
|
addNode(node, node)
|
|
175
163
|
},
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module CustomCops
|
|
4
|
+
module Style
|
|
5
|
+
##============================================================##
|
|
6
|
+
## This cop aligns the blocks of Rails routes in
|
|
7
|
+
## `config/routes.rb` and `config/routes/*.rb`: inside a
|
|
8
|
+
## block of consecutive route lines, the verb, the path,
|
|
9
|
+
## the target and every option (`:as`, `:via`,
|
|
10
|
+
## `:constraints`...) start in the same column. Options are
|
|
11
|
+
## aligned by name: a route without `:via` leaves that
|
|
12
|
+
## column empty and its `:as` lands under the `:as` of its
|
|
13
|
+
## neighbours.
|
|
14
|
+
##
|
|
15
|
+
## Only whitespace changes: paths, targets, options and
|
|
16
|
+
## comments come out identical, in the same order. The
|
|
17
|
+
## corrections only rewrite the gaps between tokens, never
|
|
18
|
+
## a token itself, so they cannot clash with the
|
|
19
|
+
## corrections of other cops.
|
|
20
|
+
##
|
|
21
|
+
## The option columns follow an order compatible with the
|
|
22
|
+
## order of every route in the block (`:via` before `:as`
|
|
23
|
+
## when a route carries them in that order, even when a
|
|
24
|
+
## neighbour without `:via` meets `:as` first). When two
|
|
25
|
+
## routes impose opposite orders, the block is left alone:
|
|
26
|
+
## no alignment can satisfy both without reordering.
|
|
27
|
+
##
|
|
28
|
+
## Recognized shapes: `get "a" => "c#a", :as => ...`, the
|
|
29
|
+
## same call with parentheses (`match("a" => "c#a", ...)`),
|
|
30
|
+
## and the shape without a positional target
|
|
31
|
+
## (`match "404", :to => ...`).
|
|
32
|
+
##
|
|
33
|
+
## @example
|
|
34
|
+
## bad
|
|
35
|
+
## get "users" => "users#index", :as => :users
|
|
36
|
+
## match "users/:id" => "users#update", :via => [:patch, :put], :as => :user
|
|
37
|
+
##
|
|
38
|
+
## good
|
|
39
|
+
## get "users" => "users#index", :as => :users
|
|
40
|
+
## match "users/:id" => "users#update", :via => [:patch, :put], :as => :user
|
|
41
|
+
##============================================================##
|
|
42
|
+
class AlignRoutes < RuboCop::Cop::Base
|
|
43
|
+
|
|
44
|
+
extend AutoCorrector
|
|
45
|
+
|
|
46
|
+
MSG = "Align the columns of consecutive routes.".freeze
|
|
47
|
+
|
|
48
|
+
VERBS = [:get, :post, :put, :patch, :delete, :match].freeze
|
|
49
|
+
|
|
50
|
+
##============================================================##
|
|
51
|
+
## Only the files Rails loads its routes from. A `get`
|
|
52
|
+
## call anywhere else is not a route.
|
|
53
|
+
##============================================================##
|
|
54
|
+
ROUTES_FILE = %r{config/routes(?:/[^/]+\.rb|\.rb)\z}
|
|
55
|
+
|
|
56
|
+
def on_new_investigation
|
|
57
|
+
@routes = []
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def on_send(node)
|
|
61
|
+
return unless routes_file?
|
|
62
|
+
return unless VERBS.include?(node.method_name)
|
|
63
|
+
return unless node.receiver.nil?
|
|
64
|
+
|
|
65
|
+
route = parse_route(node)
|
|
66
|
+
@routes << route if route
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def on_investigation_end
|
|
70
|
+
groups.each {|group| check_group(group) }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def routes_file?
|
|
76
|
+
path = processed_source.file_path
|
|
77
|
+
path.nil? || ROUTES_FILE.match?(path.to_s)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##============================================================##
|
|
81
|
+
## A route line cut into segments: verb, path, target when
|
|
82
|
+
## there is one, then its options under their name (`:as`,
|
|
83
|
+
## `:via`...), in the order the line carries them. Every
|
|
84
|
+
## segment keeps its source range, so the corrections can
|
|
85
|
+
## address the gaps between segments. Nil when the call
|
|
86
|
+
## is not a single-line route starting its line.
|
|
87
|
+
##============================================================##
|
|
88
|
+
def parse_route(node)
|
|
89
|
+
range = node.source_range
|
|
90
|
+
return if range.first_line != range.last_line
|
|
91
|
+
|
|
92
|
+
line = processed_source.lines[range.first_line - 1]
|
|
93
|
+
return if line.nil? || !line.strip.start_with?(node.source.strip)
|
|
94
|
+
|
|
95
|
+
first = node.arguments.first
|
|
96
|
+
return if first.nil?
|
|
97
|
+
|
|
98
|
+
if first.hash_type?
|
|
99
|
+
return if first.braces? || first.pairs.empty?
|
|
100
|
+
|
|
101
|
+
pair = first.pairs.first
|
|
102
|
+
return unless pair.key.str_type?
|
|
103
|
+
|
|
104
|
+
target_pair = pair
|
|
105
|
+
path_range = pair.key.source_range
|
|
106
|
+
rest_pairs = first.pairs.drop(1)
|
|
107
|
+
elsif first.str_type?
|
|
108
|
+
target_pair = nil
|
|
109
|
+
path_range = first.source_range
|
|
110
|
+
rest_pairs = []
|
|
111
|
+
if node.arguments.size > 1
|
|
112
|
+
hash = node.arguments[1]
|
|
113
|
+
return unless hash.hash_type? && !hash.braces?
|
|
114
|
+
|
|
115
|
+
rest_pairs = hash.pairs
|
|
116
|
+
end
|
|
117
|
+
else
|
|
118
|
+
return
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
segments = [{:kind => :path, :range => path_range}]
|
|
122
|
+
segments << {:kind => :target, :range => target_pair.value.source_range, :pair => target_pair} if target_pair
|
|
123
|
+
rest_pairs.each_with_index do |pair, index|
|
|
124
|
+
key = pair.key.sym_type? ? ":#{pair.key.value}" : "__raw#{index}"
|
|
125
|
+
segments << {:kind => :option, :key => key, :range => pair.source_range}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
{:node => node, :line => range.first_line, :segments => segments}
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
##============================================================##
|
|
132
|
+
## Blocks of routes on adjacent lines. Any other line
|
|
133
|
+
## (comment, `scope`, `end`, a route this cop does not
|
|
134
|
+
## recognize...) puts at least one line between two
|
|
135
|
+
## routes and so closes the block. Two routes sharing a
|
|
136
|
+
## line are dropped: aligning them would rewrite the
|
|
137
|
+
## same line twice.
|
|
138
|
+
##============================================================##
|
|
139
|
+
def groups
|
|
140
|
+
sorted = @routes.sort_by {|route| route[:node].source_range.begin_pos }
|
|
141
|
+
counts = sorted.map {|route| route[:line] }.tally
|
|
142
|
+
sorted = sorted.reject {|route| counts[route[:line]] > 1 }
|
|
143
|
+
|
|
144
|
+
sorted.chunk_while {|a, b| b[:line] == a[:line] + 1 }.to_a
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
##============================================================##
|
|
148
|
+
## Check one block: compute the column of every segment,
|
|
149
|
+
## then flag each route whose gaps differ, correcting
|
|
150
|
+
## gap by gap.
|
|
151
|
+
##============================================================##
|
|
152
|
+
def check_group(group)
|
|
153
|
+
return if group.size < 2
|
|
154
|
+
|
|
155
|
+
keys = ordered_keys(group)
|
|
156
|
+
return if keys.nil?
|
|
157
|
+
|
|
158
|
+
place_segments(group, keys)
|
|
159
|
+
|
|
160
|
+
group.each do |route|
|
|
161
|
+
corrections = corrections_for(route)
|
|
162
|
+
next if corrections.empty?
|
|
163
|
+
|
|
164
|
+
add_offense(route[:node], :message => MSG) do |corrector|
|
|
165
|
+
corrections.each {|range, text| corrector.replace(range, text) }
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
##============================================================##
|
|
171
|
+
## The column of every segment of every route of the
|
|
172
|
+
## block: first `=>` in one column, then one column per
|
|
173
|
+
## option name, in the order computed for the block. The
|
|
174
|
+
## comma stays glued to the value before it, the spaces
|
|
175
|
+
## follow it.
|
|
176
|
+
##============================================================##
|
|
177
|
+
def place_segments(group, keys)
|
|
178
|
+
verb_width = group.map {|route| route[:node].method_name.length }.max
|
|
179
|
+
path_width = group.map {|route| segment(route, :path)[:range].size }.max
|
|
180
|
+
|
|
181
|
+
group.each do |route|
|
|
182
|
+
node = route[:node]
|
|
183
|
+
path_start = node.source_range.column + verb_width + 1
|
|
184
|
+
segment(route, :path)[:start] = path_start
|
|
185
|
+
|
|
186
|
+
target = segment(route, :target)
|
|
187
|
+
head_end =
|
|
188
|
+
if target
|
|
189
|
+
target[:start] = path_start + path_width + 4
|
|
190
|
+
target[:start] + target[:range].size
|
|
191
|
+
else
|
|
192
|
+
path_start + path_width
|
|
193
|
+
end
|
|
194
|
+
route[:head_end] = head_end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
starts = {}
|
|
198
|
+
column = group.map {|route| route[:head_end] }.max + 2
|
|
199
|
+
keys.each do |key|
|
|
200
|
+
starts[key] = column
|
|
201
|
+
followers = keys.drop(keys.index(key) + 1)
|
|
202
|
+
ends = group.filter_map do |route|
|
|
203
|
+
option = route[:segments].find {|seg| seg[:key] == key }
|
|
204
|
+
column + option[:range].size if option && (option_keys(route) & followers).any?
|
|
205
|
+
end
|
|
206
|
+
column = ends.max + 2 if ends.any?
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
group.each do |route|
|
|
210
|
+
route[:segments].each do |seg|
|
|
211
|
+
seg[:start] = starts[seg[:key]] if seg[:kind] == :option
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
##============================================================##
|
|
217
|
+
## The gaps of one route that do not match the computed
|
|
218
|
+
## columns, as [range, expected text] pairs. Ranges only
|
|
219
|
+
## ever span whitespace and the commas separating the
|
|
220
|
+
## segments, never a segment itself.
|
|
221
|
+
##============================================================##
|
|
222
|
+
def corrections_for(route)
|
|
223
|
+
node = route[:node]
|
|
224
|
+
selector = node.loc.selector
|
|
225
|
+
path = segment(route, :path)
|
|
226
|
+
corrections = []
|
|
227
|
+
|
|
228
|
+
if node.loc.begin
|
|
229
|
+
replace_gap(corrections, selector.end_pos, node.loc.begin.begin_pos, "")
|
|
230
|
+
replace_gap(corrections, node.loc.begin.end_pos, path[:range].begin_pos, "")
|
|
231
|
+
else
|
|
232
|
+
replace_gap(corrections, selector.end_pos, path[:range].begin_pos,
|
|
233
|
+
" " * (path[:start] - selector.column - selector.size))
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
previous = path
|
|
237
|
+
if (target = segment(route, :target))
|
|
238
|
+
operator = target[:pair].loc.operator
|
|
239
|
+
##============================================================##
|
|
240
|
+
## The `=>` sits 3 columns before the target (its 2
|
|
241
|
+
## chars plus the space after it); the path ends, in
|
|
242
|
+
## the aligned line, at its start plus its length.
|
|
243
|
+
##============================================================##
|
|
244
|
+
replace_gap(corrections, path[:range].end_pos, operator.begin_pos,
|
|
245
|
+
" " * ((target[:start] - 3) - (path[:start] + path[:range].size)))
|
|
246
|
+
replace_gap(corrections, operator.end_pos, target[:range].begin_pos, " ")
|
|
247
|
+
previous = target
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
route[:segments].select {|seg| seg[:kind] == :option }.each do |option|
|
|
251
|
+
prev_end = previous[:start] + previous[:range].size
|
|
252
|
+
replace_gap(corrections, previous[:range].end_pos, option[:range].begin_pos,
|
|
253
|
+
",#{" " * (option[:start] - prev_end - 1)}")
|
|
254
|
+
previous = option
|
|
255
|
+
end
|
|
256
|
+
corrections
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
##============================================================##
|
|
260
|
+
## Record a gap correction when the current text differs.
|
|
261
|
+
##============================================================##
|
|
262
|
+
def replace_gap(corrections, begin_pos, end_pos, expected)
|
|
263
|
+
range = Parser::Source::Range.new(processed_source.buffer, begin_pos, end_pos)
|
|
264
|
+
return if range.source == expected
|
|
265
|
+
|
|
266
|
+
corrections << [range, expected]
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def segment(route, kind)
|
|
270
|
+
route[:segments].find {|seg| seg[:kind] == kind }
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def option_keys(route)
|
|
274
|
+
route[:segments].filter_map {|seg| seg[:key] }
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
##============================================================##
|
|
278
|
+
## The order of the option columns: the first one
|
|
279
|
+
## compatible with the order every route gives its
|
|
280
|
+
## options, keeping first-encounter order on ties. Nil
|
|
281
|
+
## when two routes impose opposite orders.
|
|
282
|
+
##============================================================##
|
|
283
|
+
def ordered_keys(group)
|
|
284
|
+
keys = group.flat_map {|route| option_keys(route) }.uniq
|
|
285
|
+
predecessors = Hash.new {|hash, key| hash[key] = [] }
|
|
286
|
+
group.each do |route|
|
|
287
|
+
option_keys(route).each_cons(2) do |before, after|
|
|
288
|
+
predecessors[after] << before unless predecessors[after].include?(before)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
sorted = []
|
|
293
|
+
remaining = keys.dup
|
|
294
|
+
while remaining.any?
|
|
295
|
+
ready = remaining.select {|key| (predecessors[key] - sorted).empty? }
|
|
296
|
+
return if ready.empty?
|
|
297
|
+
|
|
298
|
+
sorted << ready.first
|
|
299
|
+
remaining.delete(ready.first)
|
|
300
|
+
end
|
|
301
|
+
sorted
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
data/linters/rubocop.yml
CHANGED
|
@@ -5,6 +5,7 @@ require:
|
|
|
5
5
|
- rubocop/cop/custom_cops/style/align_assignments
|
|
6
6
|
- rubocop/cop/custom_cops/style/inline_multiline_calls
|
|
7
7
|
- rubocop/cop/custom_cops/style/kwarg_priority_order
|
|
8
|
+
- rubocop/cop/custom_cops/style/align_routes
|
|
8
9
|
|
|
9
10
|
# Enable all RuboCop methods and turn caching on for large files
|
|
10
11
|
AllCops:
|
|
@@ -261,6 +262,9 @@ CustomCops/Style/KwargPriorityOrder:
|
|
|
261
262
|
- remote
|
|
262
263
|
- method
|
|
263
264
|
|
|
265
|
+
CustomCops/Style/AlignRoutes:
|
|
266
|
+
Enabled: true # Align the columns of consecutive routes in config/routes.rb and config/routes/*.rb
|
|
267
|
+
|
|
264
268
|
#################### GEM ###########################
|
|
265
269
|
Gemspec/RequireMFA:
|
|
266
270
|
Enabled: false # Don't require MFA to push a gem
|
data/package.json
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
],
|
|
8
8
|
"private": true,
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@babel/parser": "^8.0.
|
|
10
|
+
"@babel/parser": "^8.0.8",
|
|
11
11
|
"@eslint/js": "^10.0.1",
|
|
12
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
13
|
-
"@typescript-eslint/parser": "^8.
|
|
12
|
+
"@typescript-eslint/eslint-plugin": "^8.72.0",
|
|
13
|
+
"@typescript-eslint/parser": "^8.72.0",
|
|
14
14
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
15
15
|
"eslint": "^10.13.0",
|
|
16
16
|
"eslint-plugin-align-import": "^1.0.0",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: immosquare-cleaner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- immosquare
|
|
@@ -195,6 +195,7 @@ files:
|
|
|
195
195
|
- linters/prettier.yml
|
|
196
196
|
- linters/rubocop.yml
|
|
197
197
|
- linters/rubocop/cop/custom_cops/style/align_assignments.rb
|
|
198
|
+
- linters/rubocop/cop/custom_cops/style/align_routes.rb
|
|
198
199
|
- linters/rubocop/cop/custom_cops/style/comment_normalization.rb
|
|
199
200
|
- linters/rubocop/cop/custom_cops/style/font_awesome_normalization.rb
|
|
200
201
|
- linters/rubocop/cop/custom_cops/style/inline_multiline_calls.rb
|