Skip to content

Commit 5ebeefe

Browse files
committed
refactor
1 parent abd03ec commit 5ebeefe

File tree

3 files changed

+71
-124
lines changed

3 files changed

+71
-124
lines changed

cmd/init.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ func createToolFileConfigurations(tool domain.Tool, patternConfiguration []domai
347347
}
348348

349349
func createPMDConfigFile(config []domain.PatternConfiguration, toolsConfigDir string) error {
350-
pmdConfigurationString := tools.CreatePmdConfig(config)
350+
pmdConfigurationString := tools.CreatePmd6Config(config)
351351
return os.WriteFile(filepath.Join(toolsConfigDir, "ruleset.xml"), []byte(pmdConfigurationString), utils.DefaultFilePerms)
352352
}
353353

tools/pmdConfigCreator.go

Lines changed: 63 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ import (
88
"strings"
99
)
1010

11-
//go:embed pmd/default-ruleset.xml
12-
var defaultPMDRuleset string
13-
1411
// Parameter represents a rule parameter
1512
type Parameter struct {
1613
Name string
@@ -33,9 +30,14 @@ type RuleSet struct {
3330
}
3431

3532
// DeprecatedReferences maps deprecated pattern IDs to their new versions
36-
var DeprecatedReferences = map[string]string{
37-
// Add deprecated pattern mappings here
38-
// Example: "rulesets_java_design_ExcessiveClassLength": "category_java_design_ExcessiveClassLength",
33+
var DeprecatedReferences = map[string]string{}
34+
35+
func CreatePmd6Config(configuration []domain.PatternConfiguration) string {
36+
return createPmdConfigGeneric(configuration, pmd6Header, convertPatternIDToPMD, false)
37+
}
38+
39+
func CreatePmd7Config(configuration []domain.PatternConfiguration) string {
40+
return createPmdConfigGeneric(configuration, pmd7Header, convertPatternIDToPMD, true)
3941
}
4042

4143
// prefixPatternID adds the appropriate prefix to a pattern ID
@@ -59,128 +61,74 @@ func prefixPatternID(patternID string) string {
5961
}
6062
}
6163

62-
// convertPatternIDToPMD converts a Codacy pattern ID to PMD format
63-
func convertPatternIDToPMD(patternID string) (string, error) {
64-
// Check if this is a deprecated pattern
64+
func convertPatternIDToPMD(patternID string, isPmd7 bool) (string, error) {
65+
// Normalize deprecated patterns
6566
if newID, ok := DeprecatedReferences[patternID]; ok {
6667
patternID = newID
6768
}
6869

69-
// Handle both formats:
70-
// 1. "java/design/NPathComplexity"
71-
// 2. "PMD_category_java_design_NPathComplexity"
72-
// 3. "PMD_category_apex_security_ApexSharingViolations"
73-
// 4. "PMD_category_plsql_errorprone_TO_TIMESTAMPWithoutDateFormat"
70+
// Normalize version-specific prefixes
71+
if isPmd7 {
72+
patternID = strings.TrimPrefix(patternID, "PMD7_")
73+
} else {
74+
patternID = strings.TrimPrefix(patternID, "PMD_")
75+
}
7476

7577
var parts []string
78+
79+
// Handle different ID formats
7680
if strings.Contains(patternID, "/") {
81+
// Already in path form: lang/category/rule
7782
parts = strings.Split(patternID, "/")
83+
if len(parts) < 3 {
84+
return "", fmt.Errorf("invalid PMD path pattern ID: %s", patternID)
85+
}
86+
lang, category := parts[0], parts[1]
87+
rule := strings.Join(parts[2:], "/")
88+
return fmt.Sprintf("rulesets/%s/%s.xml/%s", lang, category, rule), nil
89+
}
90+
91+
// Handle underscore-based Codacy pattern IDs
92+
parts = strings.Split(patternID, "_")
93+
if isPmd7 {
94+
// Expect category_lang_category_rule
95+
if len(parts) < 4 || parts[0] != "category" {
96+
return "", fmt.Errorf("invalid PMD 7 pattern ID: %s", patternID)
97+
}
98+
lang := parts[1]
99+
category := parts[2]
100+
rule := strings.Join(parts[3:], "_")
101+
return fmt.Sprintf("category/%s/%s.xml/%s", lang, category, rule), nil
78102
} else {
79-
// Remove PMD_ prefix if present
80-
id := strings.TrimPrefix(patternID, "PMD_")
81-
// Split by underscore and remove "category" if present
82-
parts = strings.Split(id, "_")
103+
// PMD 6: expect lang_category_rule
83104
if parts[0] == "category" {
84105
parts = parts[1:]
85106
}
86-
}
87-
88-
if len(parts) < 3 {
89-
return "", fmt.Errorf("invalid pattern ID format: %s", patternID)
90-
}
91-
92-
// Extract language, category, and rule
93-
language := parts[0] // java, apex, etc.
94-
category := parts[1] // design, security, etc.
95-
rule := parts[2] // rule name
96-
97-
// If there are more parts, combine them with the rule name
98-
if len(parts) > 3 {
99-
rule = strings.Join(parts[2:], "_")
100-
}
101-
102-
return fmt.Sprintf("category/%s/%s.xml/%s", language, category, rule), nil
103-
}
104-
105-
// convertPatternIDToPMD7 converts a Codacy pattern ID to PMD 7 format
106-
func convertPatternIDToPMD7(patternID string) (string, error) {
107-
// Strip deprecated mappings
108-
if newID, ok := DeprecatedReferences[patternID]; ok {
109-
patternID = newID
110-
}
111-
112-
// Remove "PMD7_" prefix if present
113-
patternID = strings.TrimPrefix(patternID, "PMD7_")
114-
115-
// Now handle patternIDs like: category_java_bestpractices_UnusedLocalVariable
116-
parts := strings.Split(patternID, "_")
117-
118-
if len(parts) < 4 || parts[0] != "category" {
119-
return "", fmt.Errorf("invalid PMD 7 pattern ID: %s", patternID)
120-
}
121-
122-
lang := parts[1]
123-
category := parts[2]
124-
rule := strings.Join(parts[3:], "_")
125-
126-
return fmt.Sprintf("category/%s/%s.xml/%s", lang, category, rule), nil
127-
}
128-
129-
// generateRuleXML generates XML for a single rule
130-
func generateRuleXML(rule Rule) (string, error) {
131-
pmdRef, err := convertPatternIDToPMD(rule.PatternID)
132-
if err != nil {
133-
return "", err
134-
}
135-
136-
if len(rule.Parameters) == 0 {
137-
return fmt.Sprintf(` <rule ref="%s"/>`, pmdRef), nil
138-
}
139-
140-
// Generate rule with parameters
141-
var params strings.Builder
142-
for _, param := range rule.Parameters {
143-
// Skip enabled and version parameters, but include all others
144-
if param.Name != "enabled" && param.Name != "version" {
145-
params.WriteString(fmt.Sprintf(`
146-
<property name="%s" value="%s"/>`, param.Name, param.Value))
107+
if len(parts) < 3 {
108+
return "", fmt.Errorf("invalid PMD 6 pattern ID: %s", patternID)
147109
}
110+
lang := parts[0]
111+
category := parts[1]
112+
rule := strings.Join(parts[2:], "_")
113+
return fmt.Sprintf("rulesets/%s/%s.xml/%s", lang, category, rule), nil
148114
}
149-
150-
// If no parameters left after filtering, just output the rule without properties
151-
if params.Len() == 0 {
152-
return fmt.Sprintf(` <rule ref="%s"/>`, pmdRef), nil
153-
}
154-
155-
result := fmt.Sprintf(` <rule ref="%s">
156-
<properties>%s
157-
</properties>
158-
</rule>`, pmdRef, params.String())
159-
160-
return result, nil
161115
}
162116

163-
// Add PMD 7 header
164-
var pmd7Header = `<?xml version="1.0" encoding="UTF-8"?>
165-
<ruleset name="Codacy PMD 7 Ruleset"
166-
xmlns="https://pmd.github.io/ruleset/2.0.0"
167-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
168-
xsi:schemaLocation="https://pmd.github.io/ruleset/2.0.0 https://pmd.github.io/schemas/pmd-7.0.0.xsd">
169-
<description>Codacy PMD 7 Ruleset</description>`
170-
171117
// createPmdConfigGeneric abstracts the config creation for both PMD and PMD7
172118
func createPmdConfigGeneric(
173119
configuration []domain.PatternConfiguration,
174120
header string,
175-
convertPatternID func(string) (string, error),
121+
convertPatternID func(string, bool) (string, error),
176122
isPMD7 bool,
177123
) string {
178124
if len(configuration) == 0 {
179125
// Fallback empty ruleset for PMD 7, or default for PMD 6
180126
if header == pmd7Header {
181127
return header + `</ruleset>`
182128
}
183-
return defaultPMDRuleset
129+
130+
return pmd6Header + `</ruleset>`
131+
184132
}
185133

186134
var rules []Rule
@@ -235,7 +183,7 @@ func createPmdConfigGeneric(
235183
continue
236184
}
237185

238-
ref, err := convertPatternID(rule.PatternID)
186+
ref, err := convertPatternID(rule.PatternID, isPMD7)
239187
if err != nil {
240188
continue
241189
}
@@ -268,18 +216,17 @@ func createPmdConfigGeneric(
268216
return rulesetXML.String()
269217
}
270218

271-
// CreatePmdConfig creates a PMD 6 configuration from the provided tool configuration
272-
func CreatePmdConfig(configuration []domain.PatternConfiguration) string {
273-
return createPmdConfigGeneric(configuration, `<?xml version="1.0"?>
274-
<ruleset name="Codacy PMD Ruleset"
275-
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
276-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
277-
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
278-
<description>Codacy PMD Ruleset</description>
279-
280-
`, convertPatternIDToPMD, false)
281-
}
219+
var pmd7Header = `<?xml version="1.0" encoding="UTF-8"?>
220+
<ruleset name="Codacy PMD 7 Ruleset"
221+
xmlns="https://pmd.github.io/ruleset/2.0.0"
222+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
223+
xsi:schemaLocation="https://pmd.github.io/ruleset/2.0.0 https://pmd.github.io/schemas/pmd-7.0.0.xsd">
224+
<description>Codacy PMD 7 Ruleset</description>`
282225

283-
func CreatePmd7Config(configuration []domain.PatternConfiguration) string {
284-
return createPmdConfigGeneric(configuration, pmd7Header, convertPatternIDToPMD7, true)
285-
}
226+
var pmd6Header = `<?xml version="1.0"?>
227+
<ruleset name="Codacy PMD Ruleset"
228+
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
229+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
230+
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
231+
<description>Codacy PMD Ruleset</description>
232+
`

tools/pmdConfigCreator_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func TestCreatePmdConfig(t *testing.T) {
8080
}
8181

8282
// Generate PMD config
83-
generatedConfig := CreatePmdConfig(config)
83+
generatedConfig := CreatePmd6Config(config)
8484

8585
// Read expected ruleset
8686
expectedRulesetPath := filepath.Join("testdata", "repositories", "pmd", "expected-ruleset.xml")
@@ -125,7 +125,7 @@ func TestCreatePmdConfigWithDisabledRules(t *testing.T) {
125125
},
126126
}
127127

128-
obtainedConfig := CreatePmdConfig(config)
128+
obtainedConfig := CreatePmd6Config(config)
129129

130130
var ruleset PMDRuleset
131131
err := xml.Unmarshal([]byte(obtainedConfig), &ruleset)
@@ -171,7 +171,7 @@ func TestCreatePmdConfigEmpty(t *testing.T) {
171171

172172
config := []domain.PatternConfiguration{}
173173

174-
obtainedConfig := CreatePmdConfig(config)
174+
obtainedConfig := CreatePmd6Config(config)
175175

176176
assert.Contains(t, obtainedConfig, `name="Default PMD Ruleset"`, "XML should contain the correct ruleset name")
177177
assert.Contains(t, obtainedConfig, `xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"`, "XML should contain the correct xmlns")
@@ -207,7 +207,7 @@ func TestCreatePmdConfigEmptyParameterValues(t *testing.T) {
207207
},
208208
}
209209

210-
obtainedConfig := CreatePmdConfig(config)
210+
obtainedConfig := CreatePmd6Config(config)
211211

212212
var ruleset PMDRuleset
213213
err := xml.Unmarshal([]byte(obtainedConfig), &ruleset)
@@ -266,7 +266,7 @@ func TestEmptyParametersAreSkipped(t *testing.T) {
266266
},
267267
}
268268

269-
obtainedConfig := CreatePmdConfig(config)
269+
obtainedConfig := CreatePmd6Config(config)
270270

271271
// Should find this exact pattern in the generated XML
272272
expectedPattern := `<rule ref="category/pom/errorprone.xml/InvalidDependencyTypes"/>`
@@ -292,7 +292,7 @@ func TestNonEmptyParameterValue(t *testing.T) {
292292
},
293293
}
294294

295-
obtainedConfig := CreatePmdConfig(config)
295+
obtainedConfig := CreatePmd6Config(config)
296296

297297
var ruleset PMDRuleset
298298
err := xml.Unmarshal([]byte(obtainedConfig), &ruleset)
@@ -338,7 +338,7 @@ func TestExactJsonStructure(t *testing.T) {
338338
},
339339
}
340340

341-
obtainedConfig := CreatePmdConfig(config)
341+
obtainedConfig := CreatePmd6Config(config)
342342

343343
var ruleset PMDRuleset
344344
err := xml.Unmarshal([]byte(obtainedConfig), &ruleset)

0 commit comments

Comments
 (0)