From dd311b9493be5152270e1017e28e2a0a784f9446 Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 13:28:57 +0300
Subject: [PATCH 01/10] 1. Added [EditorConfig](https://editorconfig.org/) 1.
Fixed the text formatting in the README
---
.editorconfig | 19 +++++++++++++++++++
.gitignore | 2 ++
README.md | 50 ++++++++++++++++++--------------------------------
3 files changed, 39 insertions(+), 32 deletions(-)
create mode 100644 .editorconfig
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..dab6d38d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+trim_trailing_whitespace = true
+max_line_length = 120
+
+[{Makefile,go.mod,go.sum,*.go}]
+insert_final_newline = true
+indent_size = tab
+indent_style = tab
+tab_width = 2
+
+[*.md]
+trim_trailing_whitespace = false
+indent_size = tab
+indent_style = space
+tab_width = 2
diff --git a/.gitignore b/.gitignore
index ca6a0ff8..9c2923c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ coverage.txt
bin
card.png
dist
+
+!.editorconfig
diff --git a/README.md b/README.md
index 6527dc14..0309001b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-
+
-
A simple, zero-dependencies library to parse environment variables into structs.
-
+
A simple, zero-dependencies library to parse environment variables into structs.
+
###### Getting started
@@ -18,8 +18,7 @@ err := env.Parse(&cfg)
cfg, err := env.ParseAs[config]()
```
-You can see the full documentation and list of examples at
-[pkg.go.dev](https://pkg.go.dev/github.com/caarlos0/env/v11).
+You can see the full documentation and list of examples at [pkg.go.dev](https://pkg.go.dev/github.com/caarlos0/env/v11).
---
@@ -27,7 +26,7 @@ You can see the full documentation and list of examples at
-
+
@@ -48,19 +47,15 @@ You can see the full documentation and list of examples at
- `Parse`: parse the current environment into a type
- `ParseAs`: parse the current environment into a type using generics
-- `ParseWithOptions`: parse the current environment into a type with custom
- options
-- `ParseAsithOptions`: parse the current environment into a type with custom
- options and using generics
+- `ParseWithOptions`: parse the current environment into a type with custom options
+- `ParseAsithOptions`: parse the current environment into a type with custom options and using generics
- `Must`: can be used to wrap `Parse.*` calls to panic on error
- `GetFieldParams`: get the `env` parsed options for a type
-- `GetFieldParamsWithOptions`: get the `env` parsed options for a type with
- custom options
+- `GetFieldParamsWithOptions`: get the `env` parsed options for a type with custom options
### Supported types
-Out of the box all built-in types are supported, plus a few others that
-are commonly used.
+Out of the box all built-in types are supported, plus a few others that are commonly used.
Complete list:
@@ -82,8 +77,7 @@ Complete list:
- `encoding.TextUnmarshaler`
- `url.URL`
-Pointers, slices and slices of pointers, and maps of those types are also
-supported.
+Pointers, slices and slices of pointers, and maps of those types are also supported.
You may also add custom parsers for your types.
@@ -91,15 +85,11 @@ You may also add custom parsers for your types.
The following tags are provided:
-- `env`: sets the environment variable name and optionally takes the tag options
- described below
+- `env`: sets the environment variable name and optionally takes the tag options described below
- `envDefault`: sets the default value for the field
-- `envPrefix`: can be used in a field that is a complex type to set a prefix to
- all environment variables used in it
-- `envSeparator`: sets the character to be used to separate items in slices and
- maps (default: `,`)
-- `envKeyValSeparator`: sets the character to be used to separate keys and their
- values in maps (default: `:`)
+- `envPrefix`: can be used in a field that is a complex type to set a prefix to all environment variables used in it
+- `envSeparator`: sets the character to be used to separate items in slices and maps (default: `,`)
+- `envKeyValSeparator`: sets the character to be used to separate keys and their values in maps (default: `:`)
### `env` tag options
@@ -118,20 +108,16 @@ There are a few options available in the functions that end with `WithOptions`:
- `Environment`: keys and values to be used instead of `os.Environ()`
- `TagName`: specifies another tag name to use rather than the default `env`
-- `RequiredIfNoDef`: set all `env` fields as required if they do not declare
- `envDefault`
-- `OnSet`: allows to hook into the `env` parsing and do something when a value
- is set
+- `RequiredIfNoDef`: set all `env` fields as required if they do not declare `envDefault`
+- `OnSet`: allows to hook into the `env` parsing and do something when a value is set
- `Prefix`: prefix to be used in all environment variables
- `UseFieldNameByDefault`: defines whether or not `env` should use the field name by default if the `env` key is missing
- `FuncMap`: custom parse functions for custom types
### Documentation and examples
-Examples are live in
-[pkg.go.dev](https://pkg.go.dev/github.com/caarlos0/env/v11),
-and also in the
-[example test file](./example_test.go).
+Examples are live in [pkg.go.dev](https://pkg.go.dev/github.com/caarlos0/env/v11),
+and also in the [example test file](./example_test.go).
## Badges
From e748170283b1d9d83729249bc28ad9efbc561645 Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 13:32:05 +0300
Subject: [PATCH 02/10] 1. Fixed the text formatting in the README
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 0309001b..cc9b489b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-
+
A simple, zero-dependencies library to parse environment variables into structs.
-
+
###### Getting started
From 517051155a1ba8f3a6ddb2415a640d063e41533f Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 13:34:45 +0300
Subject: [PATCH 03/10] 1. Partially rolled back text formatting edits in
README - GitHub does not work correctly with formatting
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index cc9b489b..c0b2a257 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
-
A simple, zero-dependencies library to parse environment variables into structs.
+ A simple, zero-dependencies library to parse environment variables into structs.
###### Getting started
From 6da32f510c6f7798ebcf5b8e8393e000336e91ae Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 14:19:12 +0300
Subject: [PATCH 04/10] Added EditorConfig linter in GitHub Actions
---
.github/workflows/lint.yml | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 90b0fe45..a26c4d1a 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,8 +1,15 @@
-name: golangci-lint
+name: linters
on:
push:
pull_request:
jobs:
+ editorconfig:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: editorconfig-checker/action-editorconfig-checker@main
+ - run: editorconfig-checker
+
golangci:
name: lint
runs-on: ubuntu-latest
From 8ca224dc89a98ceecb9bdbd73e24b28e9bf31ffe Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 15:31:35 +0300
Subject: [PATCH 05/10] Fixed the code based on comments from the EditorConfig
linter
---
.editorconfig | 14 +++++++++-
.github/workflows/build.yml | 2 +-
.gitignore | 2 --
env.go | 21 ++++++++++++---
env_test.go | 54 ++++++++++++++++++-------------------
env_tomap_windows_test.go | 3 ++-
error.go | 3 ++-
go.mod | 7 +++--
8 files changed, 68 insertions(+), 38 deletions(-)
diff --git a/.editorconfig b/.editorconfig
index dab6d38d..f0478a12 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,15 +5,27 @@ charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
max_line_length = 120
+ij_visual_guides = 100,120,150
-[{Makefile,go.mod,go.sum,*.go}]
+[{go.mod,go.sum,*.go}]
+insert_final_newline = true
+indent_size = tab
+indent_style = tab
+tab_width = 2
+
+[Makefile]
+max_line_length = off
insert_final_newline = true
indent_size = tab
indent_style = tab
tab_width = 2
[*.md]
+max_line_length = off
trim_trailing_whitespace = false
indent_size = tab
indent_style = space
tab_width = 2
+
+[.mailmap]
+max_line_length = off
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 49d3ea8c..571a1620 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -35,7 +35,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
- uses: goreleaser/goreleaser-action@v6
- if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest' && matrix.go-version == 'stable'
+ if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest' && matrix.go-version == 'stable' # editorconfig-checker-disable-line
with:
version: latest
distribution: goreleaser-pro
diff --git a/.gitignore b/.gitignore
index 9c2923c0..ca6a0ff8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,3 @@ coverage.txt
bin
card.png
dist
-
-!.editorconfig
diff --git a/env.go b/env.go
index 27776b89..e09ae6eb 100644
--- a/env.go
+++ b/env.go
@@ -112,7 +112,12 @@ type ParserFunc func(v string) (interface{}, error)
type OnSetFn func(tag string, value interface{}, isDefault bool)
// processFieldFn is a function which takes all information about a field and processes it.
-type processFieldFn func(refField reflect.Value, refTypeField reflect.StructField, opts Options, fieldParams FieldParams) error
+type processFieldFn func(
+ refField reflect.Value,
+ refTypeField reflect.StructField,
+ opts Options,
+ fieldParams FieldParams,
+) error
// Options for the parser.
type Options struct {
@@ -310,7 +315,12 @@ func doParse(ref reflect.Value, processField processFieldFn, opts Options) error
return agrErr
}
-func doParseField(refField reflect.Value, refTypeField reflect.StructField, processField processFieldFn, opts Options) error {
+func doParseField(
+ refField reflect.Value,
+ refTypeField reflect.StructField,
+ processField processFieldFn,
+ opts Options,
+) error {
if !refField.CanSet() {
return nil
}
@@ -537,7 +547,12 @@ func parseFieldParams(field reflect.StructField, opts Options) (FieldParams, err
func get(fieldParams FieldParams, opts Options) (val string, err error) {
var exists, isDefault bool
- val, exists, isDefault = getOr(fieldParams.Key, fieldParams.DefaultValue, fieldParams.HasDefaultValue, opts.Environment)
+ val, exists, isDefault = getOr(
+ fieldParams.Key,
+ fieldParams.DefaultValue,
+ fieldParams.HasDefaultValue,
+ opts.Environment,
+ )
if fieldParams.Expand {
val = os.Expand(val, opts.getRawEnv)
diff --git a/env_test.go b/env_test.go
index 1a567b44..de09c272 100644
--- a/env_test.go
+++ b/env_test.go
@@ -408,7 +408,7 @@ func TestParsesEnv_Map(t *testing.T) {
MapStringString map[string]string `env:"MAP_STRING_STRING" envSeparator:","`
MapStringInt64 map[string]int64 `env:"MAP_STRING_INT64"`
MapStringBool map[string]bool `env:"MAP_STRING_BOOL" envSeparator:";"`
- CustomSeparatorMapStringString map[string]string `env:"CUSTOM_SEPARATOR_MAP_STRING_STRING" envSeparator:"," envKeyValSeparator:"|"`
+ CustomSeparatorMapStringString map[string]string `env:"CUSTOM_SEPARATOR_MAP_STRING_STRING" envSeparator:"," envKeyValSeparator:"|"` // editorconfig-checker-disable-line
}
mss := map[string]string{
@@ -614,7 +614,7 @@ func TestParsesEnvInnerFails(t *testing.T) {
}
t.Setenv("NUMBER", "not-a-number")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -630,7 +630,7 @@ func TestParsesEnvInnerFailsMultipleErrors(t *testing.T) {
}
t.Setenv("NUMBER", "not-a-number")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax; required environment variable "AGE" is not set`)
+ isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax; required environment variable "AGE" is not set`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
@@ -648,7 +648,7 @@ func TestParsesEnvInnerInvalid(t *testing.T) {
InnerStruct: &InnerStruct{},
}
err := Parse(&cfg)
- isErrorWithMessage(t, err, `env: parse error on field "Number" of type "uint": strconv.ParseUint: parsing "-547": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Number" of type "uint": strconv.ParseUint: parsing "-547": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -691,49 +691,49 @@ func TestPassReference(t *testing.T) {
func TestInvalidBool(t *testing.T) {
t.Setenv("BOOL", "should-be-a-bool")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Bool" of type "bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax; parse error on field "BoolPtr" of type "*bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Bool" of type "bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax; parse error on field "BoolPtr" of type "*bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidInt(t *testing.T) {
t.Setenv("INT", "should-be-an-int")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Int" of type "int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax; parse error on field "IntPtr" of type "*int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Int" of type "int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax; parse error on field "IntPtr" of type "*int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidUint(t *testing.T) {
t.Setenv("UINT", "-44")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Uint" of type "uint": strconv.ParseUint: parsing "-44": invalid syntax; parse error on field "UintPtr" of type "*uint": strconv.ParseUint: parsing "-44": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Uint" of type "uint": strconv.ParseUint: parsing "-44": invalid syntax; parse error on field "UintPtr" of type "*uint": strconv.ParseUint: parsing "-44": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidFloat32(t *testing.T) {
t.Setenv("FLOAT32", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Float32" of type "float32": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float32Ptr" of type "*float32": strconv.ParseFloat: parsing "AAA": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Float32" of type "float32": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float32Ptr" of type "*float32": strconv.ParseFloat: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidFloat64(t *testing.T) {
t.Setenv("FLOAT64", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Float64" of type "float64": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float64Ptr" of type "*float64": strconv.ParseFloat: parsing "AAA": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Float64" of type "float64": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float64Ptr" of type "*float64": strconv.ParseFloat: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidUint64(t *testing.T) {
t.Setenv("UINT64", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Uint64" of type "uint64": strconv.ParseUint: parsing "AAA": invalid syntax; parse error on field "Uint64Ptr" of type "*uint64": strconv.ParseUint: parsing "AAA": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Uint64" of type "uint64": strconv.ParseUint: parsing "AAA": invalid syntax; parse error on field "Uint64Ptr" of type "*uint64": strconv.ParseUint: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidInt64(t *testing.T) {
t.Setenv("INT64", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Int64" of type "int64": strconv.ParseInt: parsing "AAA": invalid syntax; parse error on field "Int64Ptr" of type "*int64": strconv.ParseInt: parsing "AAA": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "Int64" of type "int64": strconv.ParseInt: parsing "AAA": invalid syntax; parse error on field "Int64Ptr" of type "*int64": strconv.ParseInt: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -743,7 +743,7 @@ func TestInvalidInt64Slice(t *testing.T) {
BadFloats []int64 `env:"BADINTS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]int64": strconv.ParseInt: parsing "A": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]int64": strconv.ParseInt: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -753,7 +753,7 @@ func TestInvalidUInt64Slice(t *testing.T) {
BadFloats []uint64 `env:"BADINTS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]uint64": strconv.ParseUint: parsing "A": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]uint64": strconv.ParseUint: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -763,7 +763,7 @@ func TestInvalidFloat32Slice(t *testing.T) {
BadFloats []float32 `env:"BADFLOATS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float32": strconv.ParseFloat: parsing "A": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float32": strconv.ParseFloat: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -773,7 +773,7 @@ func TestInvalidFloat64Slice(t *testing.T) {
BadFloats []float64 `env:"BADFLOATS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float64": strconv.ParseFloat: parsing "A": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float64": strconv.ParseFloat: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -783,21 +783,21 @@ func TestInvalidBoolsSlice(t *testing.T) {
BadBools []bool `env:"BADBOOLS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadBools" of type "[]bool": strconv.ParseBool: parsing "faaaalse": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "BadBools" of type "[]bool": strconv.ParseBool: parsing "faaaalse": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidDuration(t *testing.T) {
t.Setenv("DURATION", "should-be-a-valid-duration")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Duration" of type "time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"; parse error on field "DurationPtr" of type "*time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"`)
+ isErrorWithMessage(t, err, `env: parse error on field "Duration" of type "time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"; parse error on field "DurationPtr" of type "*time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidDurations(t *testing.T) {
t.Setenv("DURATIONS", "1s,contains-an-invalid-duration,3s")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Durations" of type "[]time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"; parse error on field "DurationPtrs" of type "[]*time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"`)
+ isErrorWithMessage(t, err, `env: parse error on field "Durations" of type "[]time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"; parse error on field "DurationPtrs" of type "[]*time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -813,7 +813,7 @@ func TestParseStructWithInvalidFieldKind(t *testing.T) {
}
t.Setenv("BLAH", "a")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "WontWorkByte" of type "uint8": strconv.ParseUint: parsing "a": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "WontWorkByte" of type "uint8": strconv.ParseUint: parsing "a": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -835,7 +835,7 @@ func TestBadSeparator(t *testing.T) {
t.Setenv("WONTWORK", "1,2,3,4")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "WontWork" of type "[]int": strconv.ParseInt: parsing "1,2,3,4": invalid syntax`)
+ isErrorWithMessage(t, err, `env: parse error on field "WontWork" of type "[]int": strconv.ParseInt: parsing "1,2,3,4": invalid syntax`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1320,7 +1320,7 @@ func TestTextUnmarshalerError(t *testing.T) {
}
t.Setenv("UNMARSHALER", "invalid")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "Unmarshaler" of type "env.unmarshaler": time: invalid duration "invalid"`)
+ isErrorWithMessage(t, err, `env: parse error on field "Unmarshaler" of type "env.unmarshaler": time: invalid duration "invalid"`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1330,7 +1330,7 @@ func TestTextUnmarshalersError(t *testing.T) {
}
t.Setenv("UNMARSHALERS", "1s,invalid")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "Unmarshalers" of type "[]env.unmarshaler": time: invalid duration "invalid"`)
+ isErrorWithMessage(t, err, `env: parse error on field "Unmarshalers" of type "[]env.unmarshaler": time: invalid duration "invalid"`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1350,7 +1350,7 @@ func TestParseInvalidURL(t *testing.T) {
t.Setenv("EXAMPLE_URL_2", "nope://s s/")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "ExampleURL" of type "url.URL": unable to parse URL: parse "nope://s s/": invalid character " " in host name`)
+ isErrorWithMessage(t, err, `env: parse error on field "ExampleURL" of type "url.URL": unable to parse URL: parse "nope://s s/": invalid character " " in host name`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1452,7 +1452,7 @@ func TestFileBadFile(t *testing.T) {
}
err := Parse(&config{})
- isErrorWithMessage(t, err, fmt.Sprintf(`env: could not load content of file "%s" from variable SECRET_KEY: open %s: %s`, filename, filename, oserr))
+ isErrorWithMessage(t, err, fmt.Sprintf(`env: could not load content of file "%s" from variable SECRET_KEY: open %s: %s`, filename, filename, oserr)) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, LoadFileContentError{}))
}
@@ -1524,7 +1524,7 @@ func TestRequiredIfNoDefOption(t *testing.T) {
t.Run("missing", func(t *testing.T) {
err := ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
- isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; required environment variable "FRUIT" is not set`)
+ isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; required environment variable "FRUIT" is not set`) // editorconfig-checker-disable-line
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
t.Setenv("NAME", "John")
err = ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
@@ -1584,7 +1584,7 @@ func TestPrefix(t *testing.T) {
Clean Config
}
cfg := ComplexConfig{}
- isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_HOME": "/foo", "BAR_HOME": "/bar", "HOME": "/clean"}}))
+ isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_HOME": "/foo", "BAR_HOME": "/bar", "HOME": "/clean"}})) // editorconfig-checker-disable-line
isEqual(t, "/foo", cfg.Foo.Home)
isEqual(t, "/bar", cfg.Bar.Home)
isEqual(t, "/clean", cfg.Clean.Home)
@@ -1605,7 +1605,7 @@ func TestPrefixPointers(t *testing.T) {
Bar: &Test{},
Clean: &Test{},
}
- isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_TEST": "kek", "BAR_TEST": "lel", "TEST": "clean"}}))
+ isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_TEST": "kek", "BAR_TEST": "lel", "TEST": "clean"}})) // editorconfig-checker-disable-line
isEqual(t, "kek", cfg.Foo.Str)
isEqual(t, "lel", cfg.Bar.Str)
isEqual(t, "clean", cfg.Clean.Str)
diff --git a/env_tomap_windows_test.go b/env_tomap_windows_test.go
index dc1458b3..d8efdc64 100644
--- a/env_tomap_windows_test.go
+++ b/env_tomap_windows_test.go
@@ -4,7 +4,8 @@ package env
import "testing"
-// On Windows, environment variables can start with '='. This test verifies this behavior without relying on a Windows environment.
+// On Windows, environment variables can start with '='.
+// This test verifies this behavior without relying on a Windows environment.
// See env_windows.go in the Go source: https://github.com/golang/go/blob/master/src/syscall/env_windows.go#L58
func TestToMapWindows(t *testing.T) {
envVars := []string{"=::=::\\", "=C:=C:\\test", "VAR=REGULARVAR", "FOO=", "BAR"}
diff --git a/error.go b/error.go
index 156ca3ec..b14857f1 100644
--- a/error.go
+++ b/error.go
@@ -6,7 +6,8 @@ import (
"strings"
)
-// An aggregated error wrapper to combine gathered errors. This allows either to display all errors or convert them individually
+// An aggregated error wrapper to combine gathered errors.
+// This allows either to display all errors or convert them individually
// List of the available errors
// ParseError
// NotStructPtrError
diff --git a/go.mod b/go.mod
index affcbd49..92cabd79 100644
--- a/go.mod
+++ b/go.mod
@@ -1,7 +1,10 @@
module github.com/caarlos0/env/v11
-retract v11.0.1 // v11.0.1 accidentally introduced a breaking change regarding the behavior of nil pointers. You can now chose to auto-initialize them by setting the `init` tag option.
+// v11.0.1 accidentally introduced a breaking change regarding the behavior of nil pointers.
+// You can now chose to auto-initialize them by setting the `init` tag option.
+retract v11.0.1
-retract v11.2.0 // v11.2.0 accidentally introduced a breaking change regarding the behavior of nil slices of complex types.
+// v11.2.0 accidentally introduced a breaking change regarding the behavior of nil slices of complex types.
+retract v11.2.0
go 1.18
From 9bc8f424c5afb25f5f87a129375e5672e181afb5 Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 19:46:40 +0300
Subject: [PATCH 06/10] Replaced the linter and corrected the comments from the
new linter
---
.github/workflows/build.yml | 2 +-
.github/workflows/lint.yml | 9 +-----
.golangci.yml | 14 +++++++++
env_test.go | 62 ++++++++++++++++++-------------------
error.go | 2 +-
5 files changed, 48 insertions(+), 41 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 571a1620..49d3ea8c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -35,7 +35,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
- uses: goreleaser/goreleaser-action@v6
- if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest' && matrix.go-version == 'stable' # editorconfig-checker-disable-line
+ if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest' && matrix.go-version == 'stable'
with:
version: latest
distribution: goreleaser-pro
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index a26c4d1a..90b0fe45 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,15 +1,8 @@
-name: linters
+name: golangci-lint
on:
push:
pull_request:
jobs:
- editorconfig:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: editorconfig-checker/action-editorconfig-checker@main
- - run: editorconfig-checker
-
golangci:
name: lint
runs-on: ubuntu-latest
diff --git a/.golangci.yml b/.golangci.yml
index ff791f86..73db6131 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,3 +1,16 @@
+linters-settings:
+ revive:
+ rules:
+ - name: line-length-limit
+ arguments: [120]
+
+issues:
+ exclude-rules:
+ - path: _test\.go
+ linters:
+ - revive
+ text: "line-length-limit:"
+
linters:
enable:
- thelper
@@ -6,3 +19,4 @@ linters:
- unconvert
- unparam
- wastedassign
+ - revive
diff --git a/env_test.go b/env_test.go
index de09c272..1d90b952 100644
--- a/env_test.go
+++ b/env_test.go
@@ -408,7 +408,7 @@ func TestParsesEnv_Map(t *testing.T) {
MapStringString map[string]string `env:"MAP_STRING_STRING" envSeparator:","`
MapStringInt64 map[string]int64 `env:"MAP_STRING_INT64"`
MapStringBool map[string]bool `env:"MAP_STRING_BOOL" envSeparator:";"`
- CustomSeparatorMapStringString map[string]string `env:"CUSTOM_SEPARATOR_MAP_STRING_STRING" envSeparator:"," envKeyValSeparator:"|"` // editorconfig-checker-disable-line
+ CustomSeparatorMapStringString map[string]string `env:"CUSTOM_SEPARATOR_MAP_STRING_STRING" envSeparator:"," envKeyValSeparator:"|"`
}
mss := map[string]string{
@@ -467,7 +467,7 @@ func TestParseCustomMapType(t *testing.T) {
var cfg config
isNoErr(t, ParseWithOptions(&cfg, Options{FuncMap: map[reflect.Type]ParserFunc{
- reflect.TypeOf(custommap{}): func(value string) (interface{}, error) {
+ reflect.TypeOf(custommap{}): func(_ string) (interface{}, error) {
return custommap(map[string]bool{}), nil
},
}}))
@@ -529,7 +529,7 @@ func TestParseMapCustomKeyTypeError(t *testing.T) {
var cfg config
err := ParseWithOptions(&cfg, Options{FuncMap: map[reflect.Type]ParserFunc{
- reflect.TypeOf(CustomKey("")): func(value string) (interface{}, error) {
+ reflect.TypeOf(CustomKey("")): func(_ string) (interface{}, error) {
return nil, fmt.Errorf("custom error")
},
}})
@@ -547,7 +547,7 @@ func TestParseMapCustomValueTypeError(t *testing.T) {
var cfg config
err := ParseWithOptions(&cfg, Options{FuncMap: map[reflect.Type]ParserFunc{
- reflect.TypeOf(Customval("")): func(value string) (interface{}, error) {
+ reflect.TypeOf(Customval("")): func(_ string) (interface{}, error) {
return nil, fmt.Errorf("custom error")
},
}})
@@ -614,7 +614,7 @@ func TestParsesEnvInnerFails(t *testing.T) {
}
t.Setenv("NUMBER", "not-a-number")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -630,7 +630,7 @@ func TestParsesEnvInnerFailsMultipleErrors(t *testing.T) {
}
t.Setenv("NUMBER", "not-a-number")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax; required environment variable "AGE" is not set`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax; required environment variable "AGE" is not set`)
isTrue(t, errors.Is(err, ParseError{}))
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
@@ -648,7 +648,7 @@ func TestParsesEnvInnerInvalid(t *testing.T) {
InnerStruct: &InnerStruct{},
}
err := Parse(&cfg)
- isErrorWithMessage(t, err, `env: parse error on field "Number" of type "uint": strconv.ParseUint: parsing "-547": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Number" of type "uint": strconv.ParseUint: parsing "-547": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -691,49 +691,49 @@ func TestPassReference(t *testing.T) {
func TestInvalidBool(t *testing.T) {
t.Setenv("BOOL", "should-be-a-bool")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Bool" of type "bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax; parse error on field "BoolPtr" of type "*bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Bool" of type "bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax; parse error on field "BoolPtr" of type "*bool": strconv.ParseBool: parsing "should-be-a-bool": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidInt(t *testing.T) {
t.Setenv("INT", "should-be-an-int")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Int" of type "int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax; parse error on field "IntPtr" of type "*int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Int" of type "int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax; parse error on field "IntPtr" of type "*int": strconv.ParseInt: parsing "should-be-an-int": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidUint(t *testing.T) {
t.Setenv("UINT", "-44")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Uint" of type "uint": strconv.ParseUint: parsing "-44": invalid syntax; parse error on field "UintPtr" of type "*uint": strconv.ParseUint: parsing "-44": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Uint" of type "uint": strconv.ParseUint: parsing "-44": invalid syntax; parse error on field "UintPtr" of type "*uint": strconv.ParseUint: parsing "-44": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidFloat32(t *testing.T) {
t.Setenv("FLOAT32", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Float32" of type "float32": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float32Ptr" of type "*float32": strconv.ParseFloat: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Float32" of type "float32": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float32Ptr" of type "*float32": strconv.ParseFloat: parsing "AAA": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidFloat64(t *testing.T) {
t.Setenv("FLOAT64", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Float64" of type "float64": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float64Ptr" of type "*float64": strconv.ParseFloat: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Float64" of type "float64": strconv.ParseFloat: parsing "AAA": invalid syntax; parse error on field "Float64Ptr" of type "*float64": strconv.ParseFloat: parsing "AAA": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidUint64(t *testing.T) {
t.Setenv("UINT64", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Uint64" of type "uint64": strconv.ParseUint: parsing "AAA": invalid syntax; parse error on field "Uint64Ptr" of type "*uint64": strconv.ParseUint: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Uint64" of type "uint64": strconv.ParseUint: parsing "AAA": invalid syntax; parse error on field "Uint64Ptr" of type "*uint64": strconv.ParseUint: parsing "AAA": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidInt64(t *testing.T) {
t.Setenv("INT64", "AAA")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Int64" of type "int64": strconv.ParseInt: parsing "AAA": invalid syntax; parse error on field "Int64Ptr" of type "*int64": strconv.ParseInt: parsing "AAA": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Int64" of type "int64": strconv.ParseInt: parsing "AAA": invalid syntax; parse error on field "Int64Ptr" of type "*int64": strconv.ParseInt: parsing "AAA": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -743,7 +743,7 @@ func TestInvalidInt64Slice(t *testing.T) {
BadFloats []int64 `env:"BADINTS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]int64": strconv.ParseInt: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]int64": strconv.ParseInt: parsing "A": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -753,7 +753,7 @@ func TestInvalidUInt64Slice(t *testing.T) {
BadFloats []uint64 `env:"BADINTS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]uint64": strconv.ParseUint: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]uint64": strconv.ParseUint: parsing "A": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -763,7 +763,7 @@ func TestInvalidFloat32Slice(t *testing.T) {
BadFloats []float32 `env:"BADFLOATS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float32": strconv.ParseFloat: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float32": strconv.ParseFloat: parsing "A": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -773,7 +773,7 @@ func TestInvalidFloat64Slice(t *testing.T) {
BadFloats []float64 `env:"BADFLOATS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float64": strconv.ParseFloat: parsing "A": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "BadFloats" of type "[]float64": strconv.ParseFloat: parsing "A": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -783,21 +783,21 @@ func TestInvalidBoolsSlice(t *testing.T) {
BadBools []bool `env:"BADBOOLS"`
}
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "BadBools" of type "[]bool": strconv.ParseBool: parsing "faaaalse": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "BadBools" of type "[]bool": strconv.ParseBool: parsing "faaaalse": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidDuration(t *testing.T) {
t.Setenv("DURATION", "should-be-a-valid-duration")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Duration" of type "time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"; parse error on field "DurationPtr" of type "*time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Duration" of type "time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"; parse error on field "DurationPtr" of type "*time.Duration": unable to parse duration: time: invalid duration "should-be-a-valid-duration"`)
isTrue(t, errors.Is(err, ParseError{}))
}
func TestInvalidDurations(t *testing.T) {
t.Setenv("DURATIONS", "1s,contains-an-invalid-duration,3s")
err := Parse(&Config{})
- isErrorWithMessage(t, err, `env: parse error on field "Durations" of type "[]time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"; parse error on field "DurationPtrs" of type "[]*time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Durations" of type "[]time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"; parse error on field "DurationPtrs" of type "[]*time.Duration": unable to parse duration: time: invalid duration "contains-an-invalid-duration"`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -813,7 +813,7 @@ func TestParseStructWithInvalidFieldKind(t *testing.T) {
}
t.Setenv("BLAH", "a")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "WontWorkByte" of type "uint8": strconv.ParseUint: parsing "a": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "WontWorkByte" of type "uint8": strconv.ParseUint: parsing "a": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -835,7 +835,7 @@ func TestBadSeparator(t *testing.T) {
t.Setenv("WONTWORK", "1,2,3,4")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "WontWork" of type "[]int": strconv.ParseInt: parsing "1,2,3,4": invalid syntax`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "WontWork" of type "[]int": strconv.ParseInt: parsing "1,2,3,4": invalid syntax`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1116,7 +1116,7 @@ func TestCustomParserError(t *testing.T) {
name string
}
- customParserFunc := func(v string) (interface{}, error) {
+ customParserFunc := func(_ string) (interface{}, error) {
return nil, errors.New("something broke")
}
@@ -1320,7 +1320,7 @@ func TestTextUnmarshalerError(t *testing.T) {
}
t.Setenv("UNMARSHALER", "invalid")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "Unmarshaler" of type "env.unmarshaler": time: invalid duration "invalid"`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Unmarshaler" of type "env.unmarshaler": time: invalid duration "invalid"`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1330,7 +1330,7 @@ func TestTextUnmarshalersError(t *testing.T) {
}
t.Setenv("UNMARSHALERS", "1s,invalid")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "Unmarshalers" of type "[]env.unmarshaler": time: invalid duration "invalid"`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "Unmarshalers" of type "[]env.unmarshaler": time: invalid duration "invalid"`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1350,7 +1350,7 @@ func TestParseInvalidURL(t *testing.T) {
t.Setenv("EXAMPLE_URL_2", "nope://s s/")
err := Parse(&config{})
- isErrorWithMessage(t, err, `env: parse error on field "ExampleURL" of type "url.URL": unable to parse URL: parse "nope://s s/": invalid character " " in host name`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: parse error on field "ExampleURL" of type "url.URL": unable to parse URL: parse "nope://s s/": invalid character " " in host name`)
isTrue(t, errors.Is(err, ParseError{}))
}
@@ -1452,7 +1452,7 @@ func TestFileBadFile(t *testing.T) {
}
err := Parse(&config{})
- isErrorWithMessage(t, err, fmt.Sprintf(`env: could not load content of file "%s" from variable SECRET_KEY: open %s: %s`, filename, filename, oserr)) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, fmt.Sprintf(`env: could not load content of file "%s" from variable SECRET_KEY: open %s: %s`, filename, filename, oserr))
isTrue(t, errors.Is(err, LoadFileContentError{}))
}
@@ -1524,7 +1524,7 @@ func TestRequiredIfNoDefOption(t *testing.T) {
t.Run("missing", func(t *testing.T) {
err := ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
- isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; required environment variable "FRUIT" is not set`) // editorconfig-checker-disable-line
+ isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; required environment variable "FRUIT" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
t.Setenv("NAME", "John")
err = ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
@@ -1584,7 +1584,7 @@ func TestPrefix(t *testing.T) {
Clean Config
}
cfg := ComplexConfig{}
- isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_HOME": "/foo", "BAR_HOME": "/bar", "HOME": "/clean"}})) // editorconfig-checker-disable-line
+ isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_HOME": "/foo", "BAR_HOME": "/bar", "HOME": "/clean"}}))
isEqual(t, "/foo", cfg.Foo.Home)
isEqual(t, "/bar", cfg.Bar.Home)
isEqual(t, "/clean", cfg.Clean.Home)
@@ -1605,7 +1605,7 @@ func TestPrefixPointers(t *testing.T) {
Bar: &Test{},
Clean: &Test{},
}
- isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_TEST": "kek", "BAR_TEST": "lel", "TEST": "clean"}})) // editorconfig-checker-disable-line
+ isNoErr(t, ParseWithOptions(&cfg, Options{Environment: map[string]string{"FOO_TEST": "kek", "BAR_TEST": "lel", "TEST": "clean"}}))
isEqual(t, "kek", cfg.Foo.Str)
isEqual(t, "lel", cfg.Bar.Str)
isEqual(t, "clean", cfg.Clean.Str)
diff --git a/error.go b/error.go
index b14857f1..8cec505e 100644
--- a/error.go
+++ b/error.go
@@ -106,7 +106,7 @@ func (e NoSupportedTagOptionError) Error() string {
// This error occurs when the required variable is not set
// Read about required fields: https://github.com/caarlos0/env#required-fields
-type EnvVarIsNotSetError struct {
+type EnvVarIsNotSetError struct { //nolint:revive // FIXME https://github.com/caarlos0/env/issues/328
Key string
}
From 1743abf14f4a072ae638c8aaecb684a8b35c46f6 Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 20:31:16 +0300
Subject: [PATCH 07/10] Revert EditorConfig linter
---
.github/workflows/build.yml | 2 +-
.github/workflows/lint.yml | 9 ++++++++-
env_test.go | 1 +
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 49d3ea8c..571a1620 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -35,7 +35,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
- uses: goreleaser/goreleaser-action@v6
- if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest' && matrix.go-version == 'stable'
+ if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest' && matrix.go-version == 'stable' # editorconfig-checker-disable-line
with:
version: latest
distribution: goreleaser-pro
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 90b0fe45..a26c4d1a 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,8 +1,15 @@
-name: golangci-lint
+name: linters
on:
push:
pull_request:
jobs:
+ editorconfig:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: editorconfig-checker/action-editorconfig-checker@main
+ - run: editorconfig-checker
+
golangci:
name: lint
runs-on: ubuntu-latest
diff --git a/env_test.go b/env_test.go
index 1d90b952..8784be39 100644
--- a/env_test.go
+++ b/env_test.go
@@ -1,3 +1,4 @@
+// editorconfig-checker-disable-file
package env
import (
From b55e8c75dc0ee10c4e16e8683d8de4026dcce3ec Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Thu, 22 Aug 2024 21:47:44 +0300
Subject: [PATCH 08/10] Fixer review comments
---
.editorconfig | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.editorconfig b/.editorconfig
index f0478a12..f03fc66f 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,7 +5,9 @@ charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
max_line_length = 120
-ij_visual_guides = 100,120,150
+# visual setting for intelliJ IDE, no consequences on code validation
+# https://www.jetbrains.com/help/idea/editorconfig.html
+ij_visual_guides = 100, 120, 150
[{go.mod,go.sum,*.go}]
insert_final_newline = true
From 901bdff9869f5349be8459981900468d10496b20 Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Sat, 24 Aug 2024 23:14:45 +0300
Subject: [PATCH 09/10] Fixed review comments
---
.editorconfig | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/.editorconfig b/.editorconfig
index f03fc66f..679ee238 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,26 +1,21 @@
-root = true
-
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
max_line_length = 120
-# visual setting for intelliJ IDE, no consequences on code validation
-# https://www.jetbrains.com/help/idea/editorconfig.html
-ij_visual_guides = 100, 120, 150
[{go.mod,go.sum,*.go}]
insert_final_newline = true
indent_size = tab
indent_style = tab
-tab_width = 2
+tab_width = 4
[Makefile]
max_line_length = off
insert_final_newline = true
indent_size = tab
indent_style = tab
-tab_width = 2
+tab_width = 4
[*.md]
max_line_length = off
From 84a2f9b1c546c3bf46c5a08cced5d08449b4b5ca Mon Sep 17 00:00:00 2001
From: Viktor Alenkov
Date: Sat, 24 Aug 2024 23:15:47 +0300
Subject: [PATCH 10/10] Fixed review comments
---
.editorconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.editorconfig b/.editorconfig
index 679ee238..0d3bd399 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -25,4 +25,4 @@ indent_style = space
tab_width = 2
[.mailmap]
-max_line_length = off
\ No newline at end of file
+max_line_length = off