lintcn 0.6.0 → 0.7.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.
package/src/discover.ts CHANGED
@@ -8,10 +8,17 @@ import path from 'node:path'
8
8
  export interface RuleMetadata {
9
9
  /** kebab-case rule name from // lintcn:name or derived from folder name */
10
10
  name: string
11
+ /** runtime rule name parsed from Go `rule.Rule{Name: "..."}`. This is
12
+ * the name tsgolint uses in diagnostics and must match --warn flags.
13
+ * Falls back to `name` if the Go Name field can't be parsed. */
14
+ goRuleName: string
11
15
  /** one-line description from // lintcn:description */
12
16
  description: string
13
17
  /** original source URL from // lintcn:source */
14
18
  source: string
19
+ /** severity from // lintcn:severity — 'error' (default) or 'warn'.
20
+ * Warnings are displayed with yellow styling and don't cause exit code 1. */
21
+ severity: 'error' | 'warn'
15
22
  /** exported Go variable name like NoFloatingPromisesRule */
16
23
  varName: string
17
24
  /** Go package name (= subfolder name, e.g. no_floating_promises) */
@@ -22,6 +29,12 @@ export interface RuleMetadata {
22
29
  // and optional import alias (e.g. `r.Rule{` if imported as `r "...rule"`)
23
30
  const RULE_VAR_RE = /^\s*var\s+(\w+)\s*=\s*\w*\.?Rule\s*\{/m
24
31
  const METADATA_RE = /^\/\/\s*lintcn:(\w+)\s+(.+)$/gm
32
+ // buildGoRuleNameRe creates a regex scoped to a specific rule variable's
33
+ // struct literal, e.g. `var FooRule = rule.Rule{ ... Name: "foo" ... }`.
34
+ // This avoids matching a Name field in an unrelated struct earlier in the file.
35
+ function buildGoRuleNameRe(varName: string): RegExp {
36
+ return new RegExp(`var\\s+${varName}\\s*=\\s*\\w*\\.?Rule\\s*\\{[\\s\\S]*?Name:\\s*"([^"]+)"`)
37
+ }
25
38
 
26
39
  export function parseMetadata(content: string): Record<string, string> {
27
40
  const meta: Record<string, string> = {}
@@ -36,6 +49,13 @@ export function parseRuleVar(content: string): string | undefined {
36
49
  return match?.[1]
37
50
  }
38
51
 
52
+ /** Extract the Name field from a specific rule.Rule variable's struct literal.
53
+ * Scoped to varName to avoid matching Name fields in unrelated structs. */
54
+ export function parseGoRuleName(content: string, varName: string): string | undefined {
55
+ const match = content.match(buildGoRuleNameRe(varName))
56
+ return match?.[1]
57
+ }
58
+
39
59
  export function discoverRules(lintcnDir: string): RuleMetadata[] {
40
60
  if (!fs.existsSync(lintcnDir)) {
41
61
  return []
@@ -73,10 +93,16 @@ export function discoverRules(lintcnDir: string): RuleMetadata[] {
73
93
 
74
94
  const meta = parseMetadata(content)
75
95
 
96
+ const severity = meta.severity === 'warn' ? 'warn' as const : 'error' as const
97
+ const displayName = meta.name || entry.name.replace(/_/g, '-')
98
+ const goRuleName = parseGoRuleName(content, varName) || displayName
99
+
76
100
  rules.push({
77
- name: meta.name || entry.name.replace(/_/g, '-'),
78
- description: meta.description || '',
79
- source: meta.source || '',
101
+ name: displayName,
102
+ goRuleName,
103
+ description: meta.description,
104
+ source: meta.source,
105
+ severity,
80
106
  varName,
81
107
  packageName: entry.name,
82
108
  })