github.com/ismailbayram/bigpicture@v0.0.0-20231225173155-e4b21f5efcff/internal/validators/validators.go (about)

     1  package validators
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	v10Validator "github.com/go-playground/validator/v10"
     7  	"github.com/ismailbayram/bigpicture/internal/graph"
     8  	"regexp"
     9  	"strings"
    10  )
    11  
    12  type Validator interface {
    13  	Validate() error
    14  }
    15  
    16  func NewValidator(t string, args map[string]any, tree *graph.Tree) (Validator, error) {
    17  	switch t {
    18  	case "no_import":
    19  		return NewNoImportValidator(args, tree)
    20  	case "instability":
    21  		return NewInstabilityValidator(args, tree)
    22  	case "line_count":
    23  		return NewLineCountValidator(args, tree)
    24  	case "function":
    25  		return NewFunctionValidator(args, tree)
    26  	case "file_name":
    27  		return NewFileNameValidator(args, tree)
    28  	case "size":
    29  		return NewSizeValidator(args, tree)
    30  	default:
    31  		return nil, fmt.Errorf("unknown validator type: %s", t)
    32  	}
    33  }
    34  
    35  func validateArgs(args map[string]any, validatorArgStruct any) error {
    36  	jsonData, _ := json.Marshal(args)
    37  	_ = json.Unmarshal(jsonData, validatorArgStruct)
    38  	validate := v10Validator.New()
    39  	err := validate.Struct(validatorArgStruct)
    40  	if err != nil {
    41  		return validationErrorToText(err.(v10Validator.ValidationErrors)[0])
    42  	}
    43  	return nil
    44  }
    45  
    46  func validationErrorToText(e v10Validator.FieldError) error {
    47  	word := toSnakeCase(e.Field())
    48  
    49  	switch e.Tag() {
    50  	case "required":
    51  		return fmt.Errorf("%s is required and must be %s", word, e.Type().String())
    52  	case "max":
    53  		return fmt.Errorf("%s cannot be longer than %s", word, e.Param())
    54  	case "min":
    55  		return fmt.Errorf("%s must be longer than %s", word, e.Param())
    56  	case "gte":
    57  		return fmt.Errorf("%s must be greater than or equal to %s", word, e.Param())
    58  	case "lte":
    59  		return fmt.Errorf("%s must be less than or equal to %s", word, e.Param())
    60  	case "email":
    61  		return fmt.Errorf("%s is not a valid email address", word)
    62  	case "len":
    63  		return fmt.Errorf("%s must be %s characters long", word, e.Param())
    64  	}
    65  	return fmt.Errorf("%s is not %s", word, e.Type().String())
    66  }
    67  
    68  func toSnakeCase(str string) string {
    69  	var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
    70  	var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
    71  
    72  	snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}")
    73  	snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}")
    74  	return strings.ToLower(snake)
    75  }
    76  
    77  func validatePath(path string, tree *graph.Tree) (string, error) {
    78  	if len(path) > 1 && strings.HasSuffix(path, "/*") {
    79  		path = path[:len(path)-2]
    80  	}
    81  
    82  	if _, ok := tree.Nodes[path]; !ok && path != "*" {
    83  		return "", fmt.Errorf("'%s' is not a valid module. Path should start with /", path)
    84  	}
    85  	return path, nil
    86  }
    87  
    88  func isIgnored(ignoreList []string, path string) bool {
    89  	isIgnored := false
    90  	for _, ignore := range ignoreList {
    91  		regxp := ignore
    92  		if strings.HasPrefix(ignore, "*") {
    93  			regxp = fmt.Sprintf("^%s$", ignore)
    94  		}
    95  		re := regexp.MustCompile(regxp)
    96  		if re.MatchString(path) {
    97  			isIgnored = true
    98  			break
    99  		}
   100  	}
   101  	return isIgnored
   102  }