Skip to content

Commit 471de08

Browse files
committed
docs: refresh and update style
1 parent af40b11 commit 471de08

File tree

6 files changed

+54
-105
lines changed

6 files changed

+54
-105
lines changed

env.go

Lines changed: 35 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,21 @@ import (
1111
"strings"
1212
)
1313

14-
// ErrInvalidArgument is returned when the argument provided to
15-
// [Load]/[LoadFrom] is invalid.
14+
// ErrInvalidArgument is returned when the argument provided to [Load]/[LoadFrom] is invalid.
1615
var ErrInvalidArgument = errors.New("env: argument must be a non-nil struct pointer")
1716

18-
// ErrEmptyTagName is returned when the `env` tag is found but the name of the
19-
// environment variable is empty.
17+
// ErrEmptyTagName is returned when the `env` tag is found but the name of the environment variable is empty.
2018
var ErrEmptyTagName = errors.New("env: empty tag name is not allowed")
2119

22-
// ErrUnsupportedType is returned when the provided struct contains a field of
23-
// an unsupported type.
20+
// ErrUnsupportedType is returned when the provided struct contains a field of an unsupported type.
2421
var ErrUnsupportedType = errors.New("env: unsupported type")
2522

26-
// ErrInvalidTagOption is returned when the `env` tag contains an invalid
27-
// option, e.g. `env:"VAR,invalid"`.
23+
// ErrInvalidTagOption is returned when the `env` tag contains an invalid option, e.g. `env:"VAR,invalid"`.
2824
var ErrInvalidTagOption = errors.New("env: invalid tag option")
2925

30-
// NotSetError is returned when environment variables are marked as required but
31-
// not set.
26+
// NotSetError is returned when environment variables are marked as required but not set.
3227
type NotSetError struct {
33-
// Names is a slice of the names of the missing required environment
34-
// variables.
28+
// Names is a slice of the names of the missing required environment variables.
3529
Names []string
3630
}
3731

@@ -40,15 +34,13 @@ func (e *NotSetError) Error() string {
4034
return fmt.Sprintf("env: %v are required but not set", e.Names)
4135
}
4236

43-
// Load loads environment variables into the provided struct using the [OS]
44-
// [Provider] as their source. To specify a custom [Provider], use the
45-
// [LoadFrom] function. dst must be a non-nil struct pointer, otherwise Load
46-
// returns [ErrInvalidArgument].
37+
// Load loads environment variables into the provided struct using the [OS] [Provider] as their source.
38+
// To specify a custom [Provider], use the [LoadFrom] function.
39+
// dst must be a non-nil struct pointer, otherwise Load returns [ErrInvalidArgument].
4740
//
48-
// The struct fields must have the `env:"VAR"` struct tag, where VAR is the name
49-
// of the corresponding environment variable. Unexported fields are ignored. If
50-
// the tag is found but the name of the environment variable is empty, the
51-
// error will be [ErrEmptyTagName].
41+
// The struct fields must have the `env:"VAR"` struct tag, where VAR is the name of the corresponding environment variable.
42+
// Unexported fields are ignored.
43+
// If the tag is found but the name of the environment variable is empty, the error will be [ErrEmptyTagName].
5244
//
5345
// # Supported types
5446
//
@@ -60,33 +52,28 @@ func (e *NotSetError) Error() string {
6052
// - [encoding.TextUnmarshaler]
6153
// - slices of any type above (space is the default separator for values)
6254
//
63-
// See the [strconv].Parse* functions for parsing rules. Implementing the
64-
// [encoding.TextUnmarshaler] interface is enough to use any user-defined type.
65-
// Nested structs of any depth level are supported, only the leaves of the
66-
// config tree must have the `env` tag. If a field of an unsupported type is
67-
// found, the error will be [ErrUnsupportedType].
55+
// See the [strconv].Parse* functions for parsing rules.
56+
// Implementing the [encoding.TextUnmarshaler] interface is enough to use any user-defined type.
57+
// Nested structs of any depth level are supported, only the leaves of the config tree must have the `env` tag.
58+
// If a field of an unsupported type is found, the error will be [ErrUnsupportedType].
6859
//
6960
// # Default values
7061
//
71-
// Default values can be specified either using the `default` struct tag (has a
72-
// higher priority) or by initializing the struct fields directly.
62+
// Default values can be specified either using the `default` struct tag (has a higher priority) or by initializing the struct fields directly.
7363
//
7464
// # Per-variable options
7565
//
76-
// The name of the environment variable can be followed by comma-separated
77-
// options in the form of `env:"VAR,option1,option2,..."`:
66+
// The name of the environment variable can be followed by comma-separated options in the form of `env:"VAR,option1,option2,..."`:
7867
//
7968
// - required: marks the environment variable as required
8069
// - expand: expands the value of the environment variable using [os.Expand]
8170
//
82-
// If environment variables are marked as required but not set, an error of type
83-
// [NotSetError] will be returned. If the tag contains an invalid option, the
84-
// error will be [ErrInvalidTagOption].
71+
// If environment variables are marked as required but not set, an error of type [NotSetError] will be returned.
72+
// If the tag contains an invalid option, the error will be [ErrInvalidTagOption].
8573
//
8674
// # Global options
8775
//
88-
// In addition to the per-variable options, [env] also supports global options
89-
// that apply to all variables:
76+
// In addition to the per-variable options, [env] also supports global options that apply to all variables:
9077
//
9178
// - [WithPrefix]: sets prefix for each environment variable
9279
// - [WithSliceSeparator]: sets custom separator to parse slice values
@@ -98,44 +85,40 @@ func Load(dst any, opts ...Option) error {
9885
return newLoader(OS, opts...).loadVars(dst)
9986
}
10087

101-
// LoadFrom loads environment variables into the provided struct using the
102-
// specified [Provider] as their source. See [Load] documentation for more
103-
// details.
88+
// LoadFrom loads environment variables into the provided struct using the specified [Provider] as their source.
89+
// See [Load] documentation for more details.
10490
func LoadFrom(p Provider, dst any, opts ...Option) error {
10591
return newLoader(p, opts...).loadVars(dst)
10692
}
10793

10894
// Option allows to configure the behaviour of the [Load]/[LoadFrom] functions.
10995
type Option func(*loader)
11096

111-
// WithPrefix configures [Load]/[LoadFrom] to automatically add the provided
112-
// prefix to each environment variable. By default, no prefix is configured.
97+
// WithPrefix configures [Load]/[LoadFrom] to automatically add the provided prefix to each environment variable.
98+
// By default, no prefix is configured.
11399
func WithPrefix(prefix string) Option {
114100
return func(l *loader) { l.prefix = prefix }
115101
}
116102

117-
// WithSliceSeparator configures [Load]/[LoadFrom] to use the provided separator
118-
// when parsing slice values. The default one is space.
103+
// WithSliceSeparator configures [Load]/[LoadFrom] to use the provided separator when parsing slice values.
104+
// The default one is space.
119105
func WithSliceSeparator(sep string) Option {
120106
return func(l *loader) { l.sliceSep = sep }
121107
}
122108

123-
// WithStrictMode configures [Load]/[LoadFrom] to treat all environment
124-
// variables without the `default` tag as required. By default, strict mode is
125-
// disabled.
109+
// WithStrictMode configures [Load]/[LoadFrom] to treat all environment variables without the `default` tag as required.
110+
// By default, strict mode is disabled.
126111
func WithStrictMode() Option {
127112
return func(l *loader) { l.strictMode = true }
128113
}
129114

130-
// WithUsageOnError configures [Load]/[LoadFrom] to write an auto-generated
131-
// usage message to the provided [io.Writer], if an error occurs while loading
132-
// environment variables. The message format can be changed by assigning the
133-
// global [Usage] variable to a custom implementation.
115+
// WithUsageOnError configures [Load]/[LoadFrom] to write an auto-generated usage message to the provided [io.Writer],
116+
// if an error occurs while loading environment variables.
117+
// The message format can be changed by assigning the global [Usage] variable to a custom implementation.
134118
func WithUsageOnError(w io.Writer) Option {
135119
return func(l *loader) { l.usageOutput = w }
136120
}
137121

138-
// loader is an environment variables loader.
139122
type loader struct {
140123
provider Provider
141124
prefix string
@@ -144,8 +127,6 @@ type loader struct {
144127
usageOutput io.Writer
145128
}
146129

147-
// newLoader creates a new loader with the specified [Provider] and applies the
148-
// provided options, which override the default settings.
149130
func newLoader(p Provider, opts ...Option) *loader {
150131
l := loader{
151132
provider: p,
@@ -160,7 +141,6 @@ func newLoader(p Provider, opts ...Option) *loader {
160141
return &l
161142
}
162143

163-
// loadVars loads environment variables into the provided struct.
164144
func (l *loader) loadVars(dst any) (err error) {
165145
rv := reflect.ValueOf(dst)
166146
if !structPtr(rv) {
@@ -178,8 +158,7 @@ func (l *loader) loadVars(dst any) (err error) {
178158
}
179159
}()
180160

181-
// accumulate missing required variables
182-
// to return NotSetError after the loop is finished.
161+
// accumulate missing required variables to return NotSetError after the loop is finished.
183162
var notset []string
184163

185164
for _, v := range vars {
@@ -191,8 +170,6 @@ func (l *loader) loadVars(dst any) (err error) {
191170
continue
192171
}
193172
// ...otherwise, use the default value.
194-
// TODO: actually, there is no need to set a default value
195-
// if it has been obtained from the initialized struct field.
196173
value = v.Default
197174
}
198175

@@ -213,16 +190,13 @@ func (l *loader) loadVars(dst any) (err error) {
213190
return nil
214191
}
215192

216-
// parseVars parses environment variables from the fields of the provided
217-
// struct.
218193
func (l *loader) parseVars(v reflect.Value) ([]Var, error) {
219194
var vars []Var
220195

221196
for i := 0; i < v.NumField(); i++ {
222197
field := v.Field(i)
223198
if !field.CanSet() {
224-
// skip unexported fields.
225-
continue
199+
continue // skip unexported fields.
226200
}
227201

228202
// special case: a nested struct, parse its fields recursively.
@@ -238,8 +212,7 @@ func (l *loader) parseVars(v reflect.Value) ([]Var, error) {
238212
sf := v.Type().Field(i)
239213
value, ok := sf.Tag.Lookup("env")
240214
if !ok {
241-
// skip fields without the `env` tag.
242-
continue
215+
continue // skip fields without the `env` tag.
243216
}
244217

245218
parts := strings.Split(value, ",")
@@ -290,9 +263,6 @@ func (l *loader) parseVars(v reflect.Value) ([]Var, error) {
290263
return vars, nil
291264
}
292265

293-
// lookupEnv retrieves the value of the environment variable named by the key
294-
// using the internal [Provider]. It replaces $VAR or ${VAR} in the result
295-
// using [os.Expand] if expand is true.
296266
func (l *loader) lookupEnv(key string, expand bool) (string, bool) {
297267
value, ok := l.provider.LookupEnv(key)
298268
if !ok {

env_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ func TestLoadFrom(t *testing.T) {
172172
})
173173

174174
t.Run("with usage on error", func(t *testing.T) {
175-
// reset to the default usage after the test is finished.
176175
usage := env.Usage
177176
defer func() { env.Usage = usage }()
178177

@@ -289,8 +288,8 @@ func TestLoadFrom(t *testing.T) {
289288
t.Run("parsing errors", func(t *testing.T) {
290289
test := func(name, envName string, checkErr func(error) bool) {
291290
t.Run(name, func(t *testing.T) {
292-
// "-" is an invalid value for all these types, will cause an
293-
// error for strconv.Parse*, time.ParseDuration and net.ParseIP.
291+
// "-" is an invalid value for all the following types,
292+
// it causes an error for strconv.Parse*, time.ParseDuration and net.ParseIP.
294293
m := env.Map{envName: "-"}
295294

296295
var cfg struct {
@@ -311,7 +310,6 @@ func TestLoadFrom(t *testing.T) {
311310
return errors.Is(err, strconv.ErrSyntax)
312311
}
313312
isInvalidDuration := func(err error) bool {
314-
// time.ParseDuration does not return any sentinel error :(
315313
return errors.Unwrap(err).Error() == `time: invalid duration "-"`
316314
}
317315
asParseError := func(err error) bool {

provider.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import "os"
44

55
// Provider represents an entity that is able to provide environment variables.
66
type Provider interface {
7-
// LookupEnv retrieves the value of the environment variable named by the
8-
// key. If it is not found, the boolean will be false.
7+
// LookupEnv retrieves the value of the environment variable named by the key.
8+
// If it is not found, the boolean will be false.
99
LookupEnv(key string) (value string, ok bool)
1010
}
1111

12-
// ProviderFunc is an adapter that allows using functions as [Provider].
12+
// ProviderFunc is an adapter that allows using a function as [Provider].
1313
type ProviderFunc func(key string) (value string, ok bool)
1414

1515
// LookupEnv implements the [Provider] interface.
@@ -27,16 +27,12 @@ func (m Map) LookupEnv(key string) (string, bool) {
2727
return value, ok
2828
}
2929

30-
// MultiProvider combines multiple providers into a single one, which will
31-
// contain the union of their environment variables. The order of the given
32-
// providers matters: if the same key is found in several providers, the value
33-
// from the last one takes precedence.
30+
// MultiProvider combines multiple providers into a single one containing the union of all environment variables.
31+
// The order of the given providers matters: if the same key occurs more than once, the later value takes precedence.
3432
func MultiProvider(ps ...Provider) Provider { return providers(ps) }
3533

36-
// providers wraps a slice of providers so it can be used as [Provider].
3734
type providers []Provider
3835

39-
// LookupEnv implements the [Provider] interface.
4036
func (ps providers) LookupEnv(key string) (string, bool) {
4137
var value string
4238
var found bool

provider_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestMultiProvider(t *testing.T) {
5959
"BAR": "2",
6060
}
6161
m2 := env.Map{
62-
"BAR": "3", // overrides BAR from m1
62+
"BAR": "3", // overrides BAR from m1.
6363
"BAZ": "4",
6464
}
6565
p := env.MultiProvider(m1, m2)

reflect.go

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ func kindOf(v reflect.Value, kinds ...reflect.Kind) bool {
3333
return false
3434
}
3535

36-
// implements reports whether v's type implements one of the provided
37-
// interfaces.
36+
// implements reports whether v's type implements one of the provided interfaces.
3837
func implements(v reflect.Value, ifaces ...reflect.Type) bool {
3938
for _, iface := range ifaces {
4039
if t := v.Type(); t.Implements(iface) || reflect.PtrTo(v.Type()).Implements(iface) {
@@ -49,8 +48,7 @@ func structPtr(v reflect.Value) bool {
4948
return v.IsValid() && v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct && !v.IsNil()
5049
}
5150

52-
// setValue parses s based on v's type/kind and sets v's underlying value to the
53-
// result.
51+
// setValue parses s based on v's type/kind and sets v's underlying value to the result.
5452
func setValue(v reflect.Value, s string) error {
5553
switch {
5654
case typeOf(v, durationType):
@@ -72,7 +70,6 @@ func setValue(v reflect.Value, s string) error {
7270
}
7371
}
7472

75-
// setInt parses an int value from s and sets v's underlying value to it.
7673
func setInt(v reflect.Value, s string) error {
7774
bits := v.Type().Bits()
7875
i, err := strconv.ParseInt(s, 10, bits)
@@ -83,7 +80,6 @@ func setInt(v reflect.Value, s string) error {
8380
return nil
8481
}
8582

86-
// setUint parses an uint value from s and sets v's underlying value to it.
8783
func setUint(v reflect.Value, s string) error {
8884
bits := v.Type().Bits()
8985
u, err := strconv.ParseUint(s, 10, bits)
@@ -94,7 +90,6 @@ func setUint(v reflect.Value, s string) error {
9490
return nil
9591
}
9692

97-
// setFloat parses a float value from s and sets v's underlying value to it.
9893
func setFloat(v reflect.Value, s string) error {
9994
bits := v.Type().Bits()
10095
f, err := strconv.ParseFloat(s, bits)
@@ -105,7 +100,6 @@ func setFloat(v reflect.Value, s string) error {
105100
return nil
106101
}
107102

108-
// setBool parses a bool value from s and sets v's underlying value to it.
109103
func setBool(v reflect.Value, s string) error {
110104
b, err := strconv.ParseBool(s)
111105
if err != nil {
@@ -115,14 +109,11 @@ func setBool(v reflect.Value, s string) error {
115109
return nil
116110
}
117111

118-
// setString sets v's underlying value to s.
119112
func setString(v reflect.Value, s string) error {
120113
v.SetString(s)
121114
return nil
122115
}
123116

124-
// setDuration parses a duration value from s and sets v's underlying value to
125-
// it.
126117
func setDuration(v reflect.Value, s string) error {
127118
d, err := time.ParseDuration(s)
128119
if err != nil {
@@ -132,7 +123,6 @@ func setDuration(v reflect.Value, s string) error {
132123
return nil
133124
}
134125

135-
// setUnmarshaler calls v's UnmarshalText method with s as the text argument.
136126
func setUnmarshaler(v reflect.Value, s string) error {
137127
u := v.Addr().Interface().(encoding.TextUnmarshaler)
138128
if err := u.UnmarshalText([]byte(s)); err != nil {
@@ -141,8 +131,6 @@ func setUnmarshaler(v reflect.Value, s string) error {
141131
return nil
142132
}
143133

144-
// setSlice creates a new slice of the values parsed from s and sets v's
145-
// underlying value to it.
146134
func setSlice(v reflect.Value, s []string) error {
147135
slice := reflect.MakeSlice(v.Type(), len(s), cap(s))
148136
for i := 0; i < slice.Len(); i++ {

0 commit comments

Comments
 (0)