|
2 | 2 | package config |
3 | 3 |
|
4 | 4 | import ( |
| 5 | + "bufio" |
| 6 | + "errors" |
5 | 7 | "fmt" |
6 | 8 | "os" |
7 | 9 | "path/filepath" |
8 | 10 |
|
9 | | - "github.com/conventionalcommit/commitlint/formatter" |
| 11 | + "gopkg.in/yaml.v3" |
| 12 | + |
10 | 13 | "github.com/conventionalcommit/commitlint/lint" |
11 | | - "github.com/conventionalcommit/commitlint/rule" |
12 | 14 | ) |
13 | 15 |
|
14 | 16 | const ( |
15 | 17 | // ConfFileName represent config file name |
16 | 18 | ConfFileName = "commitlint.yaml" |
17 | 19 | ) |
18 | 20 |
|
19 | | -var allFormatters = []lint.Formatter{ |
20 | | - &formatter.DefaultFormatter{}, |
21 | | - &formatter.JSONFormatter{}, |
22 | | -} |
23 | | - |
24 | | -var allRules = []lint.Rule{ |
25 | | - &rule.BodyMinLenRule{}, |
26 | | - &rule.BodyMaxLenRule{}, |
27 | | - |
28 | | - &rule.FooterMinLenRule{}, |
29 | | - &rule.FooterMaxLenRule{}, |
30 | | - |
31 | | - &rule.HeadMaxLenRule{}, |
32 | | - &rule.HeadMinLenRule{}, |
33 | | - |
34 | | - &rule.TypeEnumRule{}, |
35 | | - &rule.ScopeEnumRule{}, |
36 | | - |
37 | | - &rule.BodyMaxLineLenRule{}, |
38 | | - &rule.FooterMaxLineLenRule{}, |
39 | | - |
40 | | - &rule.TypeCharsetRule{}, |
41 | | - &rule.ScopeCharsetRule{}, |
42 | | - |
43 | | - &rule.TypeMaxLenRule{}, |
44 | | - &rule.ScopeMaxLenRule{}, |
45 | | - &rule.DescriptionMaxLenRule{}, |
46 | | - |
47 | | - &rule.TypeMinLenRule{}, |
48 | | - &rule.ScopeMinLenRule{}, |
49 | | - &rule.DescriptionMinLenRule{}, |
50 | | -} |
51 | | - |
52 | 21 | // GetConfig returns conf |
53 | 22 | func GetConfig(flagConfPath string) (*lint.Config, error) { |
54 | 23 | confFilePath, useDefault, err := GetConfigPath(flagConfPath) |
@@ -93,48 +62,86 @@ func GetConfigPath(confFilePath string) (string, bool, error) { |
93 | 62 | return filepath.Clean(confFilePath), false, nil |
94 | 63 | } |
95 | 64 |
|
96 | | -// GetFormatter returns the formatter as defined in conf |
97 | | -func GetFormatter(c *lint.Config) (lint.Formatter, error) { |
98 | | - for _, f := range allFormatters { |
99 | | - if f.Name() == c.Formatter { |
100 | | - return f, nil |
101 | | - } |
| 65 | +// Parse parse Config from given file |
| 66 | +func Parse(confPath string) (*lint.Config, error) { |
| 67 | + confBytes, err := os.ReadFile(confPath) |
| 68 | + if err != nil { |
| 69 | + return nil, err |
102 | 70 | } |
103 | | - return nil, fmt.Errorf("%s formatter not found", c.Formatter) |
| 71 | + |
| 72 | + conf := &lint.Config{} |
| 73 | + err = yaml.Unmarshal(confBytes, conf) |
| 74 | + if err != nil { |
| 75 | + return nil, err |
| 76 | + } |
| 77 | + |
| 78 | + err = Validate(conf) |
| 79 | + if err != nil { |
| 80 | + return nil, fmt.Errorf("config error: %w", err) |
| 81 | + } |
| 82 | + return conf, nil |
104 | 83 | } |
105 | 84 |
|
106 | | -// GetRules forms Rule object for rules which are enabled in config |
107 | | -func GetRules(conf *lint.Config) ([]lint.Rule, error) { |
108 | | - // rules lookup map |
109 | | - rulesMap := map[string]lint.Rule{} |
110 | | - for _, r := range allRules { |
111 | | - rulesMap[r.Name()] = r |
| 85 | +// Validate parses Config from given data |
| 86 | +func Validate(conf *lint.Config) error { |
| 87 | + if conf.Formatter == "" { |
| 88 | + return errors.New("formatter is empty") |
112 | 89 | } |
113 | 90 |
|
114 | | - enabledRules := make([]lint.Rule, 0, len(conf.Rules)) |
| 91 | + // Check Severity Level of rule config |
| 92 | + for ruleName, r := range conf.Rules { |
| 93 | + switch r.Severity { |
| 94 | + case lint.SeverityError: |
| 95 | + case lint.SeverityWarn: |
| 96 | + default: |
| 97 | + return fmt.Errorf("unknown severity level '%s' for rule '%s'", r.Severity, ruleName) |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + return nil |
| 102 | +} |
115 | 103 |
|
116 | | - for ruleName, ruleConfig := range conf.Rules { |
117 | | - r, ok := rulesMap[ruleName] |
118 | | - if !ok { |
119 | | - return nil, fmt.Errorf("unknown rule: %s", ruleName) |
| 104 | +// DefaultConfToFile writes default config to given file |
| 105 | +func DefaultConfToFile(isOnlyEnabled bool) error { |
| 106 | + outPath := filepath.Join(".", filepath.Clean(ConfFileName)) |
| 107 | + if isOnlyEnabled { |
| 108 | + confClone := &lint.Config{ |
| 109 | + Formatter: defConf.Formatter, |
| 110 | + Rules: map[string]lint.RuleConfig{}, |
120 | 111 | } |
121 | | - if ruleConfig.Enabled { |
122 | | - err := r.Apply(ruleConfig.Argument, ruleConfig.Flags) |
123 | | - if err != nil { |
124 | | - return nil, err |
| 112 | + |
| 113 | + for ruleName, r := range defConf.Rules { |
| 114 | + if r.Enabled { |
| 115 | + confClone.Rules[ruleName] = r |
125 | 116 | } |
126 | | - enabledRules = append(enabledRules, r) |
127 | 117 | } |
128 | | - } |
129 | 118 |
|
130 | | - return enabledRules, nil |
| 119 | + return WriteConfToFile(outPath, confClone) |
| 120 | + } |
| 121 | + return WriteConfToFile(outPath, defConf) |
131 | 122 | } |
132 | 123 |
|
133 | | -// GetLinter returns Linter for given confFilePath |
134 | | -func GetLinter(conf *lint.Config) (*lint.Linter, error) { |
135 | | - rules, err := GetRules(conf) |
| 124 | +// WriteConfToFile util func to write config object to given file |
| 125 | +func WriteConfToFile(outFilePath string, conf *lint.Config) (retErr error) { |
| 126 | + file, err := os.Create(outFilePath) |
136 | 127 | if err != nil { |
137 | | - return nil, err |
| 128 | + return err |
138 | 129 | } |
139 | | - return lint.NewLinter(conf, rules) |
| 130 | + defer func() { |
| 131 | + err1 := file.Close() |
| 132 | + if retErr == nil && err1 != nil { |
| 133 | + retErr = err1 |
| 134 | + } |
| 135 | + }() |
| 136 | + |
| 137 | + w := bufio.NewWriter(file) |
| 138 | + defer func() { |
| 139 | + err1 := w.Flush() |
| 140 | + if retErr == nil && err1 != nil { |
| 141 | + retErr = err1 |
| 142 | + } |
| 143 | + }() |
| 144 | + |
| 145 | + enc := yaml.NewEncoder(w) |
| 146 | + return enc.Encode(conf) |
140 | 147 | } |
0 commit comments