mirror of
https://github.com/spf13/viper.git
synced 2024-04-21 12:31:38 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab3a50c0ce | ||
|
|
9154b900c3 | ||
|
|
08e4a00949 | ||
|
|
fb6eb1e8e9 |
@@ -24,9 +24,9 @@ jobs:
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version: "1.21"
|
||||
|
||||
- name: Build
|
||||
run: go build .
|
||||
@@ -44,15 +44,15 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
go: ['1.19', '1.20', '1.21']
|
||||
tags: ['', 'finder']
|
||||
go: ["1.19", "1.20", "1.21"]
|
||||
tags: ["", "finder", "viper_bind_struct"]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
|
||||
@@ -73,9 +73,9 @@ jobs:
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version: "1.21"
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
|
||||
uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
|
||||
uses: github/codeql-action/autobuild@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -68,5 +68,5 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
|
||||
uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
//go:build viper_bind_struct
|
||||
|
||||
package features
|
||||
|
||||
const BindStruct = true
|
||||
@@ -0,0 +1,5 @@
|
||||
//go:build !viper_bind_struct
|
||||
|
||||
package features
|
||||
|
||||
const BindStruct = false
|
||||
@@ -48,6 +48,7 @@ import (
|
||||
"github.com/spf13/viper/internal/encoding/json"
|
||||
"github.com/spf13/viper/internal/encoding/toml"
|
||||
"github.com/spf13/viper/internal/encoding/yaml"
|
||||
"github.com/spf13/viper/internal/features"
|
||||
)
|
||||
|
||||
// ConfigMarshalError happens when failing to marshal the configuration.
|
||||
@@ -1114,14 +1115,20 @@ func Unmarshal(rawVal any, opts ...DecoderConfigOption) error {
|
||||
}
|
||||
|
||||
func (v *Viper) Unmarshal(rawVal any, opts ...DecoderConfigOption) error {
|
||||
// TODO: make this optional?
|
||||
structKeys, err := v.decodeStructKeys(rawVal, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
keys := v.AllKeys()
|
||||
|
||||
if features.BindStruct {
|
||||
// TODO: make this optional?
|
||||
structKeys, err := v.decodeStructKeys(rawVal, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keys = append(keys, structKeys...)
|
||||
}
|
||||
|
||||
// TODO: struct keys should be enough?
|
||||
return decode(v.getSettings(append(v.AllKeys(), structKeys...)), defaultDecoderConfig(rawVal, opts...))
|
||||
return decode(v.getSettings(keys), defaultDecoderConfig(rawVal, opts...))
|
||||
}
|
||||
|
||||
func (v *Viper) decodeStructKeys(input any, opts ...DecoderConfigOption) ([]string, error) {
|
||||
@@ -1179,7 +1186,20 @@ func (v *Viper) UnmarshalExact(rawVal any, opts ...DecoderConfigOption) error {
|
||||
config := defaultDecoderConfig(rawVal, opts...)
|
||||
config.ErrorUnused = true
|
||||
|
||||
return decode(v.AllSettings(), config)
|
||||
keys := v.AllKeys()
|
||||
|
||||
if features.BindStruct {
|
||||
// TODO: make this optional?
|
||||
structKeys, err := v.decodeStructKeys(rawVal, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keys = append(keys, structKeys...)
|
||||
}
|
||||
|
||||
// TODO: struct keys should be enough?
|
||||
return decode(v.getSettings(keys), config)
|
||||
}
|
||||
|
||||
// BindPFlags binds a full flag set to the configuration, using each flag's long
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/spf13/viper/internal/features"
|
||||
"github.com/spf13/viper/internal/testutil"
|
||||
)
|
||||
|
||||
@@ -956,6 +957,10 @@ func TestUnmarshalWithDecoderOptions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUnmarshalWithAutomaticEnv(t *testing.T) {
|
||||
if !features.BindStruct {
|
||||
t.Skip("binding struct is not enabled")
|
||||
}
|
||||
|
||||
t.Setenv("PORT", "1313")
|
||||
t.Setenv("NAME", "Steve")
|
||||
t.Setenv("DURATION", "1s1ms")
|
||||
@@ -1052,6 +1057,32 @@ func TestUnmarshalWithAutomaticEnv(t *testing.T) {
|
||||
|
||||
assert.Error(t, err, "expected viper.Unmarshal to return error due to unset field 'FLAG'")
|
||||
})
|
||||
|
||||
t.Run("Exact", func(t *testing.T) {
|
||||
var config Configuration
|
||||
|
||||
v.Set("port", 1234)
|
||||
if err := v.UnmarshalExact(&config); err != nil {
|
||||
t.Fatalf("unable to decode into struct, %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(
|
||||
t,
|
||||
Configuration{
|
||||
Name: "Steve",
|
||||
Port: 1234,
|
||||
Duration: time.Second + time.Millisecond,
|
||||
Modes: []int{1, 2, 3},
|
||||
Authentication: AuthConfig{
|
||||
Secret: "42",
|
||||
},
|
||||
Storage: StorageConfig{
|
||||
Size: 4096,
|
||||
},
|
||||
},
|
||||
config,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBindPFlags(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user