Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"codacy/cli-v2/config"
"codacy/cli-v2/domain"
"codacy/cli-v2/tools"
"codacy/cli-v2/tools/pylint"
"codacy/cli-v2/utils"
"encoding/json"
"errors"
Expand Down Expand Up @@ -307,6 +308,19 @@ func createToolFileConfigurations(tool tools.Tool, patternConfiguration []domain
}
}
fmt.Println("PMD configuration created based on Codacy settings")
case PyLint:
if len(patternConfiguration) > 0 {
err := createPylintConfigFile(patternConfiguration, toolsConfigDir)
if err != nil {
return fmt.Errorf("failed to create Pylint config: %v", err)
}
} else {
err := createDefaultPylintConfigFile(toolsConfigDir)
if err != nil {
return fmt.Errorf("failed to create default Pylint config: %v", err)
}
}
fmt.Println("Pylint configuration created based on Codacy settings")
}
return nil
}
Expand All @@ -319,6 +333,17 @@ func createPMDConfigFile(config []domain.PatternConfiguration, toolsConfigDir st
func createDefaultPMDConfigFile(toolsConfigDir string) error {
content := tools.CreatePmdConfig([]domain.PatternConfiguration{})
return os.WriteFile(filepath.Join(toolsConfigDir, "pmd-ruleset.xml"), []byte(content), utils.DefaultFilePerms)

}

func createPylintConfigFile(config []domain.PatternConfiguration, toolsConfigDir string) error {
pylintConfigurationString := pylint.GeneratePylintRC(config)
return os.WriteFile(filepath.Join(toolsConfigDir, "pylint.rc"), []byte(pylintConfigurationString), utils.DefaultFilePerms)
}

func createDefaultPylintConfigFile(toolsConfigDir string) error {
pylintConfigurationString := pylint.GeneratePylintRCDefault()
return os.WriteFile(filepath.Join(toolsConfigDir, "pylint.rc"), []byte(pylintConfigurationString), utils.DefaultFilePerms)
}

// createTrivyConfigFile creates a trivy.yaml configuration file based on the API configuration
Expand Down
152 changes: 152 additions & 0 deletions tools/pylint/pylintConfigParser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package pylint

import (
"codacy/cli-v2/domain"
"fmt"
"log"
"strings"
)

// getDefaultParametersForPatterns returns a map of pattern IDs to their default parameters
func getDefaultParametersForPatterns(patternIDs []string) map[string][]domain.ParameterConfiguration {
defaultParams := make(map[string][]domain.ParameterConfiguration)

for _, patternID := range patternIDs {
if params, exists := PatternDefaultParameters[patternID]; exists {
defaultParams[patternID] = params
}
}

return defaultParams
}

// writePylintRCHeader writes the common header sections to the RC content
func writePylintRCHeader(rcContent *strings.Builder) {
rcContent.WriteString("[MASTER]\n")
rcContent.WriteString("ignore=CVS\n")
rcContent.WriteString("persistent=yes\n")
rcContent.WriteString("load-plugins=\n\n")
rcContent.WriteString("[MESSAGES CONTROL]\n")
rcContent.WriteString("disable=all\n")
}

// writeEnabledPatterns writes the enabled patterns section to the RC content
func writeEnabledPatterns(rcContent *strings.Builder, patternIDs []string) {
if len(patternIDs) > 0 {
rcContent.WriteString(fmt.Sprintf("enable=%s\n", strings.Join(patternIDs, ",")))
}
rcContent.WriteString("\n")
}

// writeParametersBySection writes the parameters grouped by section to the RC content
func writeParametersBySection(rcContent *strings.Builder, groupedParams map[string][]domain.ParameterConfiguration) {
for sectionName, params := range groupedParams {
rcContent.WriteString(fmt.Sprintf("[%s]\n", sectionName))
for _, param := range params {
rcContent.WriteString(fmt.Sprintf("%s=%s\n", param.Name, param.Value))
}
rcContent.WriteString("\n")
}
}

// groupParametersByPatterns groups parameters from patterns into sections
func groupParametersByPatterns(patterns []domain.PatternConfiguration) map[string][]domain.ParameterConfiguration {

Check warning on line 53 in tools/pylint/pylintConfigParser.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools/pylint/pylintConfigParser.go#L53

Method groupParametersByPatterns has a cyclomatic complexity of 9 (limit is 7)
groupedParams := make(map[string][]domain.ParameterConfiguration)

for _, pattern := range patterns {
patternID := extractPatternId(pattern.PatternDefinition.Id)
params := pattern.Parameters

// If no parameters, check defaults
if len(params) == 0 {
if defaultParams, exists := PatternDefaultParameters[patternID]; exists {
params = defaultParams
}
}

// Add parameters to their respective sections
for _, param := range params {
sectionName := GetParameterSection(param.Name)
if sectionName == nil {
log.Printf("Parameter %s has no section name", param.Name)
continue
}

// Check if parameter already exists in section
exists := false
for _, existingParam := range groupedParams[*sectionName] {
if existingParam.Name == param.Name {
exists = true
break
}
}

// Only add if not already present
if !exists {
groupedParams[*sectionName] = append(groupedParams[*sectionName], param)
}
}
}

return groupedParams
}

func GeneratePylintRCDefault() string {

Check notice on line 94 in tools/pylint/pylintConfigParser.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools/pylint/pylintConfigParser.go#L94

exported function GeneratePylintRCDefault should have comment or be unexported
var rcContent strings.Builder

writePylintRCHeader(&rcContent)
writeEnabledPatterns(&rcContent, DefaultPatterns)

// Get default parameters for enabled patterns
defaultParams := getDefaultParametersForPatterns(DefaultPatterns)

// Convert default parameters to pattern configurations
var patterns []domain.PatternConfiguration
for patternID, params := range defaultParams {
patterns = append(patterns, domain.PatternConfiguration{
PatternDefinition: domain.PatternDefinition{
Id: "PyLintPython3_" + patternID,
},
Parameters: params,
})
}

// Group and write parameters
groupedParams := groupParametersByPatterns(patterns)
writeParametersBySection(&rcContent, groupedParams)

return rcContent.String()
}

// GeneratePylintRC generates a pylintrc file content with the specified patterns enabled
func GeneratePylintRC(config []domain.PatternConfiguration) string {
var rcContent strings.Builder

writePylintRCHeader(&rcContent)

// Collect enabled pattern IDs
var enabledPatternsIds []string

Check notice on line 128 in tools/pylint/pylintConfigParser.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools/pylint/pylintConfigParser.go#L128

var enabledPatternsIds should be enabledPatternsIDs

for _, pattern := range config {
patternID := extractPatternId(pattern.PatternDefinition.Id)
enabledPatternsIds = append(enabledPatternsIds, patternID)
}

writeEnabledPatterns(&rcContent, enabledPatternsIds)

// Group and write parameters
groupedParams := groupParametersByPatterns(config)
writeParametersBySection(&rcContent, groupedParams)

return rcContent.String()
}

// extractPatternId returns the part of the pattern ID after the underscore
// For example: "PyLintPython3_C0301" -> "C0301"
func extractPatternId(fullID string) string {

Check notice on line 146 in tools/pylint/pylintConfigParser.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools/pylint/pylintConfigParser.go#L146

func extractPatternId should be extractPatternID
parts := strings.Split(fullID, "_")
if len(parts) > 1 {
return parts[1]
}
return fullID
}
104 changes: 104 additions & 0 deletions tools/pylint/pylintDefaultPatterns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package pylint

// DefaultPatterns contains the list of default Pylint patterns
var DefaultPatterns = []string{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is the thing that we can change to get from the API, but I am fine moving forward with this on this scope

"C0123",
"C0200",
"C0303",
"E0100",
"E0101",
"E0102",
"E0103",
"E0104",
"E0105",
"E0106",
"E0107",
"E0108",
"E0110",
"E0112",
"E0113",
"E0114",
"E0115",
"E0116",
"E0117",
"E0202",
"E0203",
"E0211",
"E0236",
"E0238",
"E0239",
"E0240",
"E0241",
"E0301",
"E0302",
"E0601",
"E0603",
"E0604",
"E0701",
"E0702",
"E0703",
"E0704",
"E0710",
"E0711",
"E0712",
"E1003",
"E1102",
"E1111",
"E1120",
"E1121",
"E1123",
"E1124",
"E1125",
"E1126",
"E1127",
"E1132",
"E1200",
"E1201",
"E1205",
"E1206",
"E1300",
"E1301",
"E1302",
"E1303",
"E1304",
"E1305",
"E1306",
"R0201",
"R0202",
"R0203",
"W0101",
"W0102",
"W0104",
"W0105",
"W0106",
"W0107",
"W0108",
"W0109",
"W0120",
"W0122",
"W0124",
"W0150",
"W0199",
"W0221",
"W0222",
"W0233",
"W0404",
"W0410",
"W0601",
"W0602",
"W0604",
"W0611",
"W0612",
"W0622",
"W0623",
"W0702",
"W0705",
"W0711",
"W1300",
"W1301",
"W1302",
"W1303",
"W1305",
"W1306",
"W1307",
}
67 changes: 67 additions & 0 deletions tools/pylint/pylintDefaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package pylint

import "codacy/cli-v2/domain"

// PatternDefaultParameters contains the default parameters for Pylint patterns
var PatternDefaultParameters = map[string][]domain.ParameterConfiguration{
"R0914": {
{
Name: "max-locals",
Value: "15",
},
},
"C0301": {
{
Name: "max-line-length",
Value: "120",
},
},
"C0102": {
{
Name: "bad-names",
Value: "foo,bar,baz,toto,tutu,tata",
},
},
"C0103": {
{
Name: "argument-rgx",
Value: "[a-z_][a-z0-9_]{2,30}$",
},
{
Name: "attr-rgx",
Value: "[a-z_][a-z0-9_]{2,30}$",
},
{
Name: "class-rgx",
Value: "[A-Z_][a-zA-Z0-9]+$",
},
{
Name: "const-rgx",
Value: "(([A-Z_][A-Z0-9_]*)|(__.*__))$",
},
{
Name: "function-rgx",
Value: "[a-z_][a-z0-9_]{2,30}$",
},
{
Name: "method-rgx",
Value: "[a-z_][a-z0-9_]{2,30}$",
},
{
Name: "module-rgx",
Value: "(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$",
},
{
Name: "variable-rgx",
Value: "[a-z_][a-z0-9_]{2,30}$",
},
{
Name: "inlinevar-rgx",
Value: "[A-Za-z_][A-Za-z0-9_]*$",
},
{
Name: "class-attribute-rgx",
Value: "([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$",
},
},
}
Loading