Skip to content

Commit eb240f7

Browse files
parsing jsonData into pylintrc type file
1 parent 58327d1 commit eb240f7

File tree

4 files changed

+805
-0
lines changed

4 files changed

+805
-0
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package tools
2+
3+
import (
4+
"codacy/cli-v2/tools/types"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
)
9+
10+
// ParsePylintPatternsFromJSON parses a JSON array of Pylint patterns into types.PylintPatternConfiguration array
11+
func ParsePylintPatternsFromJSON(jsonData []byte) ([]types.PylintPatternConfiguration, error) {
12+
var response struct {
13+
Data []struct {
14+
PatternDefinition struct {
15+
ID string `json:"id"`
16+
Parameters []struct {
17+
Name string `json:"name"`
18+
Default string `json:"default"`
19+
} `json:"parameters"`
20+
} `json:"patternDefinition"`
21+
Enabled bool `json:"enabled"`
22+
Parameters []struct {
23+
Name string `json:"name"`
24+
Value string `json:"value"`
25+
} `json:"parameters"`
26+
} `json:"data"`
27+
}
28+
29+
if err := json.Unmarshal(jsonData, &response); err != nil {
30+
return nil, err
31+
}
32+
33+
patterns := make([]types.PylintPatternConfiguration, len(response.Data))
34+
for i, pattern := range response.Data {
35+
defaultParameters := make([]types.PylintPatternParameterConfiguration, len(pattern.PatternDefinition.Parameters))
36+
for j, param := range pattern.PatternDefinition.Parameters {
37+
defaultParameters[j] = types.PylintPatternParameterConfiguration{
38+
Name: param.Name,
39+
Value: param.Default,
40+
SectionName: GetParameterSection(param.Name),
41+
}
42+
}
43+
44+
parameters := make([]types.PylintPatternParameterConfiguration, len(pattern.Parameters))
45+
for j, param := range pattern.Parameters {
46+
parameters[j] = types.PylintPatternParameterConfiguration{
47+
Name: param.Name,
48+
Value: param.Value,
49+
SectionName: GetParameterSection(param.Name),
50+
}
51+
}
52+
53+
patterns[i] = types.PylintPatternConfiguration{
54+
Id: ExtractPatternID(pattern.PatternDefinition.ID),
55+
Enabled: pattern.Enabled,
56+
Parameters: setConfigurationParameters(parameters, defaultParameters),
57+
}
58+
}
59+
60+
return patterns, nil
61+
}
62+
63+
// FilterEnabledPatterns returns only the enabled patterns from the given slice
64+
func FilterEnabledPatterns(patterns []types.PylintPatternConfiguration) []types.PylintPatternConfiguration {
65+
enabledPatterns := make([]types.PylintPatternConfiguration, 0)
66+
for _, pattern := range patterns {
67+
if pattern.Enabled {
68+
enabledPatterns = append(enabledPatterns, pattern)
69+
}
70+
}
71+
return enabledPatterns
72+
}
73+
74+
// DefaultPylintParameters contains the default values for common Pylint parameters
75+
var DefaultPylintParameters = map[string]string{
76+
"max-line-length": "100",
77+
"max-doc-length": "100",
78+
"max-args": "5",
79+
"max-attributes": "7",
80+
"max-branches": "12",
81+
"max-locals": "15",
82+
"max-parents": "7",
83+
"max-public-methods": "20",
84+
"max-returns": "6",
85+
"max-statements": "50",
86+
}
87+
88+
// ExtractPatternID returns the part of the pattern ID after the underscore
89+
// For example: "PyLintPython3_C0301" -> "C0301"
90+
func ExtractPatternID(fullID string) string {
91+
parts := strings.Split(fullID, "_")
92+
if len(parts) > 1 {
93+
return parts[1]
94+
}
95+
return fullID
96+
}
97+
98+
// GeneratePylintRC generates a pylintrc file content with the specified patterns enabled
99+
func GeneratePylintRC(patterns []types.PylintPatternConfiguration) string {
100+
var rcContent strings.Builder
101+
102+
// Write header
103+
rcContent.WriteString("[MASTER]\n")
104+
rcContent.WriteString("ignore=CVS\n")
105+
rcContent.WriteString("persistent=yes\n")
106+
rcContent.WriteString("load-plugins=\n\n")
107+
108+
// Disable all patterns by default
109+
rcContent.WriteString("[MESSAGES CONTROL]\n")
110+
rcContent.WriteString("disable=all\n")
111+
112+
// Collect all enabled pattern IDs
113+
var enabledPatterns []string
114+
for _, pattern := range patterns {
115+
if pattern.Enabled {
116+
enabledPatterns = append(enabledPatterns, ExtractPatternID(pattern.Id))
117+
}
118+
}
119+
120+
// Write all enabled patterns in a single line
121+
if len(enabledPatterns) > 0 {
122+
rcContent.WriteString(fmt.Sprintf("enable=%s\n", strings.Join(enabledPatterns, ",")))
123+
}
124+
rcContent.WriteString("\n")
125+
126+
// Group parameters by section
127+
groupedParams := GroupParametersBySection(patterns)
128+
129+
// Write parameters for each section
130+
for sectionName, params := range groupedParams {
131+
rcContent.WriteString(fmt.Sprintf("[%s]\n", sectionName))
132+
for _, param := range params {
133+
value := param.Value
134+
if value == "" {
135+
// If no value is set, use default from DefaultPylintParameters
136+
if defaultVal, ok := DefaultPylintParameters[param.Name]; ok {
137+
value = defaultVal
138+
}
139+
}
140+
rcContent.WriteString(fmt.Sprintf("%s=%s\n", param.Name, value))
141+
}
142+
rcContent.WriteString("\n")
143+
}
144+
145+
return rcContent.String()
146+
}
147+
148+
// setConfigurationParameters returns the first array if it's not empty, otherwise returns the second array
149+
func setConfigurationParameters(parameters, defaultParameters []types.PylintPatternParameterConfiguration) []types.PylintPatternParameterConfiguration {
150+
if len(parameters) > 0 {
151+
return parameters
152+
}
153+
return defaultParameters
154+
}
155+
156+
// groupParametersBySection groups parameters by their section name
157+
func GroupParametersBySection(patterns []types.PylintPatternConfiguration) map[string][]types.PylintPatternParameterConfiguration {
158+
// Initialize the result map
159+
groupedParams := make(map[string][]types.PylintPatternParameterConfiguration)
160+
161+
// Iterate through each pattern
162+
for _, pattern := range patterns {
163+
// Iterate through each parameter
164+
for _, param := range pattern.Parameters {
165+
// Skip parameters without a section name
166+
if param.SectionName == nil {
167+
continue
168+
}
169+
170+
// Get the section name
171+
sectionName := *param.SectionName
172+
173+
// Add the parameter to the appropriate section
174+
groupedParams[sectionName] = append(groupedParams[sectionName], param)
175+
}
176+
}
177+
178+
return groupedParams
179+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package tools
2+
3+
// GetParameterSection returns the section name for a parameter or nil if it doesn't exist
4+
func GetParameterSection(paramName string) *string {
5+
sectionName, exists := map[string]string{
6+
// BASIC section
7+
"required-attributes": "BASIC",
8+
"bad-functions": "BASIC",
9+
"good-names": "BASIC",
10+
"bad-names": "BASIC",
11+
"name-group": "BASIC",
12+
"include-naming-hint": "BASIC",
13+
"function-rgx": "BASIC",
14+
"function-name-hint": "BASIC",
15+
"variable-rgx": "BASIC",
16+
"variable-name-hint": "BASIC",
17+
"const-rgx": "BASIC",
18+
"const-name-hint": "BASIC",
19+
"attr-rgx": "BASIC",
20+
"attr-name-hint": "BASIC",
21+
"argument-rgx": "BASIC",
22+
"argument-name-hint": "BASIC",
23+
"class-attribute-rgx": "BASIC",
24+
"class-attribute-name-hint": "BASIC",
25+
"inlinevar-rgx": "BASIC",
26+
"inlinevar-name-hint": "BASIC",
27+
"class-rgx": "BASIC",
28+
"class-name-hint": "BASIC",
29+
"module-rgx": "BASIC",
30+
"module-name-hint": "BASIC",
31+
"method-rgx": "BASIC",
32+
"method-name-hint": "BASIC",
33+
"no-docstring-rgx": "BASIC",
34+
"docstring-min-length": "BASIC",
35+
36+
// SPELLING section
37+
"spelling-dict": "SPELLING",
38+
"spelling-ignore-words": "SPELLING",
39+
"spelling-private-dict-file": "SPELLING",
40+
"spelling-store-unknown-words": "SPELLING",
41+
42+
// SIMILARITIES section
43+
"min-similarity-lines": "SIMILARITIES",
44+
"ignore-comments": "SIMILARITIES",
45+
"ignore-docstrings": "SIMILARITIES",
46+
"ignore-imports": "SIMILARITIES",
47+
48+
// LOGGING section
49+
"logging-modules": "LOGGING",
50+
51+
// FORMAT section
52+
"max-line-length": "FORMAT",
53+
"ignore-long-lines": "FORMAT",
54+
"single-line-if-stmt": "FORMAT",
55+
"no-space-check": "FORMAT",
56+
"max-module-lines": "FORMAT",
57+
"indent-string": "FORMAT",
58+
"indent-after-paren": "FORMAT",
59+
"expected-line-ending-format": "FORMAT",
60+
61+
// MISCELLANEOUS section
62+
"notes": "MISCELLANEOUS",
63+
64+
// TYPECHECK section
65+
"ignore-mixin-members": "TYPECHECK",
66+
"ignored-modules": "TYPECHECK",
67+
"ignored-classes": "TYPECHECK",
68+
"zope": "TYPECHECK",
69+
"generated-members": "TYPECHECK",
70+
71+
// CLASSES section
72+
"ignore-iface-methods": "CLASSES",
73+
"defining-attr-methods": "CLASSES",
74+
"valid-classmethod-first-arg": "CLASSES",
75+
"valid-metaclass-classmethod-first-arg": "CLASSES",
76+
"exclude-protected": "CLASSES",
77+
78+
// DESIGN section
79+
"max-args": "DESIGN",
80+
"ignored-argument-names": "DESIGN",
81+
"max-locals": "DESIGN",
82+
"max-returns": "DESIGN",
83+
"max-branches": "DESIGN",
84+
"max-statements": "DESIGN",
85+
"max-parents": "DESIGN",
86+
"max-attributes": "DESIGN",
87+
"min-public-methods": "DESIGN",
88+
"max-public-methods": "DESIGN",
89+
90+
// IMPORTS section
91+
"deprecated-modules": "IMPORTS",
92+
"import-graph": "IMPORTS",
93+
"ext-import-graph": "IMPORTS",
94+
"int-import-graph": "IMPORTS",
95+
96+
// EXCEPTIONS section
97+
"overgeneral-exceptions": "EXCEPTIONS",
98+
}[paramName]
99+
100+
if !exists {
101+
return nil
102+
}
103+
104+
return &sectionName
105+
}

0 commit comments

Comments
 (0)