Skip to content
This repository has been archived by the owner on Jul 19, 2023. It is now read-only.

Commit

Permalink
feat: Add a rule to ensure the use of a linter in the repository
Browse files Browse the repository at this point in the history
* add wemake and superlinter as incode rules

* add megalinter to linter rule

* linters disable by default

* increase rule unique id

* increase rule unique id

* merge main
  • Loading branch information
OriYosef authored Oct 6, 2022
1 parent b705704 commit 544b070
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 0 deletions.
185 changes: 185 additions & 0 deletions pkg/rulesConfig/defaultRules/16-ensure-linter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package defaultRules

import (
"encoding/json"

githubConnector "github.com/allero-io/allero/pkg/connectors/github"
gitlabConnector "github.com/allero-io/allero/pkg/connectors/gitlab"
)

func EnsureLinter(githubData map[string]*githubConnector.GithubOwner, gitlabData map[string]*gitlabConnector.GitlabGroup) ([]*SchemaError, error) {
schemaErrors := make([]*SchemaError, 0)
var err error

if githubData != nil {
schemaErrors, err = githubErrorsRule16(githubData)
if err != nil {
return nil, err
}
}

if gitlabData != nil {
schemaErrors, err = gitlabErrorsRule16(gitlabData)
if err != nil {
return nil, err
}
}

return schemaErrors, nil
}

func githubErrorsRule16(githubData map[string]*githubConnector.GithubOwner) ([]*SchemaError, error) {
schemaErrors := make([]*SchemaError, 0)

usesRegexExpressions := []string{
".*wemake-services/wemake-python-styleguide@.*",
".*github/super-linter@.*",
".*oxsecurity/megalinter@.*",
}

runRegexExpressions := []string{
".*^[\\S]*pip install wemake-python-styleguide.*",
".*^[\\S]*flake8 .*",
".*^[\\S]*{tool}.*",
".*docker .* run .*({tool}/)?renovate.*",
".*mega-linter-runner.*",
}

for _, owner := range githubData {
for _, repo := range owner.Repositories {
foundLinter := false

for _, workflow := range repo.GithubActionsWorkflows {
content := workflow.Content
contentByteArr, err := json.Marshal(content)
if err != nil {
return nil, err
}

var workflowObj Workflow
err = json.Unmarshal(contentByteArr, &workflowObj)
if err != nil {
return nil, err
}

for _, job := range workflowObj.Jobs {
for _, step := range job.Steps {
for _, regexExpression := range usesRegexExpressions {
if matchRegex(regexExpression, step.Uses) {
foundLinter = true
break
}
}

for _, regexExpression := range runRegexExpressions {
if matchRegex(regexExpression, step.Run) {
foundLinter = true
break
}
}

if foundLinter {
break
}
}

if foundLinter {
break
}
}

if foundLinter {
break
}
}

if !foundLinter {
schemaErrors = append(schemaErrors, &SchemaError{
ErrorLevel: 1,
RepositryName: repo.Name,
CiCdPlatform: "github-actions-workflows",
OwnerName: owner.Name,
ScmPlatform: "github",
})
}
}
}

return schemaErrors, nil
}

func gitlabErrorsRule16(gitlabData map[string]*gitlabConnector.GitlabGroup) ([]*SchemaError, error) {
schemaErrors := make([]*SchemaError, 0)

for _, group := range gitlabData {
for _, project := range group.Projects {
foundLinter, err := findLinterRule16(project)
if err != nil {
return nil, err
}

if !foundLinter {
schemaErrors = append(schemaErrors, &SchemaError{
ErrorLevel: 2,
RepositryName: project.Name,
CiCdPlatform: "gitlab-ci",
OwnerName: group.Name,
ScmPlatform: "gitlab",
})
}
}
}

return schemaErrors, nil
}

func findLinterRule16(project *gitlabConnector.GitlabProject) (bool, error) {
scriptRegexExpressions := []string{
".*^[\\S]*pip install wemake-python-styleguide.*",
".*^[\\S]*flake8 .*",
".*^[\\S]*{tool}.*",
".*docker .* run .*({tool}/)?renovate.*",
".*mega-linter-runner.*",
}

for _, pipeline := range project.GitlabCi {

for _, stage := range pipeline.Content {
stageBytes, err := json.Marshal(stage)
if err != nil {
return false, err
}

var stageWithSingleScript GitlabStageScript
var stageWithScripts GitlabStageScripts

err = json.Unmarshal(stageBytes, &stageWithSingleScript)
if err != nil {
err = json.Unmarshal(stageBytes, &stageWithScripts)
if err != nil {
continue
}
}

if stageWithSingleScript.Script != "" {
for _, regexExpression := range scriptRegexExpressions {
if matchRegex(regexExpression, stageWithSingleScript.Script) {
return true, nil
}
}
}

if stageWithScripts.Scripts != nil {
for _, script := range stageWithScripts.Scripts {
for _, regexExpression := range scriptRegexExpressions {
if matchRegex(regexExpression, script) {
return true, nil
}
}
}
}
}
}

return false, nil
}
3 changes: 3 additions & 0 deletions pkg/rulesConfig/defaultRules/defaultRules.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ func Validate(rule *Rule, githubData map[string]*githubConnector.GithubOwner, gi
if rule.UniqueId == 14 {
return EnsureCodeCoverageChecker(githubData, gitlabData)
}
if rule.UniqueId == 16 {
return EnsureLinter(githubData, gitlabData)
}

return nil, fmt.Errorf("missing implementation for rule %d", rule.UniqueId)
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/rulesConfig/defaultRules/github/16-ensure-linter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"description": "Ensure that at least one pipeline in each repository runs linter",
"failureMessage": "Linter was not detected in the repository pipelines. It is recommended to add one to keep standrads and clean code.",
"uniqueId": 16,
"enabledByDefault": false,
"inCodeImplementation": true
}
7 changes: 7 additions & 0 deletions pkg/rulesConfig/defaultRules/gitlab/16-ensure-linter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"description": "Ensure that at least one pipeline in each repository runs linter",
"failureMessage": "Linter was not detected in the repository pipelines. It is recommended to add one to keep standrads and clean code.",
"uniqueId": 16,
"enabledByDefault": false,
"inCodeImplementation": true
}

0 comments on commit 544b070

Please sign in to comment.