immosquare-cleaner 0.1.84 → 0.1.86
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/custom_html_to_content_tag.rb +2 -1
- data/linters/normalize-comments.mjs +229 -0
- data/linters/rubocop/cop/custom_cops/style/comment_normalization.rb +13 -43
- data/package.json +1 -0
- 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: f420f9fecadfdb09097a28fb22b0b319fcc88d68f22aad1278d8dc9dc71669d9
|
|
4
|
+
data.tar.gz: 03f4d9c7033a464609021a3c87768b66b62a5614543a16e9c75a5c50f5b30023
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fb224bbda3fab24d76e9d3a65f301a084773b92f587aaf28ecd115abc67e5d9b8bd10d1bdd797aa8e9520f2ca3f3f1a51ec55d385afe8a330930bfd72a7ad136
|
|
7
|
+
data.tar.gz: 32a944821528ea234e8df348c43d17e3aa2b780270ec4fbf329753a6611cbda52d40a47e1fc8cba7dcf77a8f751656a0da90ee75fa1bc98f614604c0105d6696
|
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,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,26 +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
|
|
75
|
-
comment_text = comment.text.strip
|
|
76
|
-
next_comment_text = next_comment&.text&.strip
|
|
77
|
-
is_double_hash = comment_text.start_with?("##")
|
|
78
|
-
|
|
79
|
-
##============================================================##
|
|
80
|
-
## On vérifie si le prochain commentaire est sur la ligne suivante
|
|
81
|
-
## ET si les deux commentaires sont du même "type" (## ou #)
|
|
82
|
-
## Cela permet de ne pas fusionner les commentaires temporaires
|
|
83
|
-
## (# x = 1) avec les vrais commentaires (##)
|
|
84
|
-
##============================================================##
|
|
85
|
-
next_is_double_hash = next_comment_text&.start_with?("##")
|
|
86
|
-
same_type = is_double_hash == next_is_double_hash
|
|
64
|
+
next_comment = standalone_comments[index + 1]
|
|
87
65
|
next_line_contiguous = next_comment && next_comment.location.line == comment.location.line + 1
|
|
88
66
|
|
|
89
|
-
if next_line_contiguous
|
|
67
|
+
if next_line_contiguous
|
|
90
68
|
current_block << comment
|
|
91
69
|
else
|
|
92
70
|
current_block << comment
|
|
@@ -106,7 +84,6 @@ module RuboCop
|
|
|
106
84
|
|
|
107
85
|
body = block.map do |comment|
|
|
108
86
|
text = comment.text.to_s.strip
|
|
109
|
-
chars = text.chars.uniq
|
|
110
87
|
alphanumercic = text.match?(/[\p{L}0-9]/)
|
|
111
88
|
first_line_with_text_found = true if alphanumercic && !first_line_with_text_found
|
|
112
89
|
if text == BORDER_LINE
|
|
@@ -145,25 +122,18 @@ module RuboCop
|
|
|
145
122
|
|
|
146
123
|
##============================================================##
|
|
147
124
|
## Expliquons la regex :
|
|
125
|
+
## ##\s*#*\s*(?=[[:alnum:]])
|
|
126
|
+
## ---------
|
|
148
127
|
## ## : match littéralement "##"
|
|
149
|
-
##
|
|
150
|
-
##
|
|
151
|
-
##
|
|
152
|
-
##
|
|
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
|
|
153
132
|
##============================================================##
|
|
154
133
|
def cleaned_line(line)
|
|
155
|
-
if line.start_with?("## |")
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
line.gsub(/##\s*#*\s*(?=[[:alnum:]])/, "## ")
|
|
159
|
-
else
|
|
160
|
-
##============================================================##
|
|
161
|
-
## Pour une ligne commençant par # simple, on la convertit en ##
|
|
162
|
-
## On enlève d'abord le # initial et tous les espaces qui suivent
|
|
163
|
-
##============================================================##
|
|
164
|
-
cleaned = line.gsub(/^#\s*/, "")
|
|
165
|
-
"## #{cleaned}"
|
|
166
|
-
end
|
|
134
|
+
return line if line.start_with?("## |")
|
|
135
|
+
|
|
136
|
+
line.gsub(/##\s*#*\s*(?=[[:alnum:]])/, "## ")
|
|
167
137
|
end
|
|
168
138
|
|
|
169
139
|
def needs_correction?(block, correct_block)
|
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.86
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- immosquare
|
|
@@ -152,6 +152,7 @@ files:
|
|
|
152
152
|
- linters/erb_lint/custom_html_to_content_tag.rb
|
|
153
153
|
- linters/erb_lint/custom_single_line_if_modifier.rb
|
|
154
154
|
- linters/eslint.config.mjs
|
|
155
|
+
- linters/normalize-comments.mjs
|
|
155
156
|
- linters/prettier.yml
|
|
156
157
|
- linters/rubocop-3.4.1.yml
|
|
157
158
|
- linters/rubocop.yml
|