@@ -9,31 +9,32 @@ import (
99 "path/filepath"
1010
1111 "golang.org/x/mod/semver"
12- yaml "gopkg.in/yaml.v3 "
12+ yaml "gopkg.in/yaml.v2 "
1313
1414 "github.com/conventionalcommit/commitlint/internal"
1515 "github.com/conventionalcommit/commitlint/internal/registry"
1616 "github.com/conventionalcommit/commitlint/lint"
1717)
1818
19- const (
20- // ConfigFile represent default config file name
21- ConfigFile = "commitlint.yaml"
22- )
19+ const commitlintConfig = "COMMITLINT_CONFIG"
20+
21+ var configFiles = []string {
22+ ".commitlint.yml" ,
23+ ".commitlint.yaml" ,
24+ "commitlint.yml" ,
25+ "commitlint.yaml" ,
26+ }
2327
24- // GetConfig gets the config path according to the precedence
25- // if needed parses given config file and returns config instance
26- func GetConfig ( confPath string ) ( * lint. Config , error ) {
27- confFilePath , useDefault , err := getConfigPath (confPath )
28+ // Parse parse given file in confPath, and return Config instance, error if any
29+ func Parse ( confPath string ) ( * lint. Config , error ) {
30+ confPath = filepath . Clean ( confPath )
31+ confBytes , err := os . ReadFile (confPath )
2832 if err != nil {
2933 return nil , err
3034 }
3135
32- if useDefault {
33- return defConf , nil
34- }
35-
36- conf , err := Parse (confFilePath )
36+ conf := & lint.Config {}
37+ err = yaml .UnmarshalStrict (confBytes , conf )
3738 if err != nil {
3839 return nil , err
3940 }
@@ -49,55 +50,18 @@ func GetConfig(confPath string) (*lint.Config, error) {
4950 return conf , nil
5051}
5152
52- // getConfigPath returns config file path following below order
53- // 1. commitlint.yaml in current directory
54- // 2. confFilePath parameter
55- // 3. use default config
56- func getConfigPath (confFilePath string ) (confPath string , isDefault bool , retErr error ) {
57- // get current directory
58- currentDir , err := os .Getwd ()
59- if err != nil {
60- return "" , false , err
61- }
62-
63- // check if conf file exists in current directory
64- currentDirConf := filepath .Join (currentDir , ConfigFile )
65- if _ , err1 := os .Stat (currentDirConf ); ! os .IsNotExist (err1 ) {
66- return currentDirConf , false , nil
67- }
68-
69- // if confFilePath empty,
70- // means no config in current directory or config flag is empty
71- // use default config
72- if confFilePath == "" {
73- return "" , true , nil
74- }
75- return filepath .Clean (confFilePath ), false , nil
76- }
77-
78- // Parse parse given file in confPath, and return Config instance, error if any
79- func Parse (confPath string ) (* lint.Config , error ) {
80- confPath = filepath .Clean (confPath )
81- confBytes , err := os .ReadFile (confPath )
82- if err != nil {
83- return nil , err
84- }
85-
86- conf := & lint.Config {}
87- err = yaml .Unmarshal (confBytes , conf )
88- if err != nil {
89- return nil , err
90- }
91- return conf , nil
92- }
93-
9453// Validate validates given config instance, it checks the following
9554// If formatters, rules are registered/known
9655// If arguments to rules are valid
9756// If version is valid and atleast minimum than commitlint version used
9857func Validate (conf * lint.Config ) []error {
9958 var errs []error
10059
60+ err := isValidVersion (conf .MinVersion )
61+ if err != nil {
62+ errs = append (errs , err )
63+ }
64+
10165 if conf .Formatter == "" {
10266 errs = append (errs , errors .New ("formatter is empty" ))
10367 } else {
@@ -107,16 +71,10 @@ func Validate(conf *lint.Config) []error {
10771 }
10872 }
10973
110- err := isValidVersion (conf .MinVersion )
111- if err != nil {
112- errs = append (errs , err )
113- }
114-
11574 for ruleName , r := range conf .Rules {
11675 // Check Severity Level of rule config
11776 switch r .Severity {
118- case lint .SeverityError :
119- case lint .SeverityWarn :
77+ case lint .SeverityError , lint .SeverityWarn :
12078 default :
12179 errs = append (errs , fmt .Errorf ("unknown severity level '%s' for rule '%s'" , r .Severity , ruleName ))
12280 }
@@ -136,6 +94,56 @@ func Validate(conf *lint.Config) []error {
13694 return errs
13795}
13896
97+ // LookupAndParse gets the config path according to the precedence
98+ // if exists, parses the config file and returns config instance
99+ func LookupAndParse () (* lint.Config , error ) {
100+ confFilePath , useDefault , err := lookupConfigPath ()
101+ if err != nil {
102+ return nil , err
103+ }
104+
105+ if useDefault {
106+ return defConf , nil
107+ }
108+
109+ conf , err := Parse (confFilePath )
110+ if err != nil {
111+ return nil , err
112+ }
113+ return conf , nil
114+ }
115+
116+ // lookupConfigPath returns config file path following below order
117+ // 1. env path
118+ // 2. commitlint.yaml in current directory
119+ // 3. use default config
120+ func lookupConfigPath () (confPath string , isDefault bool , retErr error ) {
121+ envConf := os .Getenv (commitlintConfig )
122+ if envConf != "" {
123+ envConf = filepath .Clean (envConf )
124+ if _ , err1 := os .Stat (envConf ); ! os .IsNotExist (err1 ) {
125+ return envConf , false , nil
126+ }
127+ }
128+
129+ // get current directory
130+ currentDir , err := os .Getwd ()
131+ if err != nil {
132+ return "" , false , err
133+ }
134+
135+ // check if conf file exists in current directory
136+ for _ , confFile := range configFiles {
137+ currentDirConf := filepath .Join (currentDir , confFile )
138+ if _ , err1 := os .Stat (currentDirConf ); ! os .IsNotExist (err1 ) {
139+ return currentDirConf , false , nil
140+ }
141+ }
142+
143+ // default config
144+ return "" , true , nil
145+ }
146+
139147// WriteToFile util func to write config object to given file
140148func WriteToFile (outFilePath string , conf * lint.Config ) (retErr error ) {
141149 f , err := os .Create (outFilePath )
@@ -158,6 +166,12 @@ func WriteToFile(outFilePath string, conf *lint.Config) (retErr error) {
158166 }()
159167
160168 enc := yaml .NewEncoder (w )
169+ defer func () {
170+ err := enc .Close ()
171+ if retErr == nil && err != nil {
172+ retErr = err
173+ }
174+ }()
161175 return enc .Encode (conf )
162176}
163177
0 commit comments