immosquare-cleaner 0.1.83 → 0.1.85
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/lib/immosquare-cleaner.rb +2 -1
- data/linters/erb-lint-3.4.1.yml +18 -0
- data/linters/erb_lint/custom_html_to_content_tag.rb +99 -12
- data/linters/normalize-comments.mjs +229 -0
- data/linters/rubocop/cop/custom_cops/style/comment_normalization.rb +14 -31
- data/linters/rubocop/cop/custom_cops/style/font_awesome_normalization.rb +25 -19
- data/linters/rubocop-3.4.1.yml +92 -0
- data/linters/rubocop.yml +63 -1
- data/package.json +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4da0616be6e3657c0023070c486b125edc9918f12debff664fab78cc7615d39c
|
|
4
|
+
data.tar.gz: 22b571ee9ba71ebd2d1cbce4f5a092e7fef94b4b2b37722719018fb4c231f950
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22aef01e31f21d0effe4604ecc3721ba780865271d5ebce3e9f33a5dc4282999b90512989db0342876ed1e39a061856a5d4c61be2e2b737ba93ff8a5106270e1
|
|
7
|
+
data.tar.gz: 71f305128320e353d98f56710c4cdc9be6965029f0972ed0639a01e4d542905f8556d178d0b8e07560c72259809f247b972f7cac32d1300e1464d5a761726702
|
data/lib/immosquare-cleaner.rb
CHANGED
|
@@ -168,7 +168,8 @@ module ImmosquareCleaner
|
|
|
168
168
|
File.write(temp_file_path, File.read(file_path))
|
|
169
169
|
cmds = []
|
|
170
170
|
cmds << "bundle exec erb_lint --config #{erblint_config_with_version_path} #{file_path} #{ImmosquareCleaner.configuration.erblint_options || "--autocorrect"}" if file_path.end_with?(".erb")
|
|
171
|
-
cmds << "bun
|
|
171
|
+
cmds << "bun #{gem_root}/linters/normalize-comments.mjs #{temp_file_path}"
|
|
172
|
+
cmds << "bun eslint --config #{gem_root}/linters/eslint.config.mjs #{temp_file_path} --fix"
|
|
172
173
|
|
|
173
174
|
launch_cmds(cmds)
|
|
174
175
|
File.normalize_last_line(temp_file_path)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
EnableDefaultLinters: true
|
|
3
|
+
linters:
|
|
4
|
+
NoJavascriptTagHelper:
|
|
5
|
+
enabled: false
|
|
6
|
+
SpaceInHtmlTag:
|
|
7
|
+
enabled: false
|
|
8
|
+
CustomSingleLineIfModifier:
|
|
9
|
+
enabled: true
|
|
10
|
+
CustomHtmlToContentTag:
|
|
11
|
+
enabled: true
|
|
12
|
+
Rubocop:
|
|
13
|
+
enabled: true
|
|
14
|
+
rubocop_config:
|
|
15
|
+
inherit_from:
|
|
16
|
+
- linters/rubocop-3.4.1.yml
|
|
17
|
+
Layout/TrailingWhitespace:
|
|
18
|
+
Enabled: false
|
|
@@ -26,7 +26,23 @@ module ERBLint
|
|
|
26
26
|
## Void elements that cannot have content (self-closing tags)
|
|
27
27
|
##============================================================##
|
|
28
28
|
VOID_ELEMENTS = [
|
|
29
|
-
"area",
|
|
29
|
+
"area",
|
|
30
|
+
"base",
|
|
31
|
+
"br",
|
|
32
|
+
"col",
|
|
33
|
+
"command",
|
|
34
|
+
"embed",
|
|
35
|
+
"hr",
|
|
36
|
+
"img",
|
|
37
|
+
"input",
|
|
38
|
+
"keygen",
|
|
39
|
+
"link",
|
|
40
|
+
"menuitem",
|
|
41
|
+
"meta",
|
|
42
|
+
"param",
|
|
43
|
+
"source",
|
|
44
|
+
"track",
|
|
45
|
+
"wbr"
|
|
30
46
|
].freeze
|
|
31
47
|
|
|
32
48
|
##============================================================##
|
|
@@ -44,7 +60,70 @@ module ERBLint
|
|
|
44
60
|
##============================================================##
|
|
45
61
|
EXCLUDED_METHODS = [
|
|
46
62
|
"render",
|
|
47
|
-
"content_tag"
|
|
63
|
+
"content_tag",
|
|
64
|
+
"image_tag"
|
|
65
|
+
].freeze
|
|
66
|
+
|
|
67
|
+
##============================================================##
|
|
68
|
+
## HTML tags that should not be converted to content_tag
|
|
69
|
+
## These tags are more readable as HTML (tables, etc.)
|
|
70
|
+
##============================================================##
|
|
71
|
+
EXCLUDED_TAGS = [
|
|
72
|
+
"th",
|
|
73
|
+
"td",
|
|
74
|
+
"tr",
|
|
75
|
+
"thead",
|
|
76
|
+
"tbody",
|
|
77
|
+
"tfoot",
|
|
78
|
+
"table",
|
|
79
|
+
"caption",
|
|
80
|
+
"colgroup"
|
|
81
|
+
].freeze
|
|
82
|
+
|
|
83
|
+
##============================================================##
|
|
84
|
+
## Form builder methods - if called on a receiver, skip conversion
|
|
85
|
+
## This detects form builders regardless of variable name (f, form, etc.)
|
|
86
|
+
## Example: <div><%= f.input(:name) %></div> should stay as-is
|
|
87
|
+
##============================================================##
|
|
88
|
+
FORM_BUILDER_METHODS = [
|
|
89
|
+
"input",
|
|
90
|
+
"label",
|
|
91
|
+
"text_field",
|
|
92
|
+
"text_area",
|
|
93
|
+
"password_field",
|
|
94
|
+
"hidden_field",
|
|
95
|
+
"file_field",
|
|
96
|
+
"check_box",
|
|
97
|
+
"radio_button",
|
|
98
|
+
"select",
|
|
99
|
+
"collection_select",
|
|
100
|
+
"collection_check_boxes",
|
|
101
|
+
"collection_radio_buttons",
|
|
102
|
+
"grouped_collection_select",
|
|
103
|
+
"date_select",
|
|
104
|
+
"time_select",
|
|
105
|
+
"datetime_select",
|
|
106
|
+
"date_field",
|
|
107
|
+
"time_field",
|
|
108
|
+
"datetime_field",
|
|
109
|
+
"datetime_local_field",
|
|
110
|
+
"month_field",
|
|
111
|
+
"week_field",
|
|
112
|
+
"url_field",
|
|
113
|
+
"email_field",
|
|
114
|
+
"number_field",
|
|
115
|
+
"range_field",
|
|
116
|
+
"search_field",
|
|
117
|
+
"telephone_field",
|
|
118
|
+
"phone_field",
|
|
119
|
+
"color_field",
|
|
120
|
+
"submit",
|
|
121
|
+
"button",
|
|
122
|
+
"association",
|
|
123
|
+
"input_field",
|
|
124
|
+
"error",
|
|
125
|
+
"hint",
|
|
126
|
+
"full_error"
|
|
48
127
|
].freeze
|
|
49
128
|
|
|
50
129
|
def run(processed_source)
|
|
@@ -61,6 +140,7 @@ module ERBLint
|
|
|
61
140
|
tag_name = extract_tag_name(child)
|
|
62
141
|
next if tag_name.nil?
|
|
63
142
|
next if VOID_ELEMENTS.include?(tag_name.downcase)
|
|
143
|
+
next if EXCLUDED_TAGS.include?(tag_name.downcase)
|
|
64
144
|
|
|
65
145
|
##============================================================##
|
|
66
146
|
## Check if next child is text containing only ERB output
|
|
@@ -165,23 +245,32 @@ module ERBLint
|
|
|
165
245
|
end
|
|
166
246
|
|
|
167
247
|
##============================================================##
|
|
168
|
-
## Check if the ERB code calls an excluded method
|
|
248
|
+
## Check if the ERB code calls an excluded method or form builder
|
|
169
249
|
## Uses Prism parser for proper Ruby AST analysis
|
|
170
250
|
##============================================================##
|
|
171
251
|
def excluded_method?(erb_code)
|
|
172
252
|
return false unless erb_code
|
|
173
253
|
|
|
174
|
-
|
|
175
|
-
return false unless
|
|
254
|
+
call_node = extract_call_node(erb_code)
|
|
255
|
+
return false unless call_node
|
|
256
|
+
|
|
257
|
+
method_name = call_node.name.to_s
|
|
258
|
+
return true if EXCLUDED_METHODS.include?(method_name)
|
|
259
|
+
|
|
260
|
+
##============================================================##
|
|
261
|
+
## If method is a form builder method called on a receiver,
|
|
262
|
+
## skip conversion (e.g., f.input, form.text_field, etc.)
|
|
263
|
+
##============================================================##
|
|
264
|
+
return true if call_node.receiver && FORM_BUILDER_METHODS.include?(method_name)
|
|
176
265
|
|
|
177
|
-
|
|
266
|
+
false
|
|
178
267
|
end
|
|
179
268
|
|
|
180
269
|
##============================================================##
|
|
181
|
-
## Extract the
|
|
270
|
+
## Extract the CallNode from Ruby code using Prism parser
|
|
182
271
|
## Handles both direct calls and calls with if/unless modifiers
|
|
183
272
|
##============================================================##
|
|
184
|
-
def
|
|
273
|
+
def extract_call_node(erb_code)
|
|
185
274
|
result = Prism.parse(erb_code)
|
|
186
275
|
return nil unless result.success?
|
|
187
276
|
|
|
@@ -190,13 +279,11 @@ module ERBLint
|
|
|
190
279
|
##============================================================##
|
|
191
280
|
## Handle if/unless modifiers: `render(...) if condition`
|
|
192
281
|
##============================================================##
|
|
193
|
-
if node.is_a?(Prism::IfNode) || node.is_a?(Prism::UnlessNode)
|
|
194
|
-
node = node.statements&.body&.first
|
|
195
|
-
end
|
|
282
|
+
node = node.statements&.body&.first if node.is_a?(Prism::IfNode) || node.is_a?(Prism::UnlessNode)
|
|
196
283
|
|
|
197
284
|
return nil unless node.is_a?(Prism::CallNode)
|
|
198
285
|
|
|
199
|
-
node
|
|
286
|
+
node
|
|
200
287
|
rescue StandardError
|
|
201
288
|
nil
|
|
202
289
|
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "fs"
|
|
2
|
+
import * as babelParser from "@babel/parser"
|
|
3
|
+
|
|
4
|
+
//============================================================//
|
|
5
|
+
// Constants
|
|
6
|
+
//============================================================//
|
|
7
|
+
const BORDER_LINE = "//" + "=".repeat(60) + "//"
|
|
8
|
+
const INSIDE_SEPARATOR = "// ---------"
|
|
9
|
+
|
|
10
|
+
//============================================================//
|
|
11
|
+
// Main function
|
|
12
|
+
//============================================================//
|
|
13
|
+
const normalizeComments = (filePath) => {
|
|
14
|
+
const code = readFileSync(filePath, "utf-8")
|
|
15
|
+
const lines = code.split("\n")
|
|
16
|
+
|
|
17
|
+
//============================================================//
|
|
18
|
+
// Parse the code with babel to get comment positions
|
|
19
|
+
//============================================================//
|
|
20
|
+
const ast = babelParser.parse(code, {
|
|
21
|
+
sourceType: "module",
|
|
22
|
+
plugins: ["typescript", "jsx"]
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
//============================================================//
|
|
26
|
+
// Get all comments from the AST
|
|
27
|
+
//============================================================//
|
|
28
|
+
const comments = ast.comments || []
|
|
29
|
+
|
|
30
|
+
//============================================================//
|
|
31
|
+
// Group consecutive standalone line comments
|
|
32
|
+
//============================================================//
|
|
33
|
+
const commentBlocks = groupConsecutiveComments(comments, lines)
|
|
34
|
+
|
|
35
|
+
//============================================================//
|
|
36
|
+
// Process blocks in reverse order to avoid line number shifts
|
|
37
|
+
//============================================================//
|
|
38
|
+
const blocksReversed = [...commentBlocks].reverse()
|
|
39
|
+
|
|
40
|
+
blocksReversed.forEach((block) => {
|
|
41
|
+
const normalized = normalizeCommentBlock(block, lines)
|
|
42
|
+
if (normalized) {
|
|
43
|
+
const startLine = block[0].loc.start.line - 1
|
|
44
|
+
const endLine = block[block.length - 1].loc.start.line - 1
|
|
45
|
+
|
|
46
|
+
//============================================================//
|
|
47
|
+
// Replace the lines in the original array
|
|
48
|
+
//============================================================//
|
|
49
|
+
lines.splice(startLine, endLine - startLine + 1, ...normalized)
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
writeFileSync(filePath, lines.join("\n"))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//============================================================//
|
|
57
|
+
// Group consecutive line comments together
|
|
58
|
+
// Only includes standalone comments (not end-of-line comments)
|
|
59
|
+
//============================================================//
|
|
60
|
+
const groupConsecutiveComments = (comments, originalLines) => {
|
|
61
|
+
const blocks = []
|
|
62
|
+
let currentBlock = []
|
|
63
|
+
let lastLine = -2
|
|
64
|
+
|
|
65
|
+
comments.forEach((comment) => {
|
|
66
|
+
//============================================================//
|
|
67
|
+
// Only process line comments (// style), not block comments (/* */)
|
|
68
|
+
//============================================================//
|
|
69
|
+
if (comment.type !== "CommentLine") {
|
|
70
|
+
if (currentBlock.length > 0) {
|
|
71
|
+
blocks.push(currentBlock)
|
|
72
|
+
currentBlock = []
|
|
73
|
+
}
|
|
74
|
+
lastLine = -2
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//============================================================//
|
|
79
|
+
// Skip triple-slash comments (/// for TypeScript docs)
|
|
80
|
+
//============================================================//
|
|
81
|
+
if (comment.value.startsWith("/")) {
|
|
82
|
+
if (currentBlock.length > 0) {
|
|
83
|
+
blocks.push(currentBlock)
|
|
84
|
+
currentBlock = []
|
|
85
|
+
}
|
|
86
|
+
lastLine = -2
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//============================================================//
|
|
91
|
+
// Check if this is a standalone comment (line starts with //)
|
|
92
|
+
// Skip end-of-line comments (e.g., const x = 1 // comment)
|
|
93
|
+
//============================================================//
|
|
94
|
+
const lineContent = originalLines[comment.loc.start.line - 1]
|
|
95
|
+
const isStandalone = lineContent.trim().startsWith("//")
|
|
96
|
+
|
|
97
|
+
if (!isStandalone) {
|
|
98
|
+
if (currentBlock.length > 0) {
|
|
99
|
+
blocks.push(currentBlock)
|
|
100
|
+
currentBlock = []
|
|
101
|
+
}
|
|
102
|
+
lastLine = -2
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const currentLine = comment.loc.start.line
|
|
107
|
+
|
|
108
|
+
if (currentLine === lastLine + 1) {
|
|
109
|
+
currentBlock.push(comment)
|
|
110
|
+
} else {
|
|
111
|
+
if (currentBlock.length > 0) {
|
|
112
|
+
blocks.push(currentBlock)
|
|
113
|
+
}
|
|
114
|
+
currentBlock = [comment]
|
|
115
|
+
}
|
|
116
|
+
lastLine = currentLine
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
if (currentBlock.length > 0) {
|
|
120
|
+
blocks.push(currentBlock)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return blocks
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
//============================================================//
|
|
127
|
+
// Normalize a block of comments
|
|
128
|
+
// Returns an array of new lines, or null if no change needed
|
|
129
|
+
//============================================================//
|
|
130
|
+
const normalizeCommentBlock = (block, originalLines) => {
|
|
131
|
+
if (block.length === 0) return null
|
|
132
|
+
|
|
133
|
+
//============================================================//
|
|
134
|
+
// Get the indentation from the first comment
|
|
135
|
+
//============================================================//
|
|
136
|
+
const firstLine = originalLines[block[0].loc.start.line - 1]
|
|
137
|
+
const indent = firstLine.match(/^(\s*)/)[1]
|
|
138
|
+
|
|
139
|
+
//============================================================//
|
|
140
|
+
// Extract the text content from each comment
|
|
141
|
+
//============================================================//
|
|
142
|
+
const bodyLines = []
|
|
143
|
+
let firstLineWithTextFound = false
|
|
144
|
+
|
|
145
|
+
block.forEach((comment) => {
|
|
146
|
+
const text = comment.value.trim()
|
|
147
|
+
const hasAlphaNum = /[\p{L}0-9]/u.test(text)
|
|
148
|
+
|
|
149
|
+
if (isBorderLine(text)) {
|
|
150
|
+
return
|
|
151
|
+
} else if (isSeparatorLine(text)) {
|
|
152
|
+
if (firstLineWithTextFound) {
|
|
153
|
+
bodyLines.push(INSIDE_SEPARATOR)
|
|
154
|
+
}
|
|
155
|
+
} else if (hasAlphaNum) {
|
|
156
|
+
firstLineWithTextFound = true
|
|
157
|
+
bodyLines.push("// " + cleanedLine(text))
|
|
158
|
+
} else if (firstLineWithTextFound && text === "") {
|
|
159
|
+
bodyLines.push("//")
|
|
160
|
+
}
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
//============================================================//
|
|
164
|
+
// If block is empty, add a placeholder
|
|
165
|
+
//============================================================//
|
|
166
|
+
if (bodyLines.length === 0) {
|
|
167
|
+
bodyLines.push("// ...")
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//============================================================//
|
|
171
|
+
// Build the new lines with borders
|
|
172
|
+
//============================================================//
|
|
173
|
+
const result = []
|
|
174
|
+
result.push(indent + BORDER_LINE)
|
|
175
|
+
bodyLines.forEach((line) => {
|
|
176
|
+
result.push(indent + line)
|
|
177
|
+
})
|
|
178
|
+
result.push(indent + BORDER_LINE)
|
|
179
|
+
|
|
180
|
+
return result
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//============================================================//
|
|
184
|
+
// Check if a line is a border (long line of = or #)
|
|
185
|
+
//============================================================//
|
|
186
|
+
const isBorderLine = (text) => {
|
|
187
|
+
const cleaned = text.replace(/[/=\-\s#]/g, "")
|
|
188
|
+
const hasEquals = text.includes("=")
|
|
189
|
+
const longEnough = text.length > 20
|
|
190
|
+
|
|
191
|
+
return cleaned === "" && hasEquals && longEnough
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
//============================================================//
|
|
195
|
+
// Check if a line is an internal separator (---------)
|
|
196
|
+
//============================================================//
|
|
197
|
+
const isSeparatorLine = (text) => {
|
|
198
|
+
const cleaned = text.replace(/[-\s]/g, "")
|
|
199
|
+
return cleaned === "" && text.length >= 5
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
//============================================================//
|
|
203
|
+
// Clean a comment line
|
|
204
|
+
//============================================================//
|
|
205
|
+
const cleanedLine = (text) => {
|
|
206
|
+
//============================================================//
|
|
207
|
+
// Preserve lines with | (markdown tables)
|
|
208
|
+
//============================================================//
|
|
209
|
+
if (text.startsWith("|")) {
|
|
210
|
+
return text
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
//============================================================//
|
|
214
|
+
// Remove leading special characters and normalize
|
|
215
|
+
//============================================================//
|
|
216
|
+
return text.replace(/^[/=\s]*(?=[\p{L}0-9])/u, "").trim()
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//============================================================//
|
|
220
|
+
// Run the script
|
|
221
|
+
//============================================================//
|
|
222
|
+
const filePath = process.argv[2]
|
|
223
|
+
|
|
224
|
+
if (!filePath) {
|
|
225
|
+
console.error("Usage: bun normalize-comments.mjs <file>")
|
|
226
|
+
process.exit(1)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
normalizeComments(filePath)
|
|
@@ -18,16 +18,6 @@ module RuboCop
|
|
|
18
18
|
|
|
19
19
|
comment_blocks = find_comment_blocks(processed_source.comments)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
##============================================================##
|
|
23
|
-
## On ne veut traiter que les blocs de commentaires où la première ligne
|
|
24
|
-
## du bloc commence par ##
|
|
25
|
-
##============================================================##
|
|
26
|
-
comment_blocks = comment_blocks.select do |block|
|
|
27
|
-
block.first.text.strip.start_with?("##")
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
|
|
31
21
|
comment_blocks.each do |block|
|
|
32
22
|
correct_block = normalize_comment_block(block)
|
|
33
23
|
|
|
@@ -59,7 +49,7 @@ module RuboCop
|
|
|
59
49
|
|
|
60
50
|
|
|
61
51
|
##============================================================##
|
|
62
|
-
## On ne veut traiter que les commentaires qui ne sont pas
|
|
52
|
+
## On ne veut traiter que les commentaires ## qui ne sont pas
|
|
63
53
|
## des commentaires de fin de ligne ruby
|
|
64
54
|
##============================================================##
|
|
65
55
|
def find_comment_blocks(comments)
|
|
@@ -67,13 +57,14 @@ module RuboCop
|
|
|
67
57
|
current_block = []
|
|
68
58
|
standalone_comments = comments.select do |comment|
|
|
69
59
|
line = processed_source.lines[comment.location.line - 1]
|
|
70
|
-
line.strip.start_with?("
|
|
60
|
+
line.strip.start_with?("##")
|
|
71
61
|
end
|
|
72
62
|
|
|
73
63
|
standalone_comments.each_with_index do |comment, index|
|
|
74
|
-
next_comment
|
|
64
|
+
next_comment = standalone_comments[index + 1]
|
|
65
|
+
next_line_contiguous = next_comment && next_comment.location.line == comment.location.line + 1
|
|
75
66
|
|
|
76
|
-
if
|
|
67
|
+
if next_line_contiguous
|
|
77
68
|
current_block << comment
|
|
78
69
|
else
|
|
79
70
|
current_block << comment
|
|
@@ -93,7 +84,6 @@ module RuboCop
|
|
|
93
84
|
|
|
94
85
|
body = block.map do |comment|
|
|
95
86
|
text = comment.text.to_s.strip
|
|
96
|
-
chars = text.chars.uniq
|
|
97
87
|
alphanumercic = text.match?(/[\p{L}0-9]/)
|
|
98
88
|
first_line_with_text_found = true if alphanumercic && !first_line_with_text_found
|
|
99
89
|
if text == BORDER_LINE
|
|
@@ -132,25 +122,18 @@ module RuboCop
|
|
|
132
122
|
|
|
133
123
|
##============================================================##
|
|
134
124
|
## Expliquons la regex :
|
|
125
|
+
## ##\s*#*\s*(?=[[:alnum:]])
|
|
126
|
+
## ---------
|
|
135
127
|
## ## : match littéralement "##"
|
|
136
|
-
##
|
|
137
|
-
##
|
|
138
|
-
##
|
|
139
|
-
##
|
|
128
|
+
## \s* : match 0 ou plusieurs espaces
|
|
129
|
+
## #* : match 0 ou plusieurs #
|
|
130
|
+
## \s* : match encore 0 ou plusieurs espaces
|
|
131
|
+
## (?=[[:alnum:]]) : lookahead positif qui vérifie qu'on a un caractère alphanumérique après
|
|
140
132
|
##============================================================##
|
|
141
133
|
def cleaned_line(line)
|
|
142
|
-
if line.start_with?("## |")
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
line.gsub(/##\s*#*\s*(?=[[:alnum:]])/, "## ")
|
|
146
|
-
else
|
|
147
|
-
##============================================================##
|
|
148
|
-
## Pour une ligne commençant par # simple, on la convertit en ##
|
|
149
|
-
## On enlève d'abord le # initial et tous les espaces qui suivent
|
|
150
|
-
##============================================================##
|
|
151
|
-
cleaned = line.gsub(/^#\s*/, "")
|
|
152
|
-
"## #{cleaned}"
|
|
153
|
-
end
|
|
134
|
+
return line if line.start_with?("## |")
|
|
135
|
+
|
|
136
|
+
line.gsub(/##\s*#*\s*(?=[[:alnum:]])/, "## ")
|
|
154
137
|
end
|
|
155
138
|
|
|
156
139
|
def needs_correction?(block, correct_block)
|
|
@@ -2,28 +2,32 @@ module RuboCop
|
|
|
2
2
|
module Cop
|
|
3
3
|
module CustomCops
|
|
4
4
|
module Style
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
##============================================================##
|
|
6
|
+
## This cop identifies usage of short Font Awesome prefix styles (e.g., 'fas', 'far', 'fal')
|
|
7
|
+
## and suggests replacing them with the long version style (which is the standard since v6).
|
|
8
|
+
##
|
|
9
|
+
## Doc : https://docs.fontawesome.com/web/setup/upgrade/whats-changed#full-style-names
|
|
10
|
+
##
|
|
11
|
+
## @example
|
|
12
|
+
## bad
|
|
13
|
+
## font_awesome_icon("fas fa-user")
|
|
14
|
+
## font_awesome_icon("far fa-circle-info")
|
|
15
|
+
## font_awesome_icon("fal fa-bell")
|
|
16
|
+
##
|
|
17
|
+
## good
|
|
18
|
+
## font_awesome_icon("fa-solid fa-user")
|
|
19
|
+
## font_awesome_icon("fa-regular fa-circle-info")
|
|
20
|
+
## font_awesome_icon("fa-light fa-bell")
|
|
21
|
+
##============================================================##
|
|
20
22
|
class FontAwesomeNormalization < RuboCop::Cop::Base
|
|
21
23
|
|
|
22
24
|
extend AutoCorrector
|
|
23
25
|
|
|
24
26
|
MSG = "Use long version Font Awesome style prefix instead of short version.".freeze
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
##============================================================##
|
|
29
|
+
## Mapping from short prefixes to long prefixes
|
|
30
|
+
##============================================================##
|
|
27
31
|
FA_PREFIX_MAP = {
|
|
28
32
|
"fas" => "fa-solid",
|
|
29
33
|
"far" => "fa-regular",
|
|
@@ -44,11 +48,11 @@ module RuboCop
|
|
|
44
48
|
"fab" => "fa-brands"
|
|
45
49
|
}.freeze
|
|
46
50
|
|
|
47
|
-
def_node_matcher
|
|
51
|
+
def_node_matcher(:font_awesome_icon_call?, <<~PATTERN)
|
|
48
52
|
(send nil? :font_awesome_icon $...)
|
|
49
53
|
PATTERN
|
|
50
54
|
|
|
51
|
-
def_node_matcher
|
|
55
|
+
def_node_matcher(:string_argument?, <<~PATTERN)
|
|
52
56
|
(str $_)
|
|
53
57
|
PATTERN
|
|
54
58
|
|
|
@@ -93,7 +97,9 @@ module RuboCop
|
|
|
93
97
|
corrector.replace(node, replacement)
|
|
94
98
|
end
|
|
95
99
|
|
|
96
|
-
|
|
100
|
+
##============================================================##
|
|
101
|
+
## Once we've found a match, no need to check other prefixes
|
|
102
|
+
##============================================================##
|
|
97
103
|
break
|
|
98
104
|
end
|
|
99
105
|
end
|
data/linters/rubocop-3.4.1.yml
CHANGED
|
@@ -107,12 +107,104 @@ Style/MethodCallWithArgsParentheses:
|
|
|
107
107
|
- raise
|
|
108
108
|
- fail
|
|
109
109
|
- gem
|
|
110
|
+
- group
|
|
110
111
|
- source
|
|
111
112
|
- ruby
|
|
112
113
|
- desc
|
|
113
114
|
- task
|
|
114
115
|
- namespace
|
|
115
116
|
- yield
|
|
117
|
+
- install_plugin
|
|
118
|
+
- before_action
|
|
119
|
+
- after_action
|
|
120
|
+
- skip_before_action
|
|
121
|
+
- around_action
|
|
122
|
+
- before_filter
|
|
123
|
+
- after_filter
|
|
124
|
+
- around_filter
|
|
125
|
+
- validates
|
|
126
|
+
- validates_presence_of
|
|
127
|
+
- validates_uniqueness_of
|
|
128
|
+
- validates_length_of
|
|
129
|
+
- validates_format_of
|
|
130
|
+
- validates_numericality_of
|
|
131
|
+
- validates_inclusion_of
|
|
132
|
+
- validates_exclusion_of
|
|
133
|
+
- validates_confirmation_of
|
|
134
|
+
- validates_acceptance_of
|
|
135
|
+
- validates_absence_of
|
|
136
|
+
- validates_associated
|
|
137
|
+
- validates_each
|
|
138
|
+
- validates_with
|
|
139
|
+
- validates_with_method
|
|
140
|
+
- validates_with_method_name
|
|
141
|
+
- validates_with_method_name_and_arguments
|
|
142
|
+
- validates_with_method_name_and_arguments_and_options
|
|
143
|
+
- belongs_to
|
|
144
|
+
- has_many
|
|
145
|
+
- has_one
|
|
146
|
+
- has_many_through
|
|
147
|
+
- has_one_through
|
|
148
|
+
- has_many_and_belongs_to_many
|
|
149
|
+
- has_many_and_belongs_to_many_through
|
|
150
|
+
- has_many_and_belongs_to_many_through_through
|
|
151
|
+
- has_many_and_belongs_to_many_through_through_through
|
|
152
|
+
- has_many_and_belongs_to_many_through_through_through_through
|
|
153
|
+
- before_validation
|
|
154
|
+
- after_validation
|
|
155
|
+
- around_validation
|
|
156
|
+
- before_save
|
|
157
|
+
- after_save
|
|
158
|
+
- around_save
|
|
159
|
+
- before_create
|
|
160
|
+
- after_create
|
|
161
|
+
- around_create
|
|
162
|
+
- before_update
|
|
163
|
+
- after_update
|
|
164
|
+
- around_update
|
|
165
|
+
- before_destroy
|
|
166
|
+
- after_destroy
|
|
167
|
+
- around_destroy
|
|
168
|
+
- before_commit
|
|
169
|
+
- after_commit
|
|
170
|
+
- around_commit
|
|
171
|
+
- before_validation
|
|
172
|
+
- after_validation
|
|
173
|
+
- around_validation
|
|
174
|
+
- before_save
|
|
175
|
+
- after_save
|
|
176
|
+
- around_save
|
|
177
|
+
- before_create
|
|
178
|
+
- after_create
|
|
179
|
+
- around_create
|
|
180
|
+
- before_update
|
|
181
|
+
- after_update
|
|
182
|
+
- around_update
|
|
183
|
+
- before_destroy
|
|
184
|
+
- after_destroy
|
|
185
|
+
- around_destroy
|
|
186
|
+
- before_commit
|
|
187
|
+
- after_commit
|
|
188
|
+
- around_commit
|
|
189
|
+
- before_validation
|
|
190
|
+
- after_validation
|
|
191
|
+
- around_validation
|
|
192
|
+
- before_save
|
|
193
|
+
- after_save
|
|
194
|
+
- around_save
|
|
195
|
+
- before_create
|
|
196
|
+
- after_create
|
|
197
|
+
- around_create
|
|
198
|
+
- before_update
|
|
199
|
+
- after_update
|
|
200
|
+
- around_update
|
|
201
|
+
- before_destroy
|
|
202
|
+
- after_destroy
|
|
203
|
+
- around_destroy
|
|
204
|
+
- before_commit
|
|
205
|
+
- after_commit
|
|
206
|
+
- around_commit
|
|
207
|
+
- serialize
|
|
116
208
|
CustomCops/Style/CommentNormalization:
|
|
117
209
|
Enabled: true
|
|
118
210
|
CustomCops/Style/FontAwesomeNormalization:
|
data/linters/rubocop.yml
CHANGED
|
@@ -111,6 +111,7 @@ Style/MethodCallWithArgsParentheses:
|
|
|
111
111
|
EnforcedStyle: require_parentheses
|
|
112
112
|
IgnoreMacros: false
|
|
113
113
|
AllowedMethods:
|
|
114
|
+
## Ruby core
|
|
114
115
|
- require
|
|
115
116
|
- require_relative
|
|
116
117
|
- include
|
|
@@ -118,13 +119,74 @@ Style/MethodCallWithArgsParentheses:
|
|
|
118
119
|
- prepend
|
|
119
120
|
- raise
|
|
120
121
|
- fail
|
|
122
|
+
- yield
|
|
123
|
+
- attr_accessor
|
|
124
|
+
- attr_reader
|
|
125
|
+
- attr_writer
|
|
126
|
+
## Bundler / Gemfile
|
|
121
127
|
- gem
|
|
128
|
+
- group
|
|
122
129
|
- source
|
|
123
130
|
- ruby
|
|
131
|
+
- install_plugin
|
|
132
|
+
## Rake
|
|
124
133
|
- desc
|
|
125
134
|
- task
|
|
126
135
|
- namespace
|
|
127
|
-
|
|
136
|
+
## Rails Controller
|
|
137
|
+
- before_action
|
|
138
|
+
- after_action
|
|
139
|
+
- around_action
|
|
140
|
+
- skip_before_action
|
|
141
|
+
- prepend_before_action
|
|
142
|
+
- append_before_action
|
|
143
|
+
- helper_method
|
|
144
|
+
- layout
|
|
145
|
+
- rescue_from
|
|
146
|
+
## Rails Model - Associations
|
|
147
|
+
- belongs_to
|
|
148
|
+
- has_many
|
|
149
|
+
- has_one
|
|
150
|
+
- has_and_belongs_to_many
|
|
151
|
+
## Rails Model - Validations
|
|
152
|
+
- validates
|
|
153
|
+
- validate
|
|
154
|
+
- validates_presence_of
|
|
155
|
+
- validates_uniqueness_of
|
|
156
|
+
- validates_length_of
|
|
157
|
+
- validates_format_of
|
|
158
|
+
- validates_numericality_of
|
|
159
|
+
- validates_inclusion_of
|
|
160
|
+
- validates_exclusion_of
|
|
161
|
+
- validates_confirmation_of
|
|
162
|
+
- validates_acceptance_of
|
|
163
|
+
- validates_absence_of
|
|
164
|
+
- validates_associated
|
|
165
|
+
- validates_each
|
|
166
|
+
- validates_with
|
|
167
|
+
## Rails Model - Callbacks
|
|
168
|
+
- after_initialize
|
|
169
|
+
- after_find
|
|
170
|
+
- before_validation
|
|
171
|
+
- after_validation
|
|
172
|
+
- before_save
|
|
173
|
+
- after_save
|
|
174
|
+
- around_save
|
|
175
|
+
- before_create
|
|
176
|
+
- after_create
|
|
177
|
+
- around_create
|
|
178
|
+
- before_update
|
|
179
|
+
- after_update
|
|
180
|
+
- around_update
|
|
181
|
+
- before_destroy
|
|
182
|
+
- after_destroy
|
|
183
|
+
- around_destroy
|
|
184
|
+
- after_touch
|
|
185
|
+
- after_commit
|
|
186
|
+
- after_rollback
|
|
187
|
+
## Rails Model - Other
|
|
188
|
+
- delegate
|
|
189
|
+
- enum
|
|
128
190
|
|
|
129
191
|
#################### CUSTOMS ###########################
|
|
130
192
|
CustomCops/Style/CommentNormalization:
|
data/package.json
CHANGED
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: 0.1.
|
|
4
|
+
version: 0.1.85
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- immosquare
|
|
@@ -147,10 +147,12 @@ files:
|
|
|
147
147
|
- lib/immosquare-cleaner/railtie.rb
|
|
148
148
|
- lib/immosquare-cleaner/version.rb
|
|
149
149
|
- lib/tasks/immosquare_cleaner.rake
|
|
150
|
+
- linters/erb-lint-3.4.1.yml
|
|
150
151
|
- linters/erb-lint.yml
|
|
151
152
|
- linters/erb_lint/custom_html_to_content_tag.rb
|
|
152
153
|
- linters/erb_lint/custom_single_line_if_modifier.rb
|
|
153
154
|
- linters/eslint.config.mjs
|
|
155
|
+
- linters/normalize-comments.mjs
|
|
154
156
|
- linters/prettier.yml
|
|
155
157
|
- linters/rubocop-3.4.1.yml
|
|
156
158
|
- linters/rubocop.yml
|