diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index f059431..8009fe4 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -28,10 +28,10 @@ jobs: - name: lint run: make lint - # - name: golangci-lint - # uses: https://github.com/golangci/golangci-lint-action@v6 - # with: - # version: v1.60 + - name: golangci-lint + uses: https://github.com/golangci/golangci-lint-action@v6 + with: + version: v1.60 - name: test id: build diff --git a/.golangci.yaml b/.golangci.yaml index 92471d4..0460a2f 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -95,7 +95,7 @@ linters: - sqlclosecheck - staticcheck - stylecheck - - tagalign + # - tagalign - tagliatelle - tenv - testableexamples diff --git a/cli.go b/cli.go index fbf4623..cd08d73 100644 --- a/cli.go +++ b/cli.go @@ -102,7 +102,7 @@ func (av *anyValue) Set(value string) error { case reflect.Uint64: return SetValueWithUintX(av.any, value, Uint64Size) default: - return fmt.Errorf("unsupported type: %s", kind.String()) + return fmt.Errorf("%w: %s", errUnsupportedType, kind.String()) } return nil @@ -192,14 +192,14 @@ func (c *Command) Init(i interface{}) error { ptrRef := reflect.ValueOf(i) if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { - return fmt.Errorf("expect a structure pointer type instead of %s", - ptrRef.Kind().String()) + return fmt.Errorf("%w: %s", + errExpectStructPointerInsteadOf, ptrRef.Kind().String()) } valueOfStruct := ptrRef.Elem() if valueOfStruct.Kind() != reflect.Struct { - return fmt.Errorf("expect a structure type instead of %s", - valueOfStruct.Kind().String()) + return fmt.Errorf("%w: %s", + errExpectStructPointerInsteadOf, valueOfStruct.Kind().String()) } return c.parseValue(valueOfStruct) @@ -273,7 +273,7 @@ func (c *Command) addFlag(value reflect.Value, field reflect.StructField) error sliceValue := newSliceValue(value, field.Tag.Get("separator")) c.FlagSet.Var(sliceValue, name, usage) default: - return fmt.Errorf("unsupported type: %s", kind.String()) + return fmt.Errorf("%w: %s", errUnsupportedType, kind.String()) } return nil diff --git a/config.go b/config.go index f98e5cb..a0b1abf 100644 --- a/config.go +++ b/config.go @@ -40,6 +40,15 @@ const ( PropConfigType = "properties" ) +var ( + errExpectStructPointerInsteadOf = errors.New("expect a structure pointer type instead of") + errFileNotFound = errors.New("file not found") + errNotImplemented = errors.New("not implemented") + errUnsupportedConfigFile = errors.New("unsupported config file") + errUnsupportedType = errors.New("unsupported type") + errValueCannotBeChanged = errors.New("value cannot be changed") +) + // ParseDefault parses the given structure, extract default value from its tag // and set structure with these values. // Normally, ParseDefault should be called before any other parsing functions @@ -48,14 +57,14 @@ func ParseDefault(i interface{}) error { ptrRef := reflect.ValueOf(i) if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { - return fmt.Errorf("expect a structure pointer type instead of %s", - ptrRef.Kind().String()) + return fmt.Errorf("%w: %s", + errExpectStructPointerInsteadOf, ptrRef.Kind().String()) } valueOfStruct := ptrRef.Elem() if valueOfStruct.Kind() != reflect.Struct { - return fmt.Errorf("expect a structure pointer type instead of %s", - valueOfStruct.Kind().String()) + return fmt.Errorf("%w: %s", + errExpectStructPointerInsteadOf, valueOfStruct.Kind().String()) } return parseValue(valueOfStruct) @@ -92,7 +101,7 @@ func parseValue(value reflect.Value) error { return err } -func setValue(value reflect.Value, defValue string, sf reflect.StructField) error { +func setValue(value reflect.Value, defValue string, field reflect.StructField) error { var err error switch value.Kind() { @@ -121,14 +130,14 @@ func setValue(value reflect.Value, defValue string, sf reflect.StructField) erro case reflect.Float64: err = SetValueWithFloatX(value, defValue, Float64Size) case reflect.Slice: - sp, ok := sf.Tag.Lookup("separator") + sp, ok := field.Tag.Lookup("separator") if !ok { sp = ":" } err = SetValueWithSlice(value, defValue, sp) default: - err = fmt.Errorf("unsupported type: %s", value.Kind().String()) + err = fmt.Errorf("%w: %s", errUnsupportedType, value.Kind().String()) } return err @@ -183,7 +192,7 @@ func ParseConfigFile(out interface{}, configFile string) error { case PropConfigType: err = parseProp(out, configFile) default: - err = fmt.Errorf("unsupported config file: %s", configFile) + err = fmt.Errorf("%w: %s", errUnsupportedConfigFile, configFile) } return err @@ -193,7 +202,7 @@ func ParseConfigFile(out interface{}, configFile string) error { func parseJSON(out interface{}, jsonFile string) error { raw, err := os.ReadFile(jsonFile) if err != nil { - return fmt.Errorf("open json config file: %s", err.Error()) + return fmt.Errorf("open json config file: %w", err) } if err := json.Unmarshal(raw, out); err != nil { @@ -207,7 +216,7 @@ func parseJSON(out interface{}, jsonFile string) error { func parseYaml(out interface{}, yamlFile string) error { raw, err := os.ReadFile(yamlFile) if err != nil { - return fmt.Errorf("open yaml config file: %s", err.Error()) + return fmt.Errorf("open yaml config file: %w", err) } if err := yaml.Unmarshal(raw, out); err != nil { @@ -219,7 +228,7 @@ func parseYaml(out interface{}, yamlFile string) error { // parseProp parses Properties file and set structure with its value func parseProp(_ interface{}, _ /* The propFile */ string) error { - return errors.New("properties config is not implemented") + return fmt.Errorf("%w: properties config", errNotImplemented) } // getDefaultConfigFile returns a existing default config file. The checking @@ -228,7 +237,7 @@ func parseProp(_ interface{}, _ /* The propFile */ string) error { func getDefaultConfigFile() (string, error) { exe, err := os.Executable() if err != nil { - return "", fmt.Errorf("find default config file: %s", err.Error()) + return "", fmt.Errorf("%w: %w", errFileNotFound, err) } path := filepath.Dir(exe) + string(filepath.Separator) @@ -251,7 +260,7 @@ func getDefaultConfigFile() (string, error) { return propConfig, nil } - return "", fmt.Errorf("default config file not found in path: %s", path) + return "", fmt.Errorf("default config %w in path: %s", errFileNotFound, path) } // getConfigFileType analyzes config file extension name and return @@ -267,5 +276,5 @@ func getConfigFileType(configFile string) (string, error) { return PropConfigType, nil } - return "", fmt.Errorf("unsupported file type: %s", configFile) + return "", fmt.Errorf("%w: %s", errUnsupportedConfigFile, configFile) } diff --git a/env.go b/env.go index b6aa375..015d6d5 100644 --- a/env.go +++ b/env.go @@ -51,14 +51,14 @@ func ParseEnvWith(i interface{}, prefix string) error { ptrRef := reflect.ValueOf(i) if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { - return fmt.Errorf("expect a structure pointer type instead of %s", - ptrRef.Kind().String()) + return fmt.Errorf("%w: %s", + errExpectStructPointerInsteadOf, ptrRef.Kind().String()) } valueOfStruct := ptrRef.Elem() if valueOfStruct.Kind() != reflect.Struct { - return fmt.Errorf("expect a structure pointer type instead of %s", - valueOfStruct.Kind().String()) + return fmt.Errorf("%w: %s", + errExpectStructPointerInsteadOf, valueOfStruct.Kind().String()) } return parseValueEnv(valueOfStruct, prefix) @@ -110,7 +110,7 @@ func setFieldValueEnv(value reflect.Value, field reflect.StructField, prefix str } if !value.CanSet() { - return fmt.Errorf("%s: can't be set", field.Name) + return fmt.Errorf("%w: %s", errValueCannotBeChanged, field.Name) } var err error @@ -151,11 +151,11 @@ func setFieldValueEnv(value reflect.Value, field reflect.StructField, prefix str err = SetValueWithSlice(value, envValue, sp) default: - return fmt.Errorf("unsupported type: %s", kind.String()) + return fmt.Errorf("%w: %s", errUnsupportedType, kind.String()) } if err != nil { - return fmt.Errorf("%s: %s", field.Name, err.Error()) + return fmt.Errorf("%s: %w", field.Name, err) } return nil diff --git a/utils.go b/utils.go index cee833f..768f914 100644 --- a/utils.go +++ b/utils.go @@ -105,7 +105,7 @@ func SetValueWithSlice(value reflect.Value, slice string, sep string) error { case reflect.Float64: err = SetValueWithFloatX(ele, data[index], Float64Size) default: - return fmt.Errorf("unsupported type: %s", kind.String()) + return fmt.Errorf("%w: %s", errUnsupportedType, kind.String()) } if err != nil {