summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/pelletier/go-toml/v2/.gitignore3
-rw-r--r--vendor/github.com/pelletier/go-toml/v2/README.md34
-rw-r--r--vendor/github.com/pelletier/go-toml/v2/SECURITY.md3
-rw-r--r--vendor/github.com/pelletier/go-toml/v2/ci.sh22
-rw-r--r--vendor/github.com/pelletier/go-toml/v2/unmarshaler.go6
-rw-r--r--vendor/github.com/sagikazarmark/locafero/.editorconfig21
-rw-r--r--vendor/github.com/sagikazarmark/locafero/.gitignore8
-rw-r--r--vendor/github.com/sagikazarmark/locafero/.golangci.yaml27
-rw-r--r--vendor/github.com/sagikazarmark/locafero/LICENSE19
-rw-r--r--vendor/github.com/sagikazarmark/locafero/README.md37
-rw-r--r--vendor/github.com/sagikazarmark/locafero/file_type.go28
-rw-r--r--vendor/github.com/sagikazarmark/locafero/finder.go165
-rw-r--r--vendor/github.com/sagikazarmark/locafero/flake.lock273
-rw-r--r--vendor/github.com/sagikazarmark/locafero/flake.nix47
-rw-r--r--vendor/github.com/sagikazarmark/locafero/helpers.go41
-rw-r--r--vendor/github.com/sagikazarmark/locafero/justfile11
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/.editorconfig18
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/.gitignore4
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/LICENSE27
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/README.md81
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/attr.go74
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/attr_120.go75
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/flake.lock273
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/flake.nix57
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/handler.go45
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/handler_120.go45
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/json_handler.go23
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go24
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/level.go61
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/level_120.go61
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/logger.go98
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/logger_120.go99
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/record.go31
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/record_120.go32
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/text_handler.go23
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go24
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/value.go109
-rw-r--r--vendor/github.com/sagikazarmark/slog-shim/value_120.go110
-rw-r--r--vendor/github.com/sourcegraph/conc/.golangci.yml11
-rw-r--r--vendor/github.com/sourcegraph/conc/LICENSE (renamed from vendor/github.com/spf13/jwalterweatherman/LICENSE)6
-rw-r--r--vendor/github.com/sourcegraph/conc/README.md464
-rw-r--r--vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go119.go10
-rw-r--r--vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go120.go10
-rw-r--r--vendor/github.com/sourcegraph/conc/iter/iter.go85
-rw-r--r--vendor/github.com/sourcegraph/conc/iter/map.go65
-rw-r--r--vendor/github.com/sourcegraph/conc/panics/panics.go102
-rw-r--r--vendor/github.com/sourcegraph/conc/panics/try.go11
-rw-r--r--vendor/github.com/sourcegraph/conc/waitgroup.go52
-rw-r--r--vendor/github.com/spf13/afero/const_bsds.go4
-rw-r--r--vendor/github.com/spf13/afero/const_win_unix.go4
-rw-r--r--vendor/github.com/spf13/afero/memmap.go65
-rw-r--r--vendor/github.com/spf13/cast/README.md4
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/.gitignore24
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/README.md148
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/default_notepad.go111
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/log_counter.go46
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/notepad.go225
-rw-r--r--vendor/github.com/spf13/viper/.editorconfig3
-rw-r--r--vendor/github.com/spf13/viper/.gitignore3
-rw-r--r--vendor/github.com/spf13/viper/.golangci.yaml14
-rw-r--r--vendor/github.com/spf13/viper/.yamlignore2
-rw-r--r--vendor/github.com/spf13/viper/.yamllint.yaml6
-rw-r--r--vendor/github.com/spf13/viper/Makefile45
-rw-r--r--vendor/github.com/spf13/viper/README.md66
-rw-r--r--vendor/github.com/spf13/viper/experimental_logger.go11
-rw-r--r--vendor/github.com/spf13/viper/file.go (renamed from vendor/github.com/spf13/viper/viper_go1_15.go)5
-rw-r--r--vendor/github.com/spf13/viper/file_finder.go38
-rw-r--r--vendor/github.com/spf13/viper/flags.go4
-rw-r--r--vendor/github.com/spf13/viper/flake.lock255
-rw-r--r--vendor/github.com/spf13/viper/flake.nix56
-rw-r--r--vendor/github.com/spf13/viper/fs.go65
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/decoder.go6
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go6
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go18
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/encoder.go6
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go4
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/ini/codec.go6
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go26
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go6
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go26
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/json/codec.go4
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/toml/codec.go4
-rw-r--r--vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go4
-rw-r--r--vendor/github.com/spf13/viper/internal/features/bind_struct.go5
-rw-r--r--vendor/github.com/spf13/viper/internal/features/bind_struct_default.go5
-rw-r--r--vendor/github.com/spf13/viper/logger.go57
-rw-r--r--vendor/github.com/spf13/viper/util.go47
-rw-r--r--vendor/github.com/spf13/viper/viper.go339
-rw-r--r--vendor/github.com/spf13/viper/viper_go1_16.go32
-rw-r--r--vendor/github.com/spf13/viper/watch.go12
-rw-r--r--vendor/github.com/spf13/viper/watch_unsupported.go32
-rw-r--r--vendor/github.com/subosito/gotenv/CHANGELOG.md37
-rw-r--r--vendor/github.com/subosito/gotenv/gotenv.go50
93 files changed, 3831 insertions, 1060 deletions
diff --git a/vendor/github.com/pelletier/go-toml/v2/.gitignore b/vendor/github.com/pelletier/go-toml/v2/.gitignore
index a69e2b0eb..4b7c4eda3 100644
--- a/vendor/github.com/pelletier/go-toml/v2/.gitignore
+++ b/vendor/github.com/pelletier/go-toml/v2/.gitignore
@@ -3,4 +3,5 @@ fuzz/
cmd/tomll/tomll
cmd/tomljson/tomljson
cmd/tomltestgen/tomltestgen
-dist \ No newline at end of file
+dist
+tests/
diff --git a/vendor/github.com/pelletier/go-toml/v2/README.md b/vendor/github.com/pelletier/go-toml/v2/README.md
index 63b92f3b0..b10f97f0b 100644
--- a/vendor/github.com/pelletier/go-toml/v2/README.md
+++ b/vendor/github.com/pelletier/go-toml/v2/README.md
@@ -179,12 +179,12 @@ Execution time speedup compared to other Go TOML libraries:
<tr><th>Benchmark</th><th>go-toml v1</th><th>BurntSushi/toml</th></tr>
</thead>
<tbody>
- <tr><td>Marshal/HugoFrontMatter-2</td><td>1.9x</td><td>1.9x</td></tr>
- <tr><td>Marshal/ReferenceFile/map-2</td><td>1.7x</td><td>1.8x</td></tr>
- <tr><td>Marshal/ReferenceFile/struct-2</td><td>2.2x</td><td>2.5x</td></tr>
- <tr><td>Unmarshal/HugoFrontMatter-2</td><td>2.9x</td><td>2.9x</td></tr>
- <tr><td>Unmarshal/ReferenceFile/map-2</td><td>2.6x</td><td>2.9x</td></tr>
- <tr><td>Unmarshal/ReferenceFile/struct-2</td><td>4.4x</td><td>5.3x</td></tr>
+ <tr><td>Marshal/HugoFrontMatter-2</td><td>1.9x</td><td>2.2x</td></tr>
+ <tr><td>Marshal/ReferenceFile/map-2</td><td>1.7x</td><td>2.1x</td></tr>
+ <tr><td>Marshal/ReferenceFile/struct-2</td><td>2.2x</td><td>3.0x</td></tr>
+ <tr><td>Unmarshal/HugoFrontMatter-2</td><td>2.9x</td><td>2.7x</td></tr>
+ <tr><td>Unmarshal/ReferenceFile/map-2</td><td>2.6x</td><td>2.7x</td></tr>
+ <tr><td>Unmarshal/ReferenceFile/struct-2</td><td>4.6x</td><td>5.1x</td></tr>
</tbody>
</table>
<details><summary>See more</summary>
@@ -197,17 +197,17 @@ provided for completeness.</p>
<tr><th>Benchmark</th><th>go-toml v1</th><th>BurntSushi/toml</th></tr>
</thead>
<tbody>
- <tr><td>Marshal/SimpleDocument/map-2</td><td>1.8x</td><td>2.9x</td></tr>
- <tr><td>Marshal/SimpleDocument/struct-2</td><td>2.7x</td><td>4.2x</td></tr>
- <tr><td>Unmarshal/SimpleDocument/map-2</td><td>4.5x</td><td>3.1x</td></tr>
- <tr><td>Unmarshal/SimpleDocument/struct-2</td><td>6.2x</td><td>3.9x</td></tr>
- <tr><td>UnmarshalDataset/example-2</td><td>3.1x</td><td>3.5x</td></tr>
- <tr><td>UnmarshalDataset/code-2</td><td>2.3x</td><td>3.1x</td></tr>
- <tr><td>UnmarshalDataset/twitter-2</td><td>2.5x</td><td>2.6x</td></tr>
- <tr><td>UnmarshalDataset/citm_catalog-2</td><td>2.1x</td><td>2.2x</td></tr>
- <tr><td>UnmarshalDataset/canada-2</td><td>1.6x</td><td>1.3x</td></tr>
- <tr><td>UnmarshalDataset/config-2</td><td>4.3x</td><td>3.2x</td></tr>
- <tr><td>[Geo mean]</td><td>2.7x</td><td>2.8x</td></tr>
+ <tr><td>Marshal/SimpleDocument/map-2</td><td>1.8x</td><td>2.7x</td></tr>
+ <tr><td>Marshal/SimpleDocument/struct-2</td><td>2.7x</td><td>3.8x</td></tr>
+ <tr><td>Unmarshal/SimpleDocument/map-2</td><td>3.8x</td><td>3.0x</td></tr>
+ <tr><td>Unmarshal/SimpleDocument/struct-2</td><td>5.6x</td><td>4.1x</td></tr>
+ <tr><td>UnmarshalDataset/example-2</td><td>3.0x</td><td>3.2x</td></tr>
+ <tr><td>UnmarshalDataset/code-2</td><td>2.3x</td><td>2.9x</td></tr>
+ <tr><td>UnmarshalDataset/twitter-2</td><td>2.6x</td><td>2.7x</td></tr>
+ <tr><td>UnmarshalDataset/citm_catalog-2</td><td>2.2x</td><td>2.3x</td></tr>
+ <tr><td>UnmarshalDataset/canada-2</td><td>1.8x</td><td>1.5x</td></tr>
+ <tr><td>UnmarshalDataset/config-2</td><td>4.1x</td><td>2.9x</td></tr>
+ <tr><td>geomean</td><td>2.7x</td><td>2.8x</td></tr>
</tbody>
</table>
<p>This table can be generated with <code>./ci.sh benchmark -a -html</code>.</p>
diff --git a/vendor/github.com/pelletier/go-toml/v2/SECURITY.md b/vendor/github.com/pelletier/go-toml/v2/SECURITY.md
index b2f21cfc9..d4d554fda 100644
--- a/vendor/github.com/pelletier/go-toml/v2/SECURITY.md
+++ b/vendor/github.com/pelletier/go-toml/v2/SECURITY.md
@@ -2,9 +2,6 @@
## Supported Versions
-Use this section to tell people about which versions of your project are
-currently being supported with security updates.
-
| Version | Supported |
| ---------- | ------------------ |
| Latest 2.x | :white_check_mark: |
diff --git a/vendor/github.com/pelletier/go-toml/v2/ci.sh b/vendor/github.com/pelletier/go-toml/v2/ci.sh
index 9ae8b7537..86217a9b0 100644
--- a/vendor/github.com/pelletier/go-toml/v2/ci.sh
+++ b/vendor/github.com/pelletier/go-toml/v2/ci.sh
@@ -77,7 +77,7 @@ cover() {
pushd "$dir"
go test -covermode=atomic -coverpkg=./... -coverprofile=coverage.out.tmp ./...
- cat coverage.out.tmp | grep -v fuzz | grep -v testsuite | grep -v tomltestgen | grep -v gotoml-test-decoder > coverage.out
+ grep -Ev '(fuzz|testsuite|tomltestgen|gotoml-test-decoder|gotoml-test-encoder)' coverage.out.tmp > coverage.out
go tool cover -func=coverage.out
echo "Coverage profile for ${branch}: ${dir}/coverage.out" >&2
popd
@@ -152,7 +152,7 @@ bench() {
fi
export GOMAXPROCS=2
- nice -n -19 taskset --cpu-list 0,1 go test '-bench=^Benchmark(Un)?[mM]arshal' -count=5 -run=Nothing ./... | tee "${out}"
+ go test '-bench=^Benchmark(Un)?[mM]arshal' -count=10 -run=Nothing ./... | tee "${out}"
popd
if [ "${branch}" != "HEAD" ]; then
@@ -161,10 +161,12 @@ bench() {
}
fmktemp() {
- if mktemp --version|grep GNU >/dev/null; then
- mktemp --suffix=-$1;
+ if mktemp --version &> /dev/null; then
+ # GNU
+ mktemp --suffix=-$1
else
- mktemp -t $1;
+ # BSD
+ mktemp -t $1
fi
}
@@ -184,12 +186,14 @@ with open(sys.argv[1]) as f:
lines.append(line.split(','))
results = []
-for line in reversed(lines[1:]):
+for line in reversed(lines[2:]):
+ if len(line) < 8 or line[0] == "":
+ continue
v2 = float(line[1])
results.append([
line[0].replace("-32", ""),
"%.1fx" % (float(line[3])/v2), # v1
- "%.1fx" % (float(line[5])/v2), # bs
+ "%.1fx" % (float(line[7])/v2), # bs
])
# move geomean to the end
results.append(results[0])
@@ -260,10 +264,10 @@ benchmark() {
if [ "$1" = "-html" ]; then
tmpcsv=`fmktemp csv`
- benchstat -csv -geomean go-toml-v2.txt go-toml-v1.txt bs-toml.txt > $tmpcsv
+ benchstat -format csv go-toml-v2.txt go-toml-v1.txt bs-toml.txt > $tmpcsv
benchstathtml $tmpcsv
else
- benchstat -geomean go-toml-v2.txt go-toml-v1.txt bs-toml.txt
+ benchstat go-toml-v2.txt go-toml-v1.txt bs-toml.txt
fi
rm -f go-toml-v2.txt go-toml-v1.txt bs-toml.txt
diff --git a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
index 868c74c15..c5e5f3390 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
@@ -1097,9 +1097,9 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node
f := fieldByIndex(v, path)
- if !f.CanSet() {
- // If the field is not settable, need to take a slower path and make a copy of
- // the struct itself to a new location.
+ if !f.CanAddr() {
+ // If the field is not addressable, need to take a slower path and
+ // make a copy of the struct itself to a new location.
nvp := reflect.New(v.Type())
nvp.Elem().Set(v)
v = nvp.Elem()
diff --git a/vendor/github.com/sagikazarmark/locafero/.editorconfig b/vendor/github.com/sagikazarmark/locafero/.editorconfig
new file mode 100644
index 000000000..6f944f540
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/.editorconfig
@@ -0,0 +1,21 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[{Makefile,*.mk}]
+indent_style = tab
+
+[*.nix]
+indent_size = 2
+
+[*.go]
+indent_style = tab
+
+[{*.yml,*.yaml}]
+indent_size = 2
diff --git a/vendor/github.com/sagikazarmark/locafero/.gitignore b/vendor/github.com/sagikazarmark/locafero/.gitignore
new file mode 100644
index 000000000..8f07e6016
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/.gitignore
@@ -0,0 +1,8 @@
+/.devenv/
+/.direnv/
+/.task/
+/bin/
+/build/
+/tmp/
+/var/
+/vendor/
diff --git a/vendor/github.com/sagikazarmark/locafero/.golangci.yaml b/vendor/github.com/sagikazarmark/locafero/.golangci.yaml
new file mode 100644
index 000000000..829de2a4a
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/.golangci.yaml
@@ -0,0 +1,27 @@
+run:
+ timeout: 10m
+
+linters-settings:
+ gci:
+ sections:
+ - standard
+ - default
+ - prefix(github.com/sagikazarmark/locafero)
+ goimports:
+ local-prefixes: github.com/sagikazarmark/locafero
+ misspell:
+ locale: US
+ nolintlint:
+ allow-leading-space: false # require machine-readable nolint directives (with no leading space)
+ allow-unused: false # report any unused nolint directives
+ require-specific: false # don't require nolint directives to be specific about which linter is being skipped
+ revive:
+ confidence: 0
+
+linters:
+ enable:
+ - gci
+ - goimports
+ - misspell
+ - nolintlint
+ - revive
diff --git a/vendor/github.com/sagikazarmark/locafero/LICENSE b/vendor/github.com/sagikazarmark/locafero/LICENSE
new file mode 100644
index 000000000..a70b0f296
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2023 Márk Sági-Kazár <mark.sagikazar@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/sagikazarmark/locafero/README.md b/vendor/github.com/sagikazarmark/locafero/README.md
new file mode 100644
index 000000000..a48e8e978
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/README.md
@@ -0,0 +1,37 @@
+# Finder library for [Afero](https://github.com/spf13/afero)
+
+[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/sagikazarmark/locafero/ci.yaml?style=flat-square)](https://github.com/sagikazarmark/locafero/actions/workflows/ci.yaml)
+[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/mod/github.com/sagikazarmark/locafero)
+![Go Version](https://img.shields.io/badge/go%20version-%3E=1.20-61CFDD.svg?style=flat-square)
+[![built with nix](https://img.shields.io/badge/builtwith-nix-7d81f7?style=flat-square)](https://builtwithnix.org)
+
+**Finder library for [Afero](https://github.com/spf13/afero) ported from [go-finder](https://github.com/sagikazarmark/go-finder).**
+
+> [!WARNING]
+> This is an experimental library under development.
+>
+> **Backwards compatibility is not guaranteed, expect breaking changes.**
+
+## Installation
+
+```shell
+go get github.com/sagikazarmark/locafero
+```
+
+## Usage
+
+Check out the [package example](https://pkg.go.dev/github.com/sagikazarmark/locafero#example-package) on go.dev.
+
+## Development
+
+**For an optimal developer experience, it is recommended to install [Nix](https://nixos.org/download.html) and [direnv](https://direnv.net/docs/installation.html).**
+
+Run the test suite:
+
+```shell
+just test
+```
+
+## License
+
+The project is licensed under the [MIT License](LICENSE).
diff --git a/vendor/github.com/sagikazarmark/locafero/file_type.go b/vendor/github.com/sagikazarmark/locafero/file_type.go
new file mode 100644
index 000000000..9a9b14023
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/file_type.go
@@ -0,0 +1,28 @@
+package locafero
+
+import "io/fs"
+
+// FileType represents the kind of entries [Finder] can return.
+type FileType int
+
+const (
+ FileTypeAll FileType = iota
+ FileTypeFile
+ FileTypeDir
+)
+
+func (ft FileType) matchFileInfo(info fs.FileInfo) bool {
+ switch ft {
+ case FileTypeAll:
+ return true
+
+ case FileTypeFile:
+ return !info.IsDir()
+
+ case FileTypeDir:
+ return info.IsDir()
+
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/sagikazarmark/locafero/finder.go b/vendor/github.com/sagikazarmark/locafero/finder.go
new file mode 100644
index 000000000..754c8b260
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/finder.go
@@ -0,0 +1,165 @@
+// Package finder looks for files and directories in an {fs.Fs} filesystem.
+package locafero
+
+import (
+ "errors"
+ "io/fs"
+ "path/filepath"
+ "strings"
+
+ "github.com/sourcegraph/conc/iter"
+ "github.com/spf13/afero"
+)
+
+// Finder looks for files and directories in an [afero.Fs] filesystem.
+type Finder struct {
+ // Paths represents a list of locations that the [Finder] will search in.
+ //
+ // They are essentially the root directories or starting points for the search.
+ //
+ // Examples:
+ // - home/user
+ // - etc
+ Paths []string
+
+ // Names are specific entries that the [Finder] will look for within the given Paths.
+ //
+ // It provides the capability to search for entries with depth,
+ // meaning it can target deeper locations within the directory structure.
+ //
+ // It also supports glob syntax (as defined by [filepat.Match]), offering greater flexibility in search patterns.
+ //
+ // Examples:
+ // - config.yaml
+ // - home/*/config.yaml
+ // - home/*/config.*
+ Names []string
+
+ // Type restricts the kind of entries returned by the [Finder].
+ //
+ // This parameter helps in differentiating and filtering out files from directories or vice versa.
+ Type FileType
+}
+
+// Find looks for files and directories in an [afero.Fs] filesystem.
+func (f Finder) Find(fsys afero.Fs) ([]string, error) {
+ // Arbitrary go routine limit (TODO: make this a parameter)
+ // pool := pool.NewWithResults[[]string]().WithMaxGoroutines(5).WithErrors().WithFirstError()
+
+ type searchItem struct {
+ path string
+ name string
+ }
+
+ var searchItems []searchItem
+
+ for _, searchPath := range f.Paths {
+ searchPath := searchPath
+
+ for _, searchName := range f.Names {
+ searchName := searchName
+
+ searchItems = append(searchItems, searchItem{searchPath, searchName})
+
+ // pool.Go(func() ([]string, error) {
+ // // If the name contains any glob character, perform a glob match
+ // if strings.ContainsAny(searchName, "*?[]\\^") {
+ // return globWalkSearch(fsys, searchPath, searchName, f.Type)
+ // }
+ //
+ // return statSearch(fsys, searchPath, searchName, f.Type)
+ // })
+ }
+ }
+
+ // allResults, err := pool.Wait()
+ // if err != nil {
+ // return nil, err
+ // }
+
+ allResults, err := iter.MapErr(searchItems, func(item *searchItem) ([]string, error) {
+ // If the name contains any glob character, perform a glob match
+ if strings.ContainsAny(item.name, "*?[]\\^") {
+ return globWalkSearch(fsys, item.path, item.name, f.Type)
+ }
+
+ return statSearch(fsys, item.path, item.name, f.Type)
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ var results []string
+
+ for _, r := range allResults {
+ results = append(results, r...)
+ }
+
+ // Sort results in alphabetical order for now
+ // sort.Strings(results)
+
+ return results, nil
+}
+
+func globWalkSearch(fsys afero.Fs, searchPath string, searchName string, searchType FileType) ([]string, error) {
+ var results []string
+
+ err := afero.Walk(fsys, searchPath, func(p string, fileInfo fs.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ // Skip the root path
+ if p == searchPath {
+ return nil
+ }
+
+ var result error
+
+ // Stop reading subdirectories
+ // TODO: add depth detection here
+ if fileInfo.IsDir() && filepath.Dir(p) == searchPath {
+ result = fs.SkipDir
+ }
+
+ // Skip unmatching type
+ if !searchType.matchFileInfo(fileInfo) {
+ return result
+ }
+
+ match, err := filepath.Match(searchName, fileInfo.Name())
+ if err != nil {
+ return err
+ }
+
+ if match {
+ results = append(results, p)
+ }
+
+ return result
+ })
+ if err != nil {
+ return results, err
+ }
+
+ return results, nil
+}
+
+func statSearch(fsys afero.Fs, searchPath string, searchName string, searchType FileType) ([]string, error) {
+ filePath := filepath.Join(searchPath, searchName)
+
+ fileInfo, err := fsys.Stat(filePath)
+ if errors.Is(err, fs.ErrNotExist) {
+ return nil, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ // Skip unmatching type
+ if !searchType.matchFileInfo(fileInfo) {
+ return nil, nil
+ }
+
+ return []string{filePath}, nil
+}
diff --git a/vendor/github.com/sagikazarmark/locafero/flake.lock b/vendor/github.com/sagikazarmark/locafero/flake.lock
new file mode 100644
index 000000000..46d28f805
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/flake.lock
@@ -0,0 +1,273 @@
+{
+ "nodes": {
+ "devenv": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "nix": "nix",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks"
+ },
+ "locked": {
+ "lastModified": 1694097209,
+ "narHash": "sha256-gQmBjjxeSyySjbh0yQVBKApo2KWIFqqbRUvG+Fa+QpM=",
+ "owner": "cachix",
+ "repo": "devenv",
+ "rev": "7a8e6a91510efe89d8dcb8e43233f93e86f6b189",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "devenv",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1693611461,
+ "narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1685518550,
+ "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "devenv",
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "lowdown-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1633514407,
+ "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "type": "github"
+ }
+ },
+ "nix": {
+ "inputs": {
+ "lowdown-src": "lowdown-src",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-regression": "nixpkgs-regression"
+ },
+ "locked": {
+ "lastModified": 1676545802,
+ "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=",
+ "owner": "domenkozar",
+ "repo": "nix",
+ "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "domenkozar",
+ "ref": "relaxed-flakes",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1678875422,
+ "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1693471703,
+ "narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-regression": {
+ "locked": {
+ "lastModified": 1643052045,
+ "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1685801374,
+ "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1694343207,
+ "narHash": "sha256-jWi7OwFxU5Owi4k2JmiL1sa/OuBCQtpaAesuj5LXC8w=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "78058d810644f5ed276804ce7ea9e82d92bee293",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": [
+ "devenv",
+ "flake-compat"
+ ],
+ "flake-utils": "flake-utils",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1688056373,
+ "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "devenv": "devenv",
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs_2"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/vendor/github.com/sagikazarmark/locafero/flake.nix b/vendor/github.com/sagikazarmark/locafero/flake.nix
new file mode 100644
index 000000000..209ecf286
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/flake.nix
@@ -0,0 +1,47 @@
+{
+ description = "Finder library for Afero";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ devenv.url = "github:cachix/devenv";
+ };
+
+ outputs = inputs@{ flake-parts, ... }:
+ flake-parts.lib.mkFlake { inherit inputs; } {
+ imports = [
+ inputs.devenv.flakeModule
+ ];
+
+ systems = [ "x86_64-linux" "aarch64-darwin" ];
+
+ perSystem = { config, self', inputs', pkgs, system, ... }: rec {
+ devenv.shells = {
+ default = {
+ languages = {
+ go.enable = true;
+ };
+
+ packages = with pkgs; [
+ just
+
+ golangci-lint
+ ];
+
+ # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767
+ containers = pkgs.lib.mkForce { };
+ };
+
+ ci = devenv.shells.default;
+
+ ci_1_20 = {
+ imports = [ devenv.shells.ci ];
+
+ languages = {
+ go.package = pkgs.go_1_20;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/vendor/github.com/sagikazarmark/locafero/helpers.go b/vendor/github.com/sagikazarmark/locafero/helpers.go
new file mode 100644
index 000000000..05b434481
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/helpers.go
@@ -0,0 +1,41 @@
+package locafero
+
+import "fmt"
+
+// NameWithExtensions creates a list of names from a base name and a list of extensions.
+//
+// TODO: find a better name for this function.
+func NameWithExtensions(baseName string, extensions ...string) []string {
+ var names []string
+
+ if baseName == "" {
+ return names
+ }
+
+ for _, ext := range extensions {
+ if ext == "" {
+ continue
+ }
+
+ names = append(names, fmt.Sprintf("%s.%s", baseName, ext))
+ }
+
+ return names
+}
+
+// NameWithOptionalExtensions creates a list of names from a base name and a list of extensions,
+// plus it adds the base name (without any extensions) to the end of the list.
+//
+// TODO: find a better name for this function.
+func NameWithOptionalExtensions(baseName string, extensions ...string) []string {
+ var names []string
+
+ if baseName == "" {
+ return names
+ }
+
+ names = NameWithExtensions(baseName, extensions...)
+ names = append(names, baseName)
+
+ return names
+}
diff --git a/vendor/github.com/sagikazarmark/locafero/justfile b/vendor/github.com/sagikazarmark/locafero/justfile
new file mode 100644
index 000000000..00a88850c
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/locafero/justfile
@@ -0,0 +1,11 @@
+default:
+ just --list
+
+test:
+ go test -race -v ./...
+
+lint:
+ golangci-lint run
+
+fmt:
+ golangci-lint run --fix
diff --git a/vendor/github.com/sagikazarmark/slog-shim/.editorconfig b/vendor/github.com/sagikazarmark/slog-shim/.editorconfig
new file mode 100644
index 000000000..1fb0e1bec
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/.editorconfig
@@ -0,0 +1,18 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.nix]
+indent_size = 2
+
+[{Makefile,*.mk}]
+indent_style = tab
+
+[Taskfile.yaml]
+indent_size = 2
diff --git a/vendor/github.com/sagikazarmark/slog-shim/.gitignore b/vendor/github.com/sagikazarmark/slog-shim/.gitignore
new file mode 100644
index 000000000..dc6d8b587
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/.gitignore
@@ -0,0 +1,4 @@
+/.devenv/
+/.direnv/
+/.task/
+/build/
diff --git a/vendor/github.com/sagikazarmark/slog-shim/LICENSE b/vendor/github.com/sagikazarmark/slog-shim/LICENSE
new file mode 100644
index 000000000..6a66aea5e
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/sagikazarmark/slog-shim/README.md b/vendor/github.com/sagikazarmark/slog-shim/README.md
new file mode 100644
index 000000000..1f5be85e1
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/README.md
@@ -0,0 +1,81 @@
+# [slog](https://pkg.go.dev/log/slog) shim
+
+[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/sagikazarmark/slog-shim/ci.yaml?style=flat-square)](https://github.com/sagikazarmark/slog-shim/actions/workflows/ci.yaml)
+[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/mod/github.com/sagikazarmark/slog-shim)
+![Go Version](https://img.shields.io/badge/go%20version-%3E=1.20-61CFDD.svg?style=flat-square)
+[![built with nix](https://img.shields.io/badge/builtwith-nix-7d81f7?style=flat-square)](https://builtwithnix.org)
+
+Go 1.21 introduced a [new structured logging package](https://golang.org/doc/go1.21#slog), `log/slog`, to the standard library.
+Although it's been eagerly anticipated by many, widespread adoption isn't expected to occur immediately,
+especially since updating to Go 1.21 is a decision that most libraries won't make overnight.
+
+Before this package was added to the standard library, there was an _experimental_ version available at [golang.org/x/exp/slog](https://pkg.go.dev/golang.org/x/exp/slog).
+While it's generally advised against using experimental packages in production,
+this one served as a sort of backport package for the last few years,
+incorporating new features before they were added to the standard library (like `slices`, `maps` or `errors`).
+
+This package serves as a bridge, helping libraries integrate slog in a backward-compatible way without having to immediately update their Go version requirement to 1.21. On Go 1.21 (and above), it acts as a drop-in replacement for `log/slog`, while below 1.21 it falls back to `golang.org/x/exp/slog`.
+
+**How does it achieve backwards compatibility?**
+
+Although there's no consensus on whether dropping support for older Go versions is considered backward compatible, a majority seems to believe it is.
+(I don't have scientific proof for this, but it's based on conversations with various individuals across different channels.)
+
+This package adheres to that interpretation of backward compatibility. On Go 1.21, the shim uses type aliases to offer the same API as `slog/log`.
+Once a library upgrades its version requirement to Go 1.21, it should be able to discard this shim and use `log/slog` directly.
+
+For older Go versions, the library might become unstable after removing the shim.
+However, since those older versions are no longer supported, the promise of backward compatibility remains intact.
+
+## Installation
+
+```shell
+go get github.com/sagikazarmark/slog-shim
+```
+
+## Usage
+
+Import this package into your library and use it in your public API:
+
+```go
+package mylib
+
+import slog "github.com/sagikazarmark/slog-shim"
+
+func New(logger *slog.Logger) MyLib {
+ // ...
+}
+```
+
+When using the library, clients can either use `log/slog` (when on Go 1.21) or `golang.org/x/exp/slog` (below Go 1.21):
+
+```go
+package main
+
+import "log/slog"
+
+// OR
+
+import "golang.org/x/exp/slog"
+
+mylib.New(slog.Default())
+```
+
+**Make sure consumers are aware that your API behaves differently on different Go versions.**
+
+Once you bump your Go version requirement to Go 1.21, you can drop the shim entirely from your code:
+
+```diff
+package mylib
+
+- import slog "github.com/sagikazarmark/slog-shim"
++ import "log/slog"
+
+func New(logger *slog.Logger) MyLib {
+ // ...
+}
+```
+
+## License
+
+The project is licensed under a [BSD-style license](LICENSE).
diff --git a/vendor/github.com/sagikazarmark/slog-shim/attr.go b/vendor/github.com/sagikazarmark/slog-shim/attr.go
new file mode 100644
index 000000000..89608bf3a
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/attr.go
@@ -0,0 +1,74 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "log/slog"
+ "time"
+)
+
+// An Attr is a key-value pair.
+type Attr = slog.Attr
+
+// String returns an Attr for a string value.
+func String(key, value string) Attr {
+ return slog.String(key, value)
+}
+
+// Int64 returns an Attr for an int64.
+func Int64(key string, value int64) Attr {
+ return slog.Int64(key, value)
+}
+
+// Int converts an int to an int64 and returns
+// an Attr with that value.
+func Int(key string, value int) Attr {
+ return slog.Int(key, value)
+}
+
+// Uint64 returns an Attr for a uint64.
+func Uint64(key string, v uint64) Attr {
+ return slog.Uint64(key, v)
+}
+
+// Float64 returns an Attr for a floating-point number.
+func Float64(key string, v float64) Attr {
+ return slog.Float64(key, v)
+}
+
+// Bool returns an Attr for a bool.
+func Bool(key string, v bool) Attr {
+ return slog.Bool(key, v)
+}
+
+// Time returns an Attr for a time.Time.
+// It discards the monotonic portion.
+func Time(key string, v time.Time) Attr {
+ return slog.Time(key, v)
+}
+
+// Duration returns an Attr for a time.Duration.
+func Duration(key string, v time.Duration) Attr {
+ return slog.Duration(key, v)
+}
+
+// Group returns an Attr for a Group Value.
+// The first argument is the key; the remaining arguments
+// are converted to Attrs as in [Logger.Log].
+//
+// Use Group to collect several key-value pairs under a single
+// key on a log line, or as the result of LogValue
+// in order to log a single value as multiple Attrs.
+func Group(key string, args ...any) Attr {
+ return slog.Group(key, args...)
+}
+
+// Any returns an Attr for the supplied value.
+// See [Value.AnyValue] for how values are treated.
+func Any(key string, value any) Attr {
+ return slog.Any(key, value)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/attr_120.go b/vendor/github.com/sagikazarmark/slog-shim/attr_120.go
new file mode 100644
index 000000000..b66481333
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/attr_120.go
@@ -0,0 +1,75 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "time"
+
+ "golang.org/x/exp/slog"
+)
+
+// An Attr is a key-value pair.
+type Attr = slog.Attr
+
+// String returns an Attr for a string value.
+func String(key, value string) Attr {
+ return slog.String(key, value)
+}
+
+// Int64 returns an Attr for an int64.
+func Int64(key string, value int64) Attr {
+ return slog.Int64(key, value)
+}
+
+// Int converts an int to an int64 and returns
+// an Attr with that value.
+func Int(key string, value int) Attr {
+ return slog.Int(key, value)
+}
+
+// Uint64 returns an Attr for a uint64.
+func Uint64(key string, v uint64) Attr {
+ return slog.Uint64(key, v)
+}
+
+// Float64 returns an Attr for a floating-point number.
+func Float64(key string, v float64) Attr {
+ return slog.Float64(key, v)
+}
+
+// Bool returns an Attr for a bool.
+func Bool(key string, v bool) Attr {
+ return slog.Bool(key, v)
+}
+
+// Time returns an Attr for a time.Time.
+// It discards the monotonic portion.
+func Time(key string, v time.Time) Attr {
+ return slog.Time(key, v)
+}
+
+// Duration returns an Attr for a time.Duration.
+func Duration(key string, v time.Duration) Attr {
+ return slog.Duration(key, v)
+}
+
+// Group returns an Attr for a Group Value.
+// The first argument is the key; the remaining arguments
+// are converted to Attrs as in [Logger.Log].
+//
+// Use Group to collect several key-value pairs under a single
+// key on a log line, or as the result of LogValue
+// in order to log a single value as multiple Attrs.
+func Group(key string, args ...any) Attr {
+ return slog.Group(key, args...)
+}
+
+// Any returns an Attr for the supplied value.
+// See [Value.AnyValue] for how values are treated.
+func Any(key string, value any) Attr {
+ return slog.Any(key, value)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/flake.lock b/vendor/github.com/sagikazarmark/slog-shim/flake.lock
new file mode 100644
index 000000000..7e8898e9e
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/flake.lock
@@ -0,0 +1,273 @@
+{
+ "nodes": {
+ "devenv": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "nix": "nix",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks"
+ },
+ "locked": {
+ "lastModified": 1694097209,
+ "narHash": "sha256-gQmBjjxeSyySjbh0yQVBKApo2KWIFqqbRUvG+Fa+QpM=",
+ "owner": "cachix",
+ "repo": "devenv",
+ "rev": "7a8e6a91510efe89d8dcb8e43233f93e86f6b189",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "devenv",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1693611461,
+ "narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1685518550,
+ "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "devenv",
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "lowdown-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1633514407,
+ "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "type": "github"
+ }
+ },
+ "nix": {
+ "inputs": {
+ "lowdown-src": "lowdown-src",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-regression": "nixpkgs-regression"
+ },
+ "locked": {
+ "lastModified": 1676545802,
+ "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=",
+ "owner": "domenkozar",
+ "repo": "nix",
+ "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "domenkozar",
+ "ref": "relaxed-flakes",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1678875422,
+ "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1693471703,
+ "narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-regression": {
+ "locked": {
+ "lastModified": 1643052045,
+ "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1685801374,
+ "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1694345580,
+ "narHash": "sha256-BbG0NUxQTz1dN/Y87yPWZc/0Kp/coJ0vM3+7sNa5kUM=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "f002de6834fdde9c864f33c1ec51da7df19cd832",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "master",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": [
+ "devenv",
+ "flake-compat"
+ ],
+ "flake-utils": "flake-utils",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1688056373,
+ "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "devenv": "devenv",
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs_2"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/flake.nix b/vendor/github.com/sagikazarmark/slog-shim/flake.nix
new file mode 100644
index 000000000..7239bbc2e
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/flake.nix
@@ -0,0 +1,57 @@
+{
+ inputs = {
+ # nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ nixpkgs.url = "github:NixOS/nixpkgs/master";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ devenv.url = "github:cachix/devenv";
+ };
+
+ outputs = inputs@{ flake-parts, ... }:
+ flake-parts.lib.mkFlake { inherit inputs; } {
+ imports = [
+ inputs.devenv.flakeModule
+ ];
+
+ systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ];
+
+ perSystem = { config, self', inputs', pkgs, system, ... }: rec {
+ devenv.shells = {
+ default = {
+ languages = {
+ go.enable = true;
+ go.package = pkgs.lib.mkDefault pkgs.go_1_21;
+ };
+
+ # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767
+ containers = pkgs.lib.mkForce { };
+ };
+
+ ci = devenv.shells.default;
+
+ ci_1_19 = {
+ imports = [ devenv.shells.ci ];
+
+ languages = {
+ go.package = pkgs.go_1_19;
+ };
+ };
+
+ ci_1_20 = {
+ imports = [ devenv.shells.ci ];
+
+ languages = {
+ go.package = pkgs.go_1_20;
+ };
+ };
+
+ ci_1_21 = {
+ imports = [ devenv.shells.ci ];
+
+ languages = {
+ go.package = pkgs.go_1_21;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/handler.go b/vendor/github.com/sagikazarmark/slog-shim/handler.go
new file mode 100644
index 000000000..f55556ae1
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/handler.go
@@ -0,0 +1,45 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "log/slog"
+)
+
+// A Handler handles log records produced by a Logger..
+//
+// A typical handler may print log records to standard error,
+// or write them to a file or database, or perhaps augment them
+// with additional attributes and pass them on to another handler.
+//
+// Any of the Handler's methods may be called concurrently with itself
+// or with other methods. It is the responsibility of the Handler to
+// manage this concurrency.
+//
+// Users of the slog package should not invoke Handler methods directly.
+// They should use the methods of [Logger] instead.
+type Handler = slog.Handler
+
+// HandlerOptions are options for a TextHandler or JSONHandler.
+// A zero HandlerOptions consists entirely of default values.
+type HandlerOptions = slog.HandlerOptions
+
+// Keys for "built-in" attributes.
+const (
+ // TimeKey is the key used by the built-in handlers for the time
+ // when the log method is called. The associated Value is a [time.Time].
+ TimeKey = slog.TimeKey
+ // LevelKey is the key used by the built-in handlers for the level
+ // of the log call. The associated value is a [Level].
+ LevelKey = slog.LevelKey
+ // MessageKey is the key used by the built-in handlers for the
+ // message of the log call. The associated value is a string.
+ MessageKey = slog.MessageKey
+ // SourceKey is the key used by the built-in handlers for the source file
+ // and line of the log call. The associated value is a string.
+ SourceKey = slog.SourceKey
+)
diff --git a/vendor/github.com/sagikazarmark/slog-shim/handler_120.go b/vendor/github.com/sagikazarmark/slog-shim/handler_120.go
new file mode 100644
index 000000000..670057573
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/handler_120.go
@@ -0,0 +1,45 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "golang.org/x/exp/slog"
+)
+
+// A Handler handles log records produced by a Logger..
+//
+// A typical handler may print log records to standard error,
+// or write them to a file or database, or perhaps augment them
+// with additional attributes and pass them on to another handler.
+//
+// Any of the Handler's methods may be called concurrently with itself
+// or with other methods. It is the responsibility of the Handler to
+// manage this concurrency.
+//
+// Users of the slog package should not invoke Handler methods directly.
+// They should use the methods of [Logger] instead.
+type Handler = slog.Handler
+
+// HandlerOptions are options for a TextHandler or JSONHandler.
+// A zero HandlerOptions consists entirely of default values.
+type HandlerOptions = slog.HandlerOptions
+
+// Keys for "built-in" attributes.
+const (
+ // TimeKey is the key used by the built-in handlers for the time
+ // when the log method is called. The associated Value is a [time.Time].
+ TimeKey = slog.TimeKey
+ // LevelKey is the key used by the built-in handlers for the level
+ // of the log call. The associated value is a [Level].
+ LevelKey = slog.LevelKey
+ // MessageKey is the key used by the built-in handlers for the
+ // message of the log call. The associated value is a string.
+ MessageKey = slog.MessageKey
+ // SourceKey is the key used by the built-in handlers for the source file
+ // and line of the log call. The associated value is a string.
+ SourceKey = slog.SourceKey
+)
diff --git a/vendor/github.com/sagikazarmark/slog-shim/json_handler.go b/vendor/github.com/sagikazarmark/slog-shim/json_handler.go
new file mode 100644
index 000000000..7c22bd81e
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/json_handler.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "io"
+ "log/slog"
+)
+
+// JSONHandler is a Handler that writes Records to an io.Writer as
+// line-delimited JSON objects.
+type JSONHandler = slog.JSONHandler
+
+// NewJSONHandler creates a JSONHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler {
+ return slog.NewJSONHandler(w, opts)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go b/vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go
new file mode 100644
index 000000000..7b14f10ba
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go
@@ -0,0 +1,24 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "io"
+
+ "golang.org/x/exp/slog"
+)
+
+// JSONHandler is a Handler that writes Records to an io.Writer as
+// line-delimited JSON objects.
+type JSONHandler = slog.JSONHandler
+
+// NewJSONHandler creates a JSONHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler {
+ return slog.NewJSONHandler(w, opts)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/level.go b/vendor/github.com/sagikazarmark/slog-shim/level.go
new file mode 100644
index 000000000..07288cf89
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/level.go
@@ -0,0 +1,61 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "log/slog"
+)
+
+// A Level is the importance or severity of a log event.
+// The higher the level, the more important or severe the event.
+type Level = slog.Level
+
+// Level numbers are inherently arbitrary,
+// but we picked them to satisfy three constraints.
+// Any system can map them to another numbering scheme if it wishes.
+//
+// First, we wanted the default level to be Info, Since Levels are ints, Info is
+// the default value for int, zero.
+//
+// Second, we wanted to make it easy to use levels to specify logger verbosity.
+// Since a larger level means a more severe event, a logger that accepts events
+// with smaller (or more negative) level means a more verbose logger. Logger
+// verbosity is thus the negation of event severity, and the default verbosity
+// of 0 accepts all events at least as severe as INFO.
+//
+// Third, we wanted some room between levels to accommodate schemes with named
+// levels between ours. For example, Google Cloud Logging defines a Notice level
+// between Info and Warn. Since there are only a few of these intermediate
+// levels, the gap between the numbers need not be large. Our gap of 4 matches
+// OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the
+// DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog
+// Level range. OpenTelemetry also has the names TRACE and FATAL, which slog
+// does not. But those OpenTelemetry levels can still be represented as slog
+// Levels by using the appropriate integers.
+//
+// Names for common levels.
+const (
+ LevelDebug Level = slog.LevelDebug
+ LevelInfo Level = slog.LevelInfo
+ LevelWarn Level = slog.LevelWarn
+ LevelError Level = slog.LevelError
+)
+
+// A LevelVar is a Level variable, to allow a Handler level to change
+// dynamically.
+// It implements Leveler as well as a Set method,
+// and it is safe for use by multiple goroutines.
+// The zero LevelVar corresponds to LevelInfo.
+type LevelVar = slog.LevelVar
+
+// A Leveler provides a Level value.
+//
+// As Level itself implements Leveler, clients typically supply
+// a Level value wherever a Leveler is needed, such as in HandlerOptions.
+// Clients who need to vary the level dynamically can provide a more complex
+// Leveler implementation such as *LevelVar.
+type Leveler = slog.Leveler
diff --git a/vendor/github.com/sagikazarmark/slog-shim/level_120.go b/vendor/github.com/sagikazarmark/slog-shim/level_120.go
new file mode 100644
index 000000000..d3feb9420
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/level_120.go
@@ -0,0 +1,61 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "golang.org/x/exp/slog"
+)
+
+// A Level is the importance or severity of a log event.
+// The higher the level, the more important or severe the event.
+type Level = slog.Level
+
+// Level numbers are inherently arbitrary,
+// but we picked them to satisfy three constraints.
+// Any system can map them to another numbering scheme if it wishes.
+//
+// First, we wanted the default level to be Info, Since Levels are ints, Info is
+// the default value for int, zero.
+//
+// Second, we wanted to make it easy to use levels to specify logger verbosity.
+// Since a larger level means a more severe event, a logger that accepts events
+// with smaller (or more negative) level means a more verbose logger. Logger
+// verbosity is thus the negation of event severity, and the default verbosity
+// of 0 accepts all events at least as severe as INFO.
+//
+// Third, we wanted some room between levels to accommodate schemes with named
+// levels between ours. For example, Google Cloud Logging defines a Notice level
+// between Info and Warn. Since there are only a few of these intermediate
+// levels, the gap between the numbers need not be large. Our gap of 4 matches
+// OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the
+// DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog
+// Level range. OpenTelemetry also has the names TRACE and FATAL, which slog
+// does not. But those OpenTelemetry levels can still be represented as slog
+// Levels by using the appropriate integers.
+//
+// Names for common levels.
+const (
+ LevelDebug Level = slog.LevelDebug
+ LevelInfo Level = slog.LevelInfo
+ LevelWarn Level = slog.LevelWarn
+ LevelError Level = slog.LevelError
+)
+
+// A LevelVar is a Level variable, to allow a Handler level to change
+// dynamically.
+// It implements Leveler as well as a Set method,
+// and it is safe for use by multiple goroutines.
+// The zero LevelVar corresponds to LevelInfo.
+type LevelVar = slog.LevelVar
+
+// A Leveler provides a Level value.
+//
+// As Level itself implements Leveler, clients typically supply
+// a Level value wherever a Leveler is needed, such as in HandlerOptions.
+// Clients who need to vary the level dynamically can provide a more complex
+// Leveler implementation such as *LevelVar.
+type Leveler = slog.Leveler
diff --git a/vendor/github.com/sagikazarmark/slog-shim/logger.go b/vendor/github.com/sagikazarmark/slog-shim/logger.go
new file mode 100644
index 000000000..e80036bec
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/logger.go
@@ -0,0 +1,98 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "context"
+ "log"
+ "log/slog"
+)
+
+// Default returns the default Logger.
+func Default() *Logger { return slog.Default() }
+
+// SetDefault makes l the default Logger.
+// After this call, output from the log package's default Logger
+// (as with [log.Print], etc.) will be logged at LevelInfo using l's Handler.
+func SetDefault(l *Logger) {
+ slog.SetDefault(l)
+}
+
+// A Logger records structured information about each call to its
+// Log, Debug, Info, Warn, and Error methods.
+// For each call, it creates a Record and passes it to a Handler.
+//
+// To create a new Logger, call [New] or a Logger method
+// that begins "With".
+type Logger = slog.Logger
+
+// New creates a new Logger with the given non-nil Handler.
+func New(h Handler) *Logger {
+ return slog.New(h)
+}
+
+// With calls Logger.With on the default logger.
+func With(args ...any) *Logger {
+ return slog.With(args...)
+}
+
+// NewLogLogger returns a new log.Logger such that each call to its Output method
+// dispatches a Record to the specified handler. The logger acts as a bridge from
+// the older log API to newer structured logging handlers.
+func NewLogLogger(h Handler, level Level) *log.Logger {
+ return slog.NewLogLogger(h, level)
+}
+
+// Debug calls Logger.Debug on the default logger.
+func Debug(msg string, args ...any) {
+ slog.Debug(msg, args...)
+}
+
+// DebugContext calls Logger.DebugContext on the default logger.
+func DebugContext(ctx context.Context, msg string, args ...any) {
+ slog.DebugContext(ctx, msg, args...)
+}
+
+// Info calls Logger.Info on the default logger.
+func Info(msg string, args ...any) {
+ slog.Info(msg, args...)
+}
+
+// InfoContext calls Logger.InfoContext on the default logger.
+func InfoContext(ctx context.Context, msg string, args ...any) {
+ slog.InfoContext(ctx, msg, args...)
+}
+
+// Warn calls Logger.Warn on the default logger.
+func Warn(msg string, args ...any) {
+ slog.Warn(msg, args...)
+}
+
+// WarnContext calls Logger.WarnContext on the default logger.
+func WarnContext(ctx context.Context, msg string, args ...any) {
+ slog.WarnContext(ctx, msg, args...)
+}
+
+// Error calls Logger.Error on the default logger.
+func Error(msg string, args ...any) {
+ slog.Error(msg, args...)
+}
+
+// ErrorContext calls Logger.ErrorContext on the default logger.
+func ErrorContext(ctx context.Context, msg string, args ...any) {
+ slog.ErrorContext(ctx, msg, args...)
+}
+
+// Log calls Logger.Log on the default logger.
+func Log(ctx context.Context, level Level, msg string, args ...any) {
+ slog.Log(ctx, level, msg, args...)
+}
+
+// LogAttrs calls Logger.LogAttrs on the default logger.
+func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ slog.LogAttrs(ctx, level, msg, attrs...)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/logger_120.go b/vendor/github.com/sagikazarmark/slog-shim/logger_120.go
new file mode 100644
index 000000000..97ebdd5e1
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/logger_120.go
@@ -0,0 +1,99 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "context"
+ "log"
+
+ "golang.org/x/exp/slog"
+)
+
+// Default returns the default Logger.
+func Default() *Logger { return slog.Default() }
+
+// SetDefault makes l the default Logger.
+// After this call, output from the log package's default Logger
+// (as with [log.Print], etc.) will be logged at LevelInfo using l's Handler.
+func SetDefault(l *Logger) {
+ slog.SetDefault(l)
+}
+
+// A Logger records structured information about each call to its
+// Log, Debug, Info, Warn, and Error methods.
+// For each call, it creates a Record and passes it to a Handler.
+//
+// To create a new Logger, call [New] or a Logger method
+// that begins "With".
+type Logger = slog.Logger
+
+// New creates a new Logger with the given non-nil Handler.
+func New(h Handler) *Logger {
+ return slog.New(h)
+}
+
+// With calls Logger.With on the default logger.
+func With(args ...any) *Logger {
+ return slog.With(args...)
+}
+
+// NewLogLogger returns a new log.Logger such that each call to its Output method
+// dispatches a Record to the specified handler. The logger acts as a bridge from
+// the older log API to newer structured logging handlers.
+func NewLogLogger(h Handler, level Level) *log.Logger {
+ return slog.NewLogLogger(h, level)
+}
+
+// Debug calls Logger.Debug on the default logger.
+func Debug(msg string, args ...any) {
+ slog.Debug(msg, args...)
+}
+
+// DebugContext calls Logger.DebugContext on the default logger.
+func DebugContext(ctx context.Context, msg string, args ...any) {
+ slog.DebugContext(ctx, msg, args...)
+}
+
+// Info calls Logger.Info on the default logger.
+func Info(msg string, args ...any) {
+ slog.Info(msg, args...)
+}
+
+// InfoContext calls Logger.InfoContext on the default logger.
+func InfoContext(ctx context.Context, msg string, args ...any) {
+ slog.InfoContext(ctx, msg, args...)
+}
+
+// Warn calls Logger.Warn on the default logger.
+func Warn(msg string, args ...any) {
+ slog.Warn(msg, args...)
+}
+
+// WarnContext calls Logger.WarnContext on the default logger.
+func WarnContext(ctx context.Context, msg string, args ...any) {
+ slog.WarnContext(ctx, msg, args...)
+}
+
+// Error calls Logger.Error on the default logger.
+func Error(msg string, args ...any) {
+ slog.Error(msg, args...)
+}
+
+// ErrorContext calls Logger.ErrorContext on the default logger.
+func ErrorContext(ctx context.Context, msg string, args ...any) {
+ slog.ErrorContext(ctx, msg, args...)
+}
+
+// Log calls Logger.Log on the default logger.
+func Log(ctx context.Context, level Level, msg string, args ...any) {
+ slog.Log(ctx, level, msg, args...)
+}
+
+// LogAttrs calls Logger.LogAttrs on the default logger.
+func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ slog.LogAttrs(ctx, level, msg, attrs...)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/record.go b/vendor/github.com/sagikazarmark/slog-shim/record.go
new file mode 100644
index 000000000..85ad1f784
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/record.go
@@ -0,0 +1,31 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "log/slog"
+ "time"
+)
+
+// A Record holds information about a log event.
+// Copies of a Record share state.
+// Do not modify a Record after handing out a copy to it.
+// Call [NewRecord] to create a new Record.
+// Use [Record.Clone] to create a copy with no shared state.
+type Record = slog.Record
+
+// NewRecord creates a Record from the given arguments.
+// Use [Record.AddAttrs] to add attributes to the Record.
+//
+// NewRecord is intended for logging APIs that want to support a [Handler] as
+// a backend.
+func NewRecord(t time.Time, level Level, msg string, pc uintptr) Record {
+ return slog.NewRecord(t, level, msg, pc)
+}
+
+// Source describes the location of a line of source code.
+type Source = slog.Source
diff --git a/vendor/github.com/sagikazarmark/slog-shim/record_120.go b/vendor/github.com/sagikazarmark/slog-shim/record_120.go
new file mode 100644
index 000000000..c2eaf4e79
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/record_120.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "time"
+
+ "golang.org/x/exp/slog"
+)
+
+// A Record holds information about a log event.
+// Copies of a Record share state.
+// Do not modify a Record after handing out a copy to it.
+// Call [NewRecord] to create a new Record.
+// Use [Record.Clone] to create a copy with no shared state.
+type Record = slog.Record
+
+// NewRecord creates a Record from the given arguments.
+// Use [Record.AddAttrs] to add attributes to the Record.
+//
+// NewRecord is intended for logging APIs that want to support a [Handler] as
+// a backend.
+func NewRecord(t time.Time, level Level, msg string, pc uintptr) Record {
+ return slog.NewRecord(t, level, msg, pc)
+}
+
+// Source describes the location of a line of source code.
+type Source = slog.Source
diff --git a/vendor/github.com/sagikazarmark/slog-shim/text_handler.go b/vendor/github.com/sagikazarmark/slog-shim/text_handler.go
new file mode 100644
index 000000000..45f6cfcba
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/text_handler.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "io"
+ "log/slog"
+)
+
+// TextHandler is a Handler that writes Records to an io.Writer as a
+// sequence of key=value pairs separated by spaces and followed by a newline.
+type TextHandler = slog.TextHandler
+
+// NewTextHandler creates a TextHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewTextHandler(w io.Writer, opts *HandlerOptions) *TextHandler {
+ return slog.NewTextHandler(w, opts)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go b/vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go
new file mode 100644
index 000000000..a69d63cce
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go
@@ -0,0 +1,24 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "io"
+
+ "golang.org/x/exp/slog"
+)
+
+// TextHandler is a Handler that writes Records to an io.Writer as a
+// sequence of key=value pairs separated by spaces and followed by a newline.
+type TextHandler = slog.TextHandler
+
+// NewTextHandler creates a TextHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewTextHandler(w io.Writer, opts *HandlerOptions) *TextHandler {
+ return slog.NewTextHandler(w, opts)
+}
diff --git a/vendor/github.com/sagikazarmark/slog-shim/value.go b/vendor/github.com/sagikazarmark/slog-shim/value.go
new file mode 100644
index 000000000..61173eb94
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/value.go
@@ -0,0 +1,109 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package slog
+
+import (
+ "log/slog"
+ "time"
+)
+
+// A Value can represent any Go value, but unlike type any,
+// it can represent most small values without an allocation.
+// The zero Value corresponds to nil.
+type Value = slog.Value
+
+// Kind is the kind of a Value.
+type Kind = slog.Kind
+
+// The following list is sorted alphabetically, but it's also important that
+// KindAny is 0 so that a zero Value represents nil.
+const (
+ KindAny = slog.KindAny
+ KindBool = slog.KindBool
+ KindDuration = slog.KindDuration
+ KindFloat64 = slog.KindFloat64
+ KindInt64 = slog.KindInt64
+ KindString = slog.KindString
+ KindTime = slog.KindTime
+ KindUint64 = slog.KindUint64
+ KindGroup = slog.KindGroup
+ KindLogValuer = slog.KindLogValuer
+)
+
+//////////////// Constructors
+
+// StringValue returns a new Value for a string.
+func StringValue(value string) Value {
+ return slog.StringValue(value)
+}
+
+// IntValue returns a Value for an int.
+func IntValue(v int) Value {
+ return slog.IntValue(v)
+}
+
+// Int64Value returns a Value for an int64.
+func Int64Value(v int64) Value {
+ return slog.Int64Value(v)
+}
+
+// Uint64Value returns a Value for a uint64.
+func Uint64Value(v uint64) Value {
+ return slog.Uint64Value(v)
+}
+
+// Float64Value returns a Value for a floating-point number.
+func Float64Value(v float64) Value {
+ return slog.Float64Value(v)
+}
+
+// BoolValue returns a Value for a bool.
+func BoolValue(v bool) Value {
+ return slog.BoolValue(v)
+}
+
+// TimeValue returns a Value for a time.Time.
+// It discards the monotonic portion.
+func TimeValue(v time.Time) Value {
+ return slog.TimeValue(v)
+}
+
+// DurationValue returns a Value for a time.Duration.
+func DurationValue(v time.Duration) Value {
+ return slog.DurationValue(v)
+}
+
+// GroupValue returns a new Value for a list of Attrs.
+// The caller must not subsequently mutate the argument slice.
+func GroupValue(as ...Attr) Value {
+ return slog.GroupValue(as...)
+}
+
+// AnyValue returns a Value for the supplied value.
+//
+// If the supplied value is of type Value, it is returned
+// unmodified.
+//
+// Given a value of one of Go's predeclared string, bool, or
+// (non-complex) numeric types, AnyValue returns a Value of kind
+// String, Bool, Uint64, Int64, or Float64. The width of the
+// original numeric type is not preserved.
+//
+// Given a time.Time or time.Duration value, AnyValue returns a Value of kind
+// KindTime or KindDuration. The monotonic time is not preserved.
+//
+// For nil, or values of all other types, including named types whose
+// underlying type is numeric, AnyValue returns a value of kind KindAny.
+func AnyValue(v any) Value {
+ return slog.AnyValue(v)
+}
+
+// A LogValuer is any Go value that can convert itself into a Value for logging.
+//
+// This mechanism may be used to defer expensive operations until they are
+// needed, or to expand a single value into a sequence of components.
+type LogValuer = slog.LogValuer
diff --git a/vendor/github.com/sagikazarmark/slog-shim/value_120.go b/vendor/github.com/sagikazarmark/slog-shim/value_120.go
new file mode 100644
index 000000000..0f9f871ee
--- /dev/null
+++ b/vendor/github.com/sagikazarmark/slog-shim/value_120.go
@@ -0,0 +1,110 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.21
+
+package slog
+
+import (
+ "time"
+
+ "golang.org/x/exp/slog"
+)
+
+// A Value can represent any Go value, but unlike type any,
+// it can represent most small values without an allocation.
+// The zero Value corresponds to nil.
+type Value = slog.Value
+
+// Kind is the kind of a Value.
+type Kind = slog.Kind
+
+// The following list is sorted alphabetically, but it's also important that
+// KindAny is 0 so that a zero Value represents nil.
+const (
+ KindAny = slog.KindAny
+ KindBool = slog.KindBool
+ KindDuration = slog.KindDuration
+ KindFloat64 = slog.KindFloat64
+ KindInt64 = slog.KindInt64
+ KindString = slog.KindString
+ KindTime = slog.KindTime
+ KindUint64 = slog.KindUint64
+ KindGroup = slog.KindGroup
+ KindLogValuer = slog.KindLogValuer
+)
+
+//////////////// Constructors
+
+// StringValue returns a new Value for a string.
+func StringValue(value string) Value {
+ return slog.StringValue(value)
+}
+
+// IntValue returns a Value for an int.
+func IntValue(v int) Value {
+ return slog.IntValue(v)
+}
+
+// Int64Value returns a Value for an int64.
+func Int64Value(v int64) Value {
+ return slog.Int64Value(v)
+}
+
+// Uint64Value returns a Value for a uint64.
+func Uint64Value(v uint64) Value {
+ return slog.Uint64Value(v)
+}
+
+// Float64Value returns a Value for a floating-point number.
+func Float64Value(v float64) Value {
+ return slog.Float64Value(v)
+}
+
+// BoolValue returns a Value for a bool.
+func BoolValue(v bool) Value {
+ return slog.BoolValue(v)
+}
+
+// TimeValue returns a Value for a time.Time.
+// It discards the monotonic portion.
+func TimeValue(v time.Time) Value {
+ return slog.TimeValue(v)
+}
+
+// DurationValue returns a Value for a time.Duration.
+func DurationValue(v time.Duration) Value {
+ return slog.DurationValue(v)
+}
+
+// GroupValue returns a new Value for a list of Attrs.
+// The caller must not subsequently mutate the argument slice.
+func GroupValue(as ...Attr) Value {
+ return slog.GroupValue(as...)
+}
+
+// AnyValue returns a Value for the supplied value.
+//
+// If the supplied value is of type Value, it is returned
+// unmodified.
+//
+// Given a value of one of Go's predeclared string, bool, or
+// (non-complex) numeric types, AnyValue returns a Value of kind
+// String, Bool, Uint64, Int64, or Float64. The width of the
+// original numeric type is not preserved.
+//
+// Given a time.Time or time.Duration value, AnyValue returns a Value of kind
+// KindTime or KindDuration. The monotonic time is not preserved.
+//
+// For nil, or values of all other types, including named types whose
+// underlying type is numeric, AnyValue returns a value of kind KindAny.
+func AnyValue(v any) Value {
+ return slog.AnyValue(v)
+}
+
+// A LogValuer is any Go value that can convert itself into a Value for logging.
+//
+// This mechanism may be used to defer expensive operations until they are
+// needed, or to expand a single value into a sequence of components.
+type LogValuer = slog.LogValuer
diff --git a/vendor/github.com/sourcegraph/conc/.golangci.yml b/vendor/github.com/sourcegraph/conc/.golangci.yml
new file mode 100644
index 000000000..ae65a760a
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/.golangci.yml
@@ -0,0 +1,11 @@
+linters:
+ disable-all: true
+ enable:
+ - errcheck
+ - godot
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - typecheck
+ - unused
diff --git a/vendor/github.com/spf13/jwalterweatherman/LICENSE b/vendor/github.com/sourcegraph/conc/LICENSE
index 4527efb9c..1081f4ef4 100644
--- a/vendor/github.com/spf13/jwalterweatherman/LICENSE
+++ b/vendor/github.com/sourcegraph/conc/LICENSE
@@ -1,6 +1,6 @@
-The MIT License (MIT)
+MIT License
-Copyright (c) 2014 Steve Francia
+Copyright (c) 2023 Sourcegraph
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE. \ No newline at end of file
+SOFTWARE.
diff --git a/vendor/github.com/sourcegraph/conc/README.md b/vendor/github.com/sourcegraph/conc/README.md
new file mode 100644
index 000000000..1c87c3c96
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/README.md
@@ -0,0 +1,464 @@
+![conch](https://user-images.githubusercontent.com/12631702/210295964-785cc63d-d697-420c-99ff-f492eb81dec9.svg)
+
+# `conc`: better structured concurrency for go
+
+[![Go Reference](https://pkg.go.dev/badge/github.com/sourcegraph/conc.svg)](https://pkg.go.dev/github.com/sourcegraph/conc)
+[![Sourcegraph](https://img.shields.io/badge/view%20on-sourcegraph-A112FE?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAEZklEQVRoQ+2aXWgUZxSG3292sxtNN43BhBakFPyhxSujRSxiU1pr7SaGXqgUxOIEW0IFkeYighYUxAuLUlq0lrq2iCDpjWtmFVtoG6QVNOCFVShVLyxIk0DVjZLMxt3xTGTccd2ZOd/8JBHci0CY9zvnPPN+/7sCIXwKavOwAcy2QgngQiIztDSE0OwQlDPYR1ebiaH6J5kZChyfW12gRG4QVgGTBfMchMbFP9Sn5nlZL2D0JjLD6710lc+z0NfqSGTXQRQ4bX07Mq423yoBL3OSyHSvUxirMuaEvgbJWrdcvkHMoJwxYuq4INUhyuWvQa1jvdMGxAvCxJlyEC9XOBCWL04wwRzpbDoDQ7wfZJzIQLi5Eggk6DiRhZgWIAbE3NrM4A3LPT8Q7UgqAqLqTmLSHLGPkyzG/qXEczhd0q6RH+zaSBfaUoc4iQx19pIClIscrTkNZzG6gd7qMY6eC2Hqyo705ZfTf+eqJmhMzcSbYtQpOXc92ZsZjLVAL4YNUQbJ5Ttg4CQrQdGYj44Xr9m1XJCzmZusFDJOWNpHjmh5x624a2ZFtOKDVL+uNo2TuXE3bZQQZUf8gtgqP31uI94Z/rMqix+IGiRfWw3xN9dCgVx+L3WrHm4Dju6PXz/EkjuXJ6R+IGgyOE1TbZqTq9y1eo0EZo7oMo1ktPu3xjHvuiLT5AFNszUyDULtWpzE2/fEsey8O5TbWuGWwxrs5rS7nFNMWJrNh2No74s9Ec4vRNmRRzPXMP19fBMSVsGcOJ98G8N3Wl2gXcbTjbX7vUBxLaeASDQCm5Cu/0E2tvtb0Ea+BowtskFD0wvlc6Rf2M+Jx7dTu7ubFr2dnKDRaMQe2v/tcIrNB7FH0O50AcrBaApmRDVwFO31ql3pD8QW4dP0feNwl/Q+kFEtRyIGyaWXnpy1OO0qNJWHo1y6iCmAGkBb/Ru+HenDWIF2mo4r8G+tRRzoniSn2uqFLxANhe9LKHVyTbz6egk9+x5w5fK6ulSNNMhZ/Feno+GebLZV6isTTa6k5qNl5RnZ5u56Ib6SBvFzaWBBVFZzvnERWlt/Cg4l27XChLCqFyLekjhy6xJyoytgjPf7opIB8QPx7sYFiMXHPGt76m741MhCKMZfng0nBOIjmoJPsLqWHwgFpe6V6qtfcopxveR2Oy+J0ntIN/zCWkf8QNAJ7y6d8Bq4lxLc2/qJl5K7t432XwcqX5CrI34gzATWuYILQtdQPyePDK3iuOekCR3Efjhig1B1Uq5UoXEEoZX7d1q535J5S9VOeFyYyEBku5XTMXXKQTToX5Rg7OI44nbW5oKYeYK4EniMeF0YFNSmb+grhc84LyRCEP1/OurOcipCQbKxDeK2V5FcVyIDMQvsgz5gwFhcWWwKyRlvQ3gv29RwWoDYAbIofNyBxI9eDlQ+n3YgsgCWnr4MStGXQXmv9pF2La/k3OccV54JEBM4yp9EsXa/3LfO0dGPcYq0Y7DfZB8nJzZw2rppHgKgVHs8L5wvRwAAAABJRU5ErkJggg==)](https://sourcegraph.com/github.com/sourcegraph/conc)
+[![Go Report Card](https://goreportcard.com/badge/github.com/sourcegraph/conc)](https://goreportcard.com/report/github.com/sourcegraph/conc)
+[![codecov](https://codecov.io/gh/sourcegraph/conc/branch/main/graph/badge.svg?token=MQZTEA1QWT)](https://codecov.io/gh/sourcegraph/conc)
+[![Discord](https://img.shields.io/badge/discord-chat-%235765F2)](https://discord.gg/bvXQXmtRjN)
+
+`conc` is your toolbelt for structured concurrency in go, making common tasks
+easier and safer.
+
+```sh
+go get github.com/sourcegraph/conc
+```
+
+# At a glance
+
+- Use [`conc.WaitGroup`](https://pkg.go.dev/github.com/sourcegraph/conc#WaitGroup) if you just want a safer version of `sync.WaitGroup`
+- Use [`pool.Pool`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#Pool) if you want a concurrency-limited task runner
+- Use [`pool.ResultPool`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#ResultPool) if you want a concurrent task runner that collects task results
+- Use [`pool.(Result)?ErrorPool`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#ErrorPool) if your tasks are fallible
+- Use [`pool.(Result)?ContextPool`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#ContextPool) if your tasks should be canceled on failure
+- Use [`stream.Stream`](https://pkg.go.dev/github.com/sourcegraph/conc/stream#Stream) if you want to process an ordered stream of tasks in parallel with serial callbacks
+- Use [`iter.Map`](https://pkg.go.dev/github.com/sourcegraph/conc/iter#Map) if you want to concurrently map a slice
+- Use [`iter.ForEach`](https://pkg.go.dev/github.com/sourcegraph/conc/iter#ForEach) if you want to concurrently iterate over a slice
+- Use [`panics.Catcher`](https://pkg.go.dev/github.com/sourcegraph/conc/panics#Catcher) if you want to catch panics in your own goroutines
+
+All pools are created with
+[`pool.New()`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#New)
+or
+[`pool.NewWithResults[T]()`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#NewWithResults),
+then configured with methods:
+
+- [`p.WithMaxGoroutines()`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#Pool.MaxGoroutines) configures the maximum number of goroutines in the pool
+- [`p.WithErrors()`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#Pool.WithErrors) configures the pool to run tasks that return errors
+- [`p.WithContext(ctx)`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#Pool.WithContext) configures the pool to run tasks that should be canceled on first error
+- [`p.WithFirstError()`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#ErrorPool.WithFirstError) configures error pools to only keep the first returned error rather than an aggregated error
+- [`p.WithCollectErrored()`](https://pkg.go.dev/github.com/sourcegraph/conc/pool#ResultContextPool.WithCollectErrored) configures result pools to collect results even when the task errored
+
+# Goals
+
+The main goals of the package are:
+1) Make it harder to leak goroutines
+2) Handle panics gracefully
+3) Make concurrent code easier to read
+
+## Goal #1: Make it harder to leak goroutines
+
+A common pain point when working with goroutines is cleaning them up. It's
+really easy to fire off a `go` statement and fail to properly wait for it to
+complete.
+
+`conc` takes the opinionated stance that all concurrency should be scoped.
+That is, goroutines should have an owner and that owner should always
+ensure that its owned goroutines exit properly.
+
+In `conc`, the owner of a goroutine is always a `conc.WaitGroup`. Goroutines
+are spawned in a `WaitGroup` with `(*WaitGroup).Go()`, and
+`(*WaitGroup).Wait()` should always be called before the `WaitGroup` goes out
+of scope.
+
+In some cases, you might want a spawned goroutine to outlast the scope of the
+caller. In that case, you could pass a `WaitGroup` into the spawning function.
+
+```go
+func main() {
+ var wg conc.WaitGroup
+ defer wg.Wait()
+
+ startTheThing(&wg)
+}
+
+func startTheThing(wg *conc.WaitGroup) {
+ wg.Go(func() { ... })
+}
+```
+
+For some more discussion on why scoped concurrency is nice, check out [this
+blog
+post](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/).
+
+## Goal #2: Handle panics gracefully
+
+A frequent problem with goroutines in long-running applications is handling
+panics. A goroutine spawned without a panic handler will crash the whole process
+on panic. This is usually undesirable.
+
+However, if you do add a panic handler to a goroutine, what do you do with the
+panic once you catch it? Some options:
+1) Ignore it
+2) Log it
+3) Turn it into an error and return that to the goroutine spawner
+4) Propagate the panic to the goroutine spawner
+
+Ignoring panics is a bad idea since panics usually mean there is actually
+something wrong and someone should fix it.
+
+Just logging panics isn't great either because then there is no indication to the spawner
+that something bad happened, and it might just continue on as normal even though your
+program is in a really bad state.
+
+Both (3) and (4) are reasonable options, but both require the goroutine to have
+an owner that can actually receive the message that something went wrong. This
+is generally not true with a goroutine spawned with `go`, but in the `conc`
+package, all goroutines have an owner that must collect the spawned goroutine.
+In the conc package, any call to `Wait()` will panic if any of the spawned goroutines
+panicked. Additionally, it decorates the panic value with a stacktrace from the child
+goroutine so that you don't lose information about what caused the panic.
+
+Doing this all correctly every time you spawn something with `go` is not
+trivial and it requires a lot of boilerplate that makes the important parts of
+the code more difficult to read, so `conc` does this for you.
+
+<table>
+<tr>
+<th><code>stdlib</code></th>
+<th><code>conc</code></th>
+</tr>
+<tr>
+<td>
+
+```go
+type caughtPanicError struct {
+ val any
+ stack []byte
+}
+
+func (e *caughtPanicError) Error() string {
+ return fmt.Sprintf(
+ "panic: %q\n%s",
+ e.val,
+ string(e.stack)
+ )
+}
+
+func main() {
+ done := make(chan error)
+ go func() {
+ defer func() {
+ if v := recover(); v != nil {
+ done <- &caughtPanicError{
+ val: v,
+ stack: debug.Stack()
+ }
+ } else {
+ done <- nil
+ }
+ }()
+ doSomethingThatMightPanic()
+ }()
+ err := <-done
+ if err != nil {
+ panic(err)
+ }
+}
+```
+</td>
+<td>
+
+```go
+func main() {
+ var wg conc.WaitGroup
+ wg.Go(doSomethingThatMightPanic)
+ // panics with a nice stacktrace
+ wg.Wait()
+}
+```
+</td>
+</tr>
+</table>
+
+## Goal #3: Make concurrent code easier to read
+
+Doing concurrency correctly is difficult. Doing it in a way that doesn't
+obfuscate what the code is actually doing is more difficult. The `conc` package
+attempts to make common operations easier by abstracting as much boilerplate
+complexity as possible.
+
+Want to run a set of concurrent tasks with a bounded set of goroutines? Use
+`pool.New()`. Want to process an ordered stream of results concurrently, but
+still maintain order? Try `stream.New()`. What about a concurrent map over
+a slice? Take a peek at `iter.Map()`.
+
+Browse some examples below for some comparisons with doing these by hand.
+
+# Examples
+
+Each of these examples forgoes propagating panics for simplicity. To see
+what kind of complexity that would add, check out the "Goal #2" header above.
+
+Spawn a set of goroutines and waiting for them to finish:
+
+<table>
+<tr>
+<th><code>stdlib</code></th>
+<th><code>conc</code></th>
+</tr>
+<tr>
+<td>
+
+```go
+func main() {
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ // crashes on panic!
+ doSomething()
+ }()
+ }
+ wg.Wait()
+}
+```
+</td>
+<td>
+
+```go
+func main() {
+ var wg conc.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Go(doSomething)
+ }
+ wg.Wait()
+}
+```
+</td>
+</tr>
+</table>
+
+Process each element of a stream in a static pool of goroutines:
+
+<table>
+<tr>
+<th><code>stdlib</code></th>
+<th><code>conc</code></th>
+</tr>
+<tr>
+<td>
+
+```go
+func process(stream chan int) {
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for elem := range stream {
+ handle(elem)
+ }
+ }()
+ }
+ wg.Wait()
+}
+```
+</td>
+<td>
+
+```go
+func process(stream chan int) {
+ p := pool.New().WithMaxGoroutines(10)
+ for elem := range stream {
+ elem := elem
+ p.Go(func() {
+ handle(elem)
+ })
+ }
+ p.Wait()
+}
+```
+</td>
+</tr>
+</table>
+
+Process each element of a slice in a static pool of goroutines:
+
+<table>
+<tr>
+<th><code>stdlib</code></th>
+<th><code>conc</code></th>
+</tr>
+<tr>
+<td>
+
+```go
+func process(values []int) {
+ feeder := make(chan int, 8)
+
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for elem := range feeder {
+ handle(elem)
+ }
+ }()
+ }
+
+ for _, value := range values {
+ feeder <- value
+ }
+ close(feeder)
+ wg.Wait()
+}
+```
+</td>
+<td>
+
+```go
+func process(values []int) {
+ iter.ForEach(values, handle)
+}
+```
+</td>
+</tr>
+</table>
+
+Concurrently map a slice:
+
+<table>
+<tr>
+<th><code>stdlib</code></th>
+<th><code>conc</code></th>
+</tr>
+<tr>
+<td>
+
+```go
+func concMap(
+ input []int,
+ f func(int) int,
+) []int {
+ res := make([]int, len(input))
+ var idx atomic.Int64
+
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ for {
+ i := int(idx.Add(1) - 1)
+ if i >= len(input) {
+ return
+ }
+
+ res[i] = f(input[i])
+ }
+ }()
+ }
+ wg.Wait()
+ return res
+}
+```
+</td>
+<td>
+
+```go
+func concMap(
+ input []int,
+ f func(*int) int,
+) []int {
+ return iter.Map(input, f)
+}
+```
+</td>
+</tr>
+</table>
+
+Process an ordered stream concurrently:
+
+
+<table>
+<tr>
+<th><code>stdlib</code></th>
+<th><code>conc</code></th>
+</tr>
+<tr>
+<td>
+
+```go
+func mapStream(
+ in chan int,
+ out chan int,
+ f func(int) int,
+) {
+ tasks := make(chan func())
+ taskResults := make(chan chan int)
+
+ // Worker goroutines
+ var workerWg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ workerWg.Add(1)
+ go func() {
+ defer workerWg.Done()
+ for task := range tasks {
+ task()
+ }
+ }()
+ }
+
+ // Ordered reader goroutines
+ var readerWg sync.WaitGroup
+ readerWg.Add(1)
+ go func() {
+ defer readerWg.Done()
+ for result := range taskResults {
+ item := <-result
+ out <- item
+ }
+ }()
+
+ // Feed the workers with tasks
+ for elem := range in {
+ resultCh := make(chan int, 1)
+ taskResults <- resultCh
+ tasks <- func() {
+ resultCh <- f(elem)
+ }
+ }
+
+ // We've exhausted input.
+ // Wait for everything to finish
+ close(tasks)
+ workerWg.Wait()
+ close(taskResults)
+ readerWg.Wait()
+}
+```
+</td>
+<td>
+
+```go
+func mapStream(
+ in chan int,
+ out chan int,
+ f func(int) int,
+) {
+ s := stream.New().WithMaxGoroutines(10)
+ for elem := range in {
+ elem := elem
+ s.Go(func() stream.Callback {
+ res := f(elem)
+ return func() { out <- res }
+ })
+ }
+ s.Wait()
+}
+```
+</td>
+</tr>
+</table>
+
+# Status
+
+This package is currently pre-1.0. There are likely to be minor breaking
+changes before a 1.0 release as we stabilize the APIs and tweak defaults.
+Please open an issue if you have questions, concerns, or requests that you'd
+like addressed before the 1.0 release. Currently, a 1.0 is targeted for
+March 2023.
diff --git a/vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go119.go b/vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go119.go
new file mode 100644
index 000000000..7087e32a8
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go119.go
@@ -0,0 +1,10 @@
+//go:build !go1.20
+// +build !go1.20
+
+package multierror
+
+import "go.uber.org/multierr"
+
+var (
+ Join = multierr.Combine
+)
diff --git a/vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go120.go b/vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go120.go
new file mode 100644
index 000000000..39cff829a
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go120.go
@@ -0,0 +1,10 @@
+//go:build go1.20
+// +build go1.20
+
+package multierror
+
+import "errors"
+
+var (
+ Join = errors.Join
+)
diff --git a/vendor/github.com/sourcegraph/conc/iter/iter.go b/vendor/github.com/sourcegraph/conc/iter/iter.go
new file mode 100644
index 000000000..124b4f940
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/iter/iter.go
@@ -0,0 +1,85 @@
+package iter
+
+import (
+ "runtime"
+ "sync/atomic"
+
+ "github.com/sourcegraph/conc"
+)
+
+// defaultMaxGoroutines returns the default maximum number of
+// goroutines to use within this package.
+func defaultMaxGoroutines() int { return runtime.GOMAXPROCS(0) }
+
+// Iterator can be used to configure the behaviour of ForEach
+// and ForEachIdx. The zero value is safe to use with reasonable
+// defaults.
+//
+// Iterator is also safe for reuse and concurrent use.
+type Iterator[T any] struct {
+ // MaxGoroutines controls the maximum number of goroutines
+ // to use on this Iterator's methods.
+ //
+ // If unset, MaxGoroutines defaults to runtime.GOMAXPROCS(0).
+ MaxGoroutines int
+}
+
+// ForEach executes f in parallel over each element in input.
+//
+// It is safe to mutate the input parameter, which makes it
+// possible to map in place.
+//
+// ForEach always uses at most runtime.GOMAXPROCS goroutines.
+// It takes roughly 2µs to start up the goroutines and adds
+// an overhead of roughly 50ns per element of input. For
+// a configurable goroutine limit, use a custom Iterator.
+func ForEach[T any](input []T, f func(*T)) { Iterator[T]{}.ForEach(input, f) }
+
+// ForEach executes f in parallel over each element in input,
+// using up to the Iterator's configured maximum number of
+// goroutines.
+//
+// It is safe to mutate the input parameter, which makes it
+// possible to map in place.
+//
+// It takes roughly 2µs to start up the goroutines and adds
+// an overhead of roughly 50ns per element of input.
+func (iter Iterator[T]) ForEach(input []T, f func(*T)) {
+ iter.ForEachIdx(input, func(_ int, t *T) {
+ f(t)
+ })
+}
+
+// ForEachIdx is the same as ForEach except it also provides the
+// index of the element to the callback.
+func ForEachIdx[T any](input []T, f func(int, *T)) { Iterator[T]{}.ForEachIdx(input, f) }
+
+// ForEachIdx is the same as ForEach except it also provides the
+// index of the element to the callback.
+func (iter Iterator[T]) ForEachIdx(input []T, f func(int, *T)) {
+ if iter.MaxGoroutines == 0 {
+ // iter is a value receiver and is hence safe to mutate
+ iter.MaxGoroutines = defaultMaxGoroutines()
+ }
+
+ numInput := len(input)
+ if iter.MaxGoroutines > numInput {
+ // No more concurrent tasks than the number of input items.
+ iter.MaxGoroutines = numInput
+ }
+
+ var idx atomic.Int64
+ // Create the task outside the loop to avoid extra closure allocations.
+ task := func() {
+ i := int(idx.Add(1) - 1)
+ for ; i < numInput; i = int(idx.Add(1) - 1) {
+ f(i, &input[i])
+ }
+ }
+
+ var wg conc.WaitGroup
+ for i := 0; i < iter.MaxGoroutines; i++ {
+ wg.Go(task)
+ }
+ wg.Wait()
+}
diff --git a/vendor/github.com/sourcegraph/conc/iter/map.go b/vendor/github.com/sourcegraph/conc/iter/map.go
new file mode 100644
index 000000000..efbe6bfaf
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/iter/map.go
@@ -0,0 +1,65 @@
+package iter
+
+import (
+ "sync"
+
+ "github.com/sourcegraph/conc/internal/multierror"
+)
+
+// Mapper is an Iterator with a result type R. It can be used to configure
+// the behaviour of Map and MapErr. The zero value is safe to use with
+// reasonable defaults.
+//
+// Mapper is also safe for reuse and concurrent use.
+type Mapper[T, R any] Iterator[T]
+
+// Map applies f to each element of input, returning the mapped result.
+//
+// Map always uses at most runtime.GOMAXPROCS goroutines. For a configurable
+// goroutine limit, use a custom Mapper.
+func Map[T, R any](input []T, f func(*T) R) []R {
+ return Mapper[T, R]{}.Map(input, f)
+}
+
+// Map applies f to each element of input, returning the mapped result.
+//
+// Map uses up to the configured Mapper's maximum number of goroutines.
+func (m Mapper[T, R]) Map(input []T, f func(*T) R) []R {
+ res := make([]R, len(input))
+ Iterator[T](m).ForEachIdx(input, func(i int, t *T) {
+ res[i] = f(t)
+ })
+ return res
+}
+
+// MapErr applies f to each element of the input, returning the mapped result
+// and a combined error of all returned errors.
+//
+// Map always uses at most runtime.GOMAXPROCS goroutines. For a configurable
+// goroutine limit, use a custom Mapper.
+func MapErr[T, R any](input []T, f func(*T) (R, error)) ([]R, error) {
+ return Mapper[T, R]{}.MapErr(input, f)
+}
+
+// MapErr applies f to each element of the input, returning the mapped result
+// and a combined error of all returned errors.
+//
+// Map uses up to the configured Mapper's maximum number of goroutines.
+func (m Mapper[T, R]) MapErr(input []T, f func(*T) (R, error)) ([]R, error) {
+ var (
+ res = make([]R, len(input))
+ errMux sync.Mutex
+ errs error
+ )
+ Iterator[T](m).ForEachIdx(input, func(i int, t *T) {
+ var err error
+ res[i], err = f(t)
+ if err != nil {
+ errMux.Lock()
+ // TODO: use stdlib errors once multierrors land in go 1.20
+ errs = multierror.Join(errs, err)
+ errMux.Unlock()
+ }
+ })
+ return res, errs
+}
diff --git a/vendor/github.com/sourcegraph/conc/panics/panics.go b/vendor/github.com/sourcegraph/conc/panics/panics.go
new file mode 100644
index 000000000..abbed7fa0
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/panics/panics.go
@@ -0,0 +1,102 @@
+package panics
+
+import (
+ "fmt"
+ "runtime"
+ "runtime/debug"
+ "sync/atomic"
+)
+
+// Catcher is used to catch panics. You can execute a function with Try,
+// which will catch any spawned panic. Try can be called any number of times,
+// from any number of goroutines. Once all calls to Try have completed, you can
+// get the value of the first panic (if any) with Recovered(), or you can just
+// propagate the panic (re-panic) with Repanic().
+type Catcher struct {
+ recovered atomic.Pointer[Recovered]
+}
+
+// Try executes f, catching any panic it might spawn. It is safe
+// to call from multiple goroutines simultaneously.
+func (p *Catcher) Try(f func()) {
+ defer p.tryRecover()
+ f()
+}
+
+func (p *Catcher) tryRecover() {
+ if val := recover(); val != nil {
+ rp := NewRecovered(1, val)
+ p.recovered.CompareAndSwap(nil, &rp)
+ }
+}
+
+// Repanic panics if any calls to Try caught a panic. It will panic with the
+// value of the first panic caught, wrapped in a panics.Recovered with caller
+// information.
+func (p *Catcher) Repanic() {
+ if val := p.Recovered(); val != nil {
+ panic(val)
+ }
+}
+
+// Recovered returns the value of the first panic caught by Try, or nil if
+// no calls to Try panicked.
+func (p *Catcher) Recovered() *Recovered {
+ return p.recovered.Load()
+}
+
+// NewRecovered creates a panics.Recovered from a panic value and a collected
+// stacktrace. The skip parameter allows the caller to skip stack frames when
+// collecting the stacktrace. Calling with a skip of 0 means include the call to
+// NewRecovered in the stacktrace.
+func NewRecovered(skip int, value any) Recovered {
+ // 64 frames should be plenty
+ var callers [64]uintptr
+ n := runtime.Callers(skip+1, callers[:])
+ return Recovered{
+ Value: value,
+ Callers: callers[:n],
+ Stack: debug.Stack(),
+ }
+}
+
+// Recovered is a panic that was caught with recover().
+type Recovered struct {
+ // The original value of the panic.
+ Value any
+ // The caller list as returned by runtime.Callers when the panic was
+ // recovered. Can be used to produce a more detailed stack information with
+ // runtime.CallersFrames.
+ Callers []uintptr
+ // The formatted stacktrace from the goroutine where the panic was recovered.
+ // Easier to use than Callers.
+ Stack []byte
+}
+
+// String renders a human-readable formatting of the panic.
+func (p *Recovered) String() string {
+ return fmt.Sprintf("panic: %v\nstacktrace:\n%s\n", p.Value, p.Stack)
+}
+
+// AsError casts the panic into an error implementation. The implementation
+// is unwrappable with the cause of the panic, if the panic was provided one.
+func (p *Recovered) AsError() error {
+ if p == nil {
+ return nil
+ }
+ return &ErrRecovered{*p}
+}
+
+// ErrRecovered wraps a panics.Recovered in an error implementation.
+type ErrRecovered struct{ Recovered }
+
+var _ error = (*ErrRecovered)(nil)
+
+func (p *ErrRecovered) Error() string { return p.String() }
+
+func (p *ErrRecovered) Unwrap() error {
+ if err, ok := p.Value.(error); ok {
+ return err
+ }
+ return nil
+}
diff --git a/vendor/github.com/sourcegraph/conc/panics/try.go b/vendor/github.com/sourcegraph/conc/panics/try.go
new file mode 100644
index 000000000..4ded92a1c
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/panics/try.go
@@ -0,0 +1,11 @@
+package panics
+
+// Try executes f, catching and returning any panic it might spawn.
+//
+// The recovered panic can be propagated with panic(), or handled as a normal error with
+// (*panics.Recovered).AsError().
+func Try(f func()) *Recovered {
+ var c Catcher
+ c.Try(f)
+ return c.Recovered()
+}
diff --git a/vendor/github.com/sourcegraph/conc/waitgroup.go b/vendor/github.com/sourcegraph/conc/waitgroup.go
new file mode 100644
index 000000000..47b1bc1a5
--- /dev/null
+++ b/vendor/github.com/sourcegraph/conc/waitgroup.go
@@ -0,0 +1,52 @@
+package conc
+
+import (
+ "sync"
+
+ "github.com/sourcegraph/conc/panics"
+)
+
+// NewWaitGroup creates a new WaitGroup.
+func NewWaitGroup() *WaitGroup {
+ return &WaitGroup{}
+}
+
+// WaitGroup is the primary building block for scoped concurrency.
+// Goroutines can be spawned in the WaitGroup with the Go method,
+// and calling Wait() will ensure that each of those goroutines exits
+// before continuing. Any panics in a child goroutine will be caught
+// and propagated to the caller of Wait().
+//
+// The zero value of WaitGroup is usable, just like sync.WaitGroup.
+// Also like sync.WaitGroup, it must not be copied after first use.
+type WaitGroup struct {
+ wg sync.WaitGroup
+ pc panics.Catcher
+}
+
+// Go spawns a new goroutine in the WaitGroup.
+func (h *WaitGroup) Go(f func()) {
+ h.wg.Add(1)
+ go func() {
+ defer h.wg.Done()
+ h.pc.Try(f)
+ }()
+}
+
+// Wait will block until all goroutines spawned with Go exit and will
+// propagate any panics spawned in a child goroutine.
+func (h *WaitGroup) Wait() {
+ h.wg.Wait()
+
+ // Propagate a panic if we caught one from a child goroutine.
+ h.pc.Repanic()
+}
+
+// WaitAndRecover will block until all goroutines spawned with Go exit and
+// will return a *panics.Recovered if one of the child goroutines panics.
+func (h *WaitGroup) WaitAndRecover() *panics.Recovered {
+ h.wg.Wait()
+
+ // Return a recovered panic if we caught one from a child goroutine.
+ return h.pc.Recovered()
+}
diff --git a/vendor/github.com/spf13/afero/const_bsds.go b/vendor/github.com/spf13/afero/const_bsds.go
index eed0f225f..30855de57 100644
--- a/vendor/github.com/spf13/afero/const_bsds.go
+++ b/vendor/github.com/spf13/afero/const_bsds.go
@@ -11,8 +11,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-//go:build aix || darwin || openbsd || freebsd || netbsd || dragonfly
-// +build aix darwin openbsd freebsd netbsd dragonfly
+//go:build aix || darwin || openbsd || freebsd || netbsd || dragonfly || zos
+// +build aix darwin openbsd freebsd netbsd dragonfly zos
package afero
diff --git a/vendor/github.com/spf13/afero/const_win_unix.go b/vendor/github.com/spf13/afero/const_win_unix.go
index 004d57e2f..12792d21e 100644
--- a/vendor/github.com/spf13/afero/const_win_unix.go
+++ b/vendor/github.com/spf13/afero/const_win_unix.go
@@ -10,8 +10,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//go:build !darwin && !openbsd && !freebsd && !dragonfly && !netbsd && !aix
-// +build !darwin,!openbsd,!freebsd,!dragonfly,!netbsd,!aix
+//go:build !darwin && !openbsd && !freebsd && !dragonfly && !netbsd && !aix && !zos
+// +build !darwin,!openbsd,!freebsd,!dragonfly,!netbsd,!aix,!zos
package afero
diff --git a/vendor/github.com/spf13/afero/memmap.go b/vendor/github.com/spf13/afero/memmap.go
index e6b7d70b9..d6c744e8d 100644
--- a/vendor/github.com/spf13/afero/memmap.go
+++ b/vendor/github.com/spf13/afero/memmap.go
@@ -16,9 +16,12 @@ package afero
import (
"fmt"
"io"
+
"log"
"os"
"path/filepath"
+
+ "sort"
"strings"
"sync"
"time"
@@ -88,6 +91,24 @@ func (m *MemMapFs) findParent(f *mem.FileData) *mem.FileData {
return pfile
}
+func (m *MemMapFs) findDescendants(name string) []*mem.FileData {
+ fData := m.getData()
+ descendants := make([]*mem.FileData, 0, len(fData))
+ for p, dFile := range fData {
+ if strings.HasPrefix(p, name+FilePathSeparator) {
+ descendants = append(descendants, dFile)
+ }
+ }
+
+ sort.Slice(descendants, func(i, j int) bool {
+ cur := len(strings.Split(descendants[i].Name(), FilePathSeparator))
+ next := len(strings.Split(descendants[j].Name(), FilePathSeparator))
+ return cur < next
+ })
+
+ return descendants
+}
+
func (m *MemMapFs) registerWithParent(f *mem.FileData, perm os.FileMode) {
if f == nil {
return
@@ -309,29 +330,51 @@ func (m *MemMapFs) Rename(oldname, newname string) error {
if _, ok := m.getData()[oldname]; ok {
m.mu.RUnlock()
m.mu.Lock()
- m.unRegisterWithParent(oldname)
+ err := m.unRegisterWithParent(oldname)
+ if err != nil {
+ return err
+ }
+
fileData := m.getData()[oldname]
- delete(m.getData(), oldname)
mem.ChangeFileName(fileData, newname)
m.getData()[newname] = fileData
+
+ err = m.renameDescendants(oldname, newname)
+ if err != nil {
+ return err
+ }
+
+ delete(m.getData(), oldname)
+
m.registerWithParent(fileData, 0)
m.mu.Unlock()
m.mu.RLock()
} else {
return &os.PathError{Op: "rename", Path: oldname, Err: ErrFileNotFound}
}
+ return nil
+}
- for p, fileData := range m.getData() {
- if strings.HasPrefix(p, oldname+FilePathSeparator) {
- m.mu.RUnlock()
- m.mu.Lock()
- delete(m.getData(), p)
- p := strings.Replace(p, oldname, newname, 1)
- m.getData()[p] = fileData
- m.mu.Unlock()
- m.mu.RLock()
+func (m *MemMapFs) renameDescendants(oldname, newname string) error {
+ descendants := m.findDescendants(oldname)
+ removes := make([]string, 0, len(descendants))
+ for _, desc := range descendants {
+ descNewName := strings.Replace(desc.Name(), oldname, newname, 1)
+ err := m.unRegisterWithParent(desc.Name())
+ if err != nil {
+ return err
}
+
+ removes = append(removes, desc.Name())
+ mem.ChangeFileName(desc, descNewName)
+ m.getData()[descNewName] = desc
+
+ m.registerWithParent(desc, 0)
+ }
+ for _, r := range removes {
+ delete(m.getData(), r)
}
+
return nil
}
diff --git a/vendor/github.com/spf13/cast/README.md b/vendor/github.com/spf13/cast/README.md
index 58141f02f..0e9e14593 100644
--- a/vendor/github.com/spf13/cast/README.md
+++ b/vendor/github.com/spf13/cast/README.md
@@ -1,9 +1,9 @@
# cast
-[![Build Status](https://github.com/spf13/cast/actions/workflows/ci.yml/badge.svg)](https://github.com/spf13/cast/actions/workflows/ci.yml)
+[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spf13/cast/ci.yaml?branch=master&style=flat-square)](https://github.com/spf13/cast/actions/workflows/ci.yaml)
[![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/spf13/cast)](https://pkg.go.dev/mod/github.com/spf13/cast)
![Go Version](https://img.shields.io/badge/go%20version-%3E=1.16-61CFDD.svg?style=flat-square)
-[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cast)](https://goreportcard.com/report/github.com/spf13/cast)
+[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cast?style=flat-square)](https://goreportcard.com/report/github.com/spf13/cast)
Easy and safe casting from one type to another in Go
diff --git a/vendor/github.com/spf13/jwalterweatherman/.gitignore b/vendor/github.com/spf13/jwalterweatherman/.gitignore
deleted file mode 100644
index a71f88af8..000000000
--- a/vendor/github.com/spf13/jwalterweatherman/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.bench
-go.sum \ No newline at end of file
diff --git a/vendor/github.com/spf13/jwalterweatherman/README.md b/vendor/github.com/spf13/jwalterweatherman/README.md
deleted file mode 100644
index 932a23fc6..000000000
--- a/vendor/github.com/spf13/jwalterweatherman/README.md
+++ /dev/null
@@ -1,148 +0,0 @@
-jWalterWeatherman
-=================
-
-Seamless printing to the terminal (stdout) and logging to a io.Writer
-(file) that’s as easy to use as fmt.Println.
-
-![and_that__s_why_you_always_leave_a_note_by_jonnyetc-d57q7um](https://cloud.githubusercontent.com/assets/173412/11002937/ccd01654-847d-11e5-828e-12ebaf582eaf.jpg)
-Graphic by [JonnyEtc](http://jonnyetc.deviantart.com/art/And-That-s-Why-You-Always-Leave-a-Note-315311422)
-
-JWW is primarily a wrapper around the excellent standard log library. It
-provides a few advantages over using the standard log library alone.
-
-1. Ready to go out of the box.
-2. One library for both printing to the terminal and logging (to files).
-3. Really easy to log to either a temp file or a file you specify.
-
-
-I really wanted a very straightforward library that could seamlessly do
-the following things.
-
-1. Replace all the println, printf, etc statements thoughout my code with
- something more useful
-2. Allow the user to easily control what levels are printed to stdout
-3. Allow the user to easily control what levels are logged
-4. Provide an easy mechanism (like fmt.Println) to print info to the user
- which can be easily logged as well
-5. Due to 2 & 3 provide easy verbose mode for output and logs
-6. Not have any unnecessary initialization cruft. Just use it.
-
-# Usage
-
-## Step 1. Use it
-Put calls throughout your source based on type of feedback.
-No initialization or setup needs to happen. Just start calling things.
-
-Available Loggers are:
-
- * TRACE
- * DEBUG
- * INFO
- * WARN
- * ERROR
- * CRITICAL
- * FATAL
-
-These each are loggers based on the log standard library and follow the
-standard usage. Eg.
-
-```go
- import (
- jww "github.com/spf13/jwalterweatherman"
- )
-
- ...
-
- if err != nil {
-
- // This is a pretty serious error and the user should know about
- // it. It will be printed to the terminal as well as logged under the
- // default thresholds.
-
- jww.ERROR.Println(err)
- }
-
- if err2 != nil {
- // This error isn’t going to materially change the behavior of the
- // application, but it’s something that may not be what the user
- // expects. Under the default thresholds, Warn will be logged, but
- // not printed to the terminal.
-
- jww.WARN.Println(err2)
- }
-
- // Information that’s relevant to what’s happening, but not very
- // important for the user. Under the default thresholds this will be
- // discarded.
-
- jww.INFO.Printf("information %q", response)
-
-```
-
-NOTE: You can also use the library in a non-global setting by creating an instance of a Notebook:
-
-```go
-notepad = jww.NewNotepad(jww.LevelInfo, jww.LevelTrace, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
-notepad.WARN.Println("Some warning"")
-```
-
-_Why 7 levels?_
-
-Maybe you think that 7 levels are too much for any application... and you
-are probably correct. Just because there are seven levels doesn’t mean
-that you should be using all 7 levels. Pick the right set for your needs.
-Remember they only have to mean something to your project.
-
-## Step 2. Optionally configure JWW
-
-Under the default thresholds :
-
- * Debug, Trace & Info goto /dev/null
- * Warn and above is logged (when a log file/io.Writer is provided)
- * Error and above is printed to the terminal (stdout)
-
-### Changing the thresholds
-
-The threshold can be changed at any time, but will only affect calls that
-execute after the change was made.
-
-This is very useful if your application has a verbose mode. Of course you
-can decide what verbose means to you or even have multiple levels of
-verbosity.
-
-
-```go
- import (
- jww "github.com/spf13/jwalterweatherman"
- )
-
- if Verbose {
- jww.SetLogThreshold(jww.LevelTrace)
- jww.SetStdoutThreshold(jww.LevelInfo)
- }
-```
-
-Note that JWW's own internal output uses log levels as well, so set the log
-level before making any other calls if you want to see what it's up to.
-
-
-### Setting a log file
-
-JWW can log to any `io.Writer`:
-
-
-```go
-
- jww.SetLogOutput(customWriter)
-
-```
-
-
-# More information
-
-This is an early release. I’ve been using it for a while and this is the
-third interface I’ve tried. I like this one pretty well, but no guarantees
-that it won’t change a bit.
-
-I wrote this for use in [hugo](https://gohugo.io). If you are looking
-for a static website engine that’s super fast please checkout Hugo.
diff --git a/vendor/github.com/spf13/jwalterweatherman/default_notepad.go b/vendor/github.com/spf13/jwalterweatherman/default_notepad.go
deleted file mode 100644
index a018c15c4..000000000
--- a/vendor/github.com/spf13/jwalterweatherman/default_notepad.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright © 2016 Steve Francia <spf@spf13.com>.
-//
-// Use of this source code is governed by an MIT-style
-// license that can be found in the LICENSE file.
-
-package jwalterweatherman
-
-import (
- "io"
- "io/ioutil"
- "log"
- "os"
-)
-
-var (
- TRACE *log.Logger
- DEBUG *log.Logger
- INFO *log.Logger
- WARN *log.Logger
- ERROR *log.Logger
- CRITICAL *log.Logger
- FATAL *log.Logger
-
- LOG *log.Logger
- FEEDBACK *Feedback
-
- defaultNotepad *Notepad
-)
-
-func reloadDefaultNotepad() {
- TRACE = defaultNotepad.TRACE
- DEBUG = defaultNotepad.DEBUG
- INFO = defaultNotepad.INFO
- WARN = defaultNotepad.WARN
- ERROR = defaultNotepad.ERROR
- CRITICAL = defaultNotepad.CRITICAL
- FATAL = defaultNotepad.FATAL
-
- LOG = defaultNotepad.LOG
- FEEDBACK = defaultNotepad.FEEDBACK
-}
-
-func init() {
- defaultNotepad = NewNotepad(LevelError, LevelWarn, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
- reloadDefaultNotepad()
-}
-
-// SetLogThreshold set the log threshold for the default notepad. Trace by default.
-func SetLogThreshold(threshold Threshold) {
- defaultNotepad.SetLogThreshold(threshold)
- reloadDefaultNotepad()
-}
-
-// SetLogOutput set the log output for the default notepad. Discarded by default.
-func SetLogOutput(handle io.Writer) {
- defaultNotepad.SetLogOutput(handle)
- reloadDefaultNotepad()
-}
-
-// SetStdoutThreshold set the standard output threshold for the default notepad.
-// Info by default.
-func SetStdoutThreshold(threshold Threshold) {
- defaultNotepad.SetStdoutThreshold(threshold)
- reloadDefaultNotepad()
-}
-
-// SetStdoutOutput set the stdout output for the default notepad. Default is stdout.
-func SetStdoutOutput(handle io.Writer) {
- defaultNotepad.outHandle = handle
- defaultNotepad.init()
- reloadDefaultNotepad()
-}
-
-// SetPrefix set the prefix for the default logger. Empty by default.
-func SetPrefix(prefix string) {
- defaultNotepad.SetPrefix(prefix)
- reloadDefaultNotepad()
-}
-
-// SetFlags set the flags for the default logger. "log.Ldate | log.Ltime" by default.
-func SetFlags(flags int) {
- defaultNotepad.SetFlags(flags)
- reloadDefaultNotepad()
-}
-
-// SetLogListeners configures the default logger with one or more log listeners.
-func SetLogListeners(l ...LogListener) {
- defaultNotepad.logListeners = l
- defaultNotepad.init()
- reloadDefaultNotepad()
-}
-
-// Level returns the current global log threshold.
-func LogThreshold() Threshold {
- return defaultNotepad.logThreshold
-}
-
-// Level returns the current global output threshold.
-func StdoutThreshold() Threshold {
- return defaultNotepad.stdoutThreshold
-}
-
-// GetStdoutThreshold returns the defined Treshold for the log logger.
-func GetLogThreshold() Threshold {
- return defaultNotepad.GetLogThreshold()
-}
-
-// GetStdoutThreshold returns the Treshold for the stdout logger.
-func GetStdoutThreshold() Threshold {
- return defaultNotepad.GetStdoutThreshold()
-}
diff --git a/vendor/github.com/spf13/jwalterweatherman/log_counter.go b/vendor/github.com/spf13/jwalterweatherman/log_counter.go
deleted file mode 100644
index 41285f3dc..000000000
--- a/vendor/github.com/spf13/jwalterweatherman/log_counter.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright © 2016 Steve Francia <spf@spf13.com>.
-//
-// Use of this source code is governed by an MIT-style
-// license that can be found in the LICENSE file.
-
-package jwalterweatherman
-
-import (
- "io"
- "sync/atomic"
-)
-
-// Counter is an io.Writer that increments a counter on Write.
-type Counter struct {
- count uint64
-}
-
-func (c *Counter) incr() {
- atomic.AddUint64(&c.count, 1)
-}
-
-// Reset resets the counter.
-func (c *Counter) Reset() {
- atomic.StoreUint64(&c.count, 0)
-}
-
-// Count returns the current count.
-func (c *Counter) Count() uint64 {
- return atomic.LoadUint64(&c.count)
-}
-
-func (c *Counter) Write(p []byte) (n int, err error) {
- c.incr()
- return len(p), nil
-}
-
-// LogCounter creates a LogListener that counts log statements >= the given threshold.
-func LogCounter(counter *Counter, t1 Threshold) LogListener {
- return func(t2 Threshold) io.Writer {
- if t2 < t1 {
- // Not interested in this threshold.
- return nil
- }
- return counter
- }
-}
diff --git a/vendor/github.com/spf13/jwalterweatherman/notepad.go b/vendor/github.com/spf13/jwalterweatherman/notepad.go
deleted file mode 100644
index cc7957bf7..000000000
--- a/vendor/github.com/spf13/jwalterweatherman/notepad.go
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright © 2016 Steve Francia <spf@spf13.com>.
-//
-// Use of this source code is governed by an MIT-style
-// license that can be found in the LICENSE file.
-
-package jwalterweatherman
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "log"
-)
-
-type Threshold int
-
-func (t Threshold) String() string {
- return prefixes[t]
-}
-
-const (
- LevelTrace Threshold = iota
- LevelDebug
- LevelInfo
- LevelWarn
- LevelError
- LevelCritical
- LevelFatal
-)
-
-var prefixes map[Threshold]string = map[Threshold]string{
- LevelTrace: "TRACE",
- LevelDebug: "DEBUG",
- LevelInfo: "INFO",
- LevelWarn: "WARN",
- LevelError: "ERROR",
- LevelCritical: "CRITICAL",
- LevelFatal: "FATAL",
-}
-
-// Notepad is where you leave a note!
-type Notepad struct {
- TRACE *log.Logger
- DEBUG *log.Logger
- INFO *log.Logger
- WARN *log.Logger
- ERROR *log.Logger
- CRITICAL *log.Logger
- FATAL *log.Logger
-
- LOG *log.Logger
- FEEDBACK *Feedback
-
- loggers [7]**log.Logger
- logHandle io.Writer
- outHandle io.Writer
- logThreshold Threshold
- stdoutThreshold Threshold
- prefix string
- flags int
-
- logListeners []LogListener
-}
-
-// A LogListener can ble supplied to a Notepad to listen on log writes for a given
-// threshold. This can be used to capture log events in unit tests and similar.
-// Note that this function will be invoked once for each log threshold. If
-// the given threshold is not of interest to you, return nil.
-// Note that these listeners will receive log events for a given threshold, even
-// if the current configuration says not to log it. That way you can count ERRORs even
-// if you don't print them to the console.
-type LogListener func(t Threshold) io.Writer
-
-// NewNotepad creates a new Notepad.
-func NewNotepad(
- outThreshold Threshold,
- logThreshold Threshold,
- outHandle, logHandle io.Writer,
- prefix string, flags int,
- logListeners ...LogListener,
-) *Notepad {
-
- n := &Notepad{logListeners: logListeners}
-
- n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
- n.outHandle = outHandle
- n.logHandle = logHandle
- n.stdoutThreshold = outThreshold
- n.logThreshold = logThreshold
-
- if len(prefix) != 0 {
- n.prefix = "[" + prefix + "] "
- } else {
- n.prefix = ""
- }
-
- n.flags = flags
-
- n.LOG = log.New(n.logHandle,
- "LOG: ",
- n.flags)
- n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
-
- n.init()
- return n
-}
-
-// init creates the loggers for each level depending on the notepad thresholds.
-func (n *Notepad) init() {
- logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
-
- for t, logger := range n.loggers {
- threshold := Threshold(t)
- prefix := n.prefix + threshold.String() + " "
-
- switch {
- case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
- *logger = log.New(n.createLogWriters(threshold, logAndOut), prefix, n.flags)
-
- case threshold >= n.logThreshold:
- *logger = log.New(n.createLogWriters(threshold, n.logHandle), prefix, n.flags)
-
- case threshold >= n.stdoutThreshold:
- *logger = log.New(n.createLogWriters(threshold, n.outHandle), prefix, n.flags)
-
- default:
- *logger = log.New(n.createLogWriters(threshold, ioutil.Discard), prefix, n.flags)
- }
- }
-}
-
-func (n *Notepad) createLogWriters(t Threshold, handle io.Writer) io.Writer {
- if len(n.logListeners) == 0 {
- return handle
- }
- writers := []io.Writer{handle}
- for _, l := range n.logListeners {
- w := l(t)
- if w != nil {
- writers = append(writers, w)
- }
- }
-
- if len(writers) == 1 {
- return handle
- }
-
- return io.MultiWriter(writers...)
-}
-
-// SetLogThreshold changes the threshold above which messages are written to the
-// log file.
-func (n *Notepad) SetLogThreshold(threshold Threshold) {
- n.logThreshold = threshold
- n.init()
-}
-
-// SetLogOutput changes the file where log messages are written.
-func (n *Notepad) SetLogOutput(handle io.Writer) {
- n.logHandle = handle
- n.init()
-}
-
-// GetStdoutThreshold returns the defined Treshold for the log logger.
-func (n *Notepad) GetLogThreshold() Threshold {
- return n.logThreshold
-}
-
-// SetStdoutThreshold changes the threshold above which messages are written to the
-// standard output.
-func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
- n.stdoutThreshold = threshold
- n.init()
-}
-
-// GetStdoutThreshold returns the Treshold for the stdout logger.
-func (n *Notepad) GetStdoutThreshold() Threshold {
- return n.stdoutThreshold
-}
-
-// SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
-// brackets at the beginning of the line. An empty prefix won't be displayed at all.
-func (n *Notepad) SetPrefix(prefix string) {
- if len(prefix) != 0 {
- n.prefix = "[" + prefix + "] "
- } else {
- n.prefix = ""
- }
- n.init()
-}
-
-// SetFlags choose which flags the logger will display (after prefix and message
-// level). See the package log for more informations on this.
-func (n *Notepad) SetFlags(flags int) {
- n.flags = flags
- n.init()
-}
-
-// Feedback writes plainly to the outHandle while
-// logging with the standard extra information (date, file, etc).
-type Feedback struct {
- out *log.Logger
- log *log.Logger
-}
-
-func (fb *Feedback) Println(v ...interface{}) {
- fb.output(fmt.Sprintln(v...))
-}
-
-func (fb *Feedback) Printf(format string, v ...interface{}) {
- fb.output(fmt.Sprintf(format, v...))
-}
-
-func (fb *Feedback) Print(v ...interface{}) {
- fb.output(fmt.Sprint(v...))
-}
-
-func (fb *Feedback) output(s string) {
- if fb.out != nil {
- fb.out.Output(2, s)
- }
- if fb.log != nil {
- fb.log.Output(2, s)
- }
-}
diff --git a/vendor/github.com/spf13/viper/.editorconfig b/vendor/github.com/spf13/viper/.editorconfig
index 6d0b6d356..1f664d13a 100644
--- a/vendor/github.com/spf13/viper/.editorconfig
+++ b/vendor/github.com/spf13/viper/.editorconfig
@@ -13,3 +13,6 @@ indent_style = tab
[{Makefile,*.mk}]
indent_style = tab
+
+[*.nix]
+indent_size = 2
diff --git a/vendor/github.com/spf13/viper/.gitignore b/vendor/github.com/spf13/viper/.gitignore
index 896250839..f1bbd4280 100644
--- a/vendor/github.com/spf13/viper/.gitignore
+++ b/vendor/github.com/spf13/viper/.gitignore
@@ -1,4 +1,7 @@
+/.devenv/
+/.direnv/
/.idea/
+/.pre-commit-config.yaml
/bin/
/build/
/var/
diff --git a/vendor/github.com/spf13/viper/.golangci.yaml b/vendor/github.com/spf13/viper/.golangci.yaml
index acd9eebac..1faeae42c 100644
--- a/vendor/github.com/spf13/viper/.golangci.yaml
+++ b/vendor/github.com/spf13/viper/.golangci.yaml
@@ -7,6 +7,16 @@ linters-settings:
- standard
- default
- prefix(github.com/spf13/viper)
+ gocritic:
+ # Enable multiple checks by tags. See "Tags" section in https://github.com/go-critic/go-critic#usage.
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - style
+ disabled-checks:
+ - importShadow
+ - unnamedResult
golint:
min-confidence: 0
goimports:
@@ -22,6 +32,8 @@ linters:
- exhaustive
- exportloopref
- gci
+ - gocritic
+ - godot
- gofmt
- gofumpt
- goimports
@@ -62,9 +74,7 @@ linters:
# - gochecknoinits
# - gocognit
# - goconst
- # - gocritic
# - gocyclo
- # - godot
# - gosec
# - gosimple
# - ifshort
diff --git a/vendor/github.com/spf13/viper/.yamlignore b/vendor/github.com/spf13/viper/.yamlignore
new file mode 100644
index 000000000..c04c4dead
--- /dev/null
+++ b/vendor/github.com/spf13/viper/.yamlignore
@@ -0,0 +1,2 @@
+# TODO: FIXME
+/.github/
diff --git a/vendor/github.com/spf13/viper/.yamllint.yaml b/vendor/github.com/spf13/viper/.yamllint.yaml
new file mode 100644
index 000000000..bac19ce18
--- /dev/null
+++ b/vendor/github.com/spf13/viper/.yamllint.yaml
@@ -0,0 +1,6 @@
+ignore-from-file: [.gitignore, .yamlignore]
+
+extends: default
+
+rules:
+ line-length: disable
diff --git a/vendor/github.com/spf13/viper/Makefile b/vendor/github.com/spf13/viper/Makefile
index e8d3baaa8..a77b9c81c 100644
--- a/vendor/github.com/spf13/viper/Makefile
+++ b/vendor/github.com/spf13/viper/Makefile
@@ -16,7 +16,7 @@ endif
# Dependency versions
GOTESTSUM_VERSION = 1.9.0
-GOLANGCI_VERSION = 1.52.2
+GOLANGCI_VERSION = 1.53.3
# Add the ability to override some variables
# Use with care
@@ -29,11 +29,6 @@ clear: ## Clear the working area and the project
.PHONY: check
check: test lint ## Run tests and linters
-bin/gotestsum: bin/gotestsum-${GOTESTSUM_VERSION}
- @ln -sf gotestsum-${GOTESTSUM_VERSION} bin/gotestsum
-bin/gotestsum-${GOTESTSUM_VERSION}:
- @mkdir -p bin
- curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_${OS}_amd64.tar.gz | tar -zOxf - gotestsum > ./bin/gotestsum-${GOTESTSUM_VERSION} && chmod +x ./bin/gotestsum-${GOTESTSUM_VERSION}
TEST_PKGS ?= ./...
.PHONY: test
@@ -44,20 +39,36 @@ test: bin/gotestsum ## Run tests
@mkdir -p ${BUILD_DIR}
bin/gotestsum --no-summary=skipped --junitfile ${BUILD_DIR}/coverage.xml --format ${TEST_FORMAT} -- -race -coverprofile=${BUILD_DIR}/coverage.txt -covermode=atomic $(filter-out -v,${GOARGS}) $(if ${TEST_PKGS},${TEST_PKGS},./...)
-bin/golangci-lint: bin/golangci-lint-${GOLANGCI_VERSION}
- @ln -sf golangci-lint-${GOLANGCI_VERSION} bin/golangci-lint
-bin/golangci-lint-${GOLANGCI_VERSION}:
+.PHONY: lint
+lint: lint-go lint-yaml
+lint: ## Run linters
+
+.PHONY: lint-go
+lint-go:
+ golangci-lint run $(if ${CI},--out-format github-actions,)
+
+.PHONY: lint-yaml
+lint-yaml:
+ yamllint $(if ${CI},-f github,) --no-warnings .
+
+.PHONY: fmt
+fmt: ## Format code
+ golangci-lint run --fix
+
+deps: bin/golangci-lint bin/gotestsum yamllint
+deps: ## Install dependencies
+
+bin/gotestsum:
@mkdir -p bin
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b ./bin/ v${GOLANGCI_VERSION}
- @mv bin/golangci-lint "$@"
+ curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_${OS}_amd64.tar.gz | tar -zOxf - gotestsum > ./bin/gotestsum && chmod +x ./bin/gotestsum
-.PHONY: lint
-lint: bin/golangci-lint ## Run linter
- bin/golangci-lint run
+bin/golangci-lint:
+ @mkdir -p bin
+ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- v${GOLANGCI_VERSION}
-.PHONY: fix
-fix: bin/golangci-lint ## Fix lint violations
- bin/golangci-lint run --fix
+.PHONY: yamllint
+yamllint:
+ pip3 install --user yamllint
# Add custom targets here
-include custom.mk
diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md
index 4184d2a11..b96180b3b 100644
--- a/vendor/github.com/spf13/viper/README.md
+++ b/vendor/github.com/spf13/viper/README.md
@@ -11,7 +11,7 @@
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spf13/viper/ci.yaml?branch=master&style=flat-square)](https://github.com/spf13/viper/actions?query=workflow%3ACI)
[![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/viper?style=flat-square)](https://goreportcard.com/report/github.com/spf13/viper)
-![Go Version](https://img.shields.io/badge/go%20version-%3E=1.16-61CFDD.svg?style=flat-square)
+![Go Version](https://img.shields.io/badge/go%20version-%3E=1.19-61CFDD.svg?style=flat-square)
[![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/spf13/viper)](https://pkg.go.dev/mod/github.com/spf13/viper)
**Go configuration with fangs!**
@@ -30,6 +30,7 @@ Many Go projects are built using Viper including:
* [Meshery](https://github.com/meshery/meshery)
* [Bearer](https://github.com/bearer/bearer)
* [Coder](https://github.com/coder/coder)
+* [Vitess](https://vitess.io/)
## Install
@@ -140,7 +141,7 @@ if err := viper.ReadInConfig(); err != nil {
// Config file found and successfully parsed
```
-*NOTE [since 1.6]:* You can also have a file without an extension and specify the format programmaticaly. For those configuration files that lie in the home of the user without any extension like `.bashrc`
+*NOTE [since 1.6]:* You can also have a file without an extension and specify the format programmatically. For those configuration files that lie in the home of the user without any extension like `.bashrc`
### Writing Config Files
@@ -221,6 +222,7 @@ These could be from a command line flag, or from your own application logic.
```go
viper.Set("Verbose", true)
viper.Set("LogFile", LogFile)
+viper.Set("host.port", 5899) // set subset
```
### Registering and Using Aliases
@@ -416,6 +418,8 @@ in a Key/Value store such as etcd or Consul. These values take precedence over
default values, but are overridden by configuration values retrieved from disk,
flags, or environment variables.
+Viper supports multiple hosts. To use, pass a list of endpoints separated by `;`. For example `http://127.0.0.1:4001;http://127.0.0.1:4002`.
+
Viper uses [crypt](https://github.com/bketelsen/crypt) to retrieve
configuration from the K/V store, which means that you can store your
configuration values encrypted and have them automatically decrypted if you have
@@ -487,6 +491,15 @@ err := viper.ReadRemoteConfig()
Of course, you're allowed to use `SecureRemoteProvider` also
+
+#### NATS
+
+```go
+viper.AddRemoteProvider("nats", "nats://127.0.0.1:4222", "myapp.config")
+viper.SetConfigType("json")
+err := viper.ReadRemoteConfig()
+```
+
### Remote Key/Value Store Example - Encrypted
```go
@@ -534,24 +547,27 @@ go func(){
In Viper, there are a few ways to get a value depending on the value’s type.
The following functions and methods exist:
- * `Get(key string) : interface{}`
+ * `Get(key string) : any`
* `GetBool(key string) : bool`
* `GetFloat64(key string) : float64`
* `GetInt(key string) : int`
* `GetIntSlice(key string) : []int`
* `GetString(key string) : string`
- * `GetStringMap(key string) : map[string]interface{}`
+ * `GetStringMap(key string) : map[string]any`
* `GetStringMapString(key string) : map[string]string`
* `GetStringSlice(key string) : []string`
* `GetTime(key string) : time.Time`
* `GetDuration(key string) : time.Duration`
* `IsSet(key string) : bool`
- * `AllSettings() : map[string]interface{}`
+ * `AllSettings() : map[string]any`
One important thing to recognize is that each Get function will return a zero
value if it’s not found. To check if a given key exists, the `IsSet()` method
has been provided.
+The zero value will also be returned if the value is set, but fails to parse
+as the requested type.
+
Example:
```go
viper.GetString("logfile") // case-insensitive Setting & Getting
@@ -709,8 +725,8 @@ etc.
There are two methods to do this:
- * `Unmarshal(rawVal interface{}) : error`
- * `UnmarshalKey(key string, rawVal interface{}) : error`
+ * `Unmarshal(rawVal any) : error`
+ * `UnmarshalKey(key string, rawVal any) : error`
Example:
@@ -735,9 +751,9 @@ you have to change the delimiter:
```go
v := viper.NewWithOptions(viper.KeyDelimiter("::"))
-v.SetDefault("chart::values", map[string]interface{}{
- "ingress": map[string]interface{}{
- "annotations": map[string]interface{}{
+v.SetDefault("chart::values", map[string]any{
+ "ingress": map[string]any{
+ "annotations": map[string]any{
"traefik.frontend.rule.type": "PathPrefix",
"traefik.ingress.kubernetes.io/ssl-redirect": "true",
},
@@ -746,7 +762,7 @@ v.SetDefault("chart::values", map[string]interface{}{
type config struct {
Chart struct{
- Values map[string]interface{}
+ Values map[string]any
}
}
@@ -882,3 +898,31 @@ No, you will need to synchronize access to the viper yourself (for example by us
## Troubleshooting
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md).
+
+## Development
+
+**For an optimal developer experience, it is recommended to install [Nix](https://nixos.org/download.html) and [direnv](https://direnv.net/docs/installation.html).**
+
+_Alternatively, install [Go](https://go.dev/dl/) on your computer then run `make deps` to install the rest of the dependencies._
+
+Run the test suite:
+
+```shell
+make test
+```
+
+Run linters:
+
+```shell
+make lint # pass -j option to run them in parallel
+```
+
+Some linter violations can automatically be fixed:
+
+```shell
+make fmt
+```
+
+## License
+
+The project is licensed under the [MIT License](LICENSE).
diff --git a/vendor/github.com/spf13/viper/experimental_logger.go b/vendor/github.com/spf13/viper/experimental_logger.go
deleted file mode 100644
index 206dad6a0..000000000
--- a/vendor/github.com/spf13/viper/experimental_logger.go
+++ /dev/null
@@ -1,11 +0,0 @@
-//go:build viper_logger
-// +build viper_logger
-
-package viper
-
-// WithLogger sets a custom logger.
-func WithLogger(l Logger) Option {
- return optionFunc(func(v *Viper) {
- v.logger = l
- })
-}
diff --git a/vendor/github.com/spf13/viper/viper_go1_15.go b/vendor/github.com/spf13/viper/file.go
index 19a771cbd..a54fe5a7a 100644
--- a/vendor/github.com/spf13/viper/viper_go1_15.go
+++ b/vendor/github.com/spf13/viper/file.go
@@ -1,5 +1,4 @@
-//go:build !go1.16 || !finder
-// +build !go1.16 !finder
+//go:build !finder
package viper
@@ -44,7 +43,7 @@ func (v *Viper) searchInPath(in string) (filename string) {
return ""
}
-// Check if file Exists
+// exists checks if file exists.
func exists(fs afero.Fs, path string) (bool, error) {
stat, err := fs.Stat(path)
if err == nil {
diff --git a/vendor/github.com/spf13/viper/file_finder.go b/vendor/github.com/spf13/viper/file_finder.go
new file mode 100644
index 000000000..d96a1bd22
--- /dev/null
+++ b/vendor/github.com/spf13/viper/file_finder.go
@@ -0,0 +1,38 @@
+//go:build finder
+
+package viper
+
+import (
+ "fmt"
+
+ "github.com/sagikazarmark/locafero"
+)
+
+// Search all configPaths for any config file.
+// Returns the first path that exists (and is a config file).
+func (v *Viper) findConfigFile() (string, error) {
+ var names []string
+
+ if v.configType != "" {
+ names = locafero.NameWithOptionalExtensions(v.configName, SupportedExts...)
+ } else {
+ names = locafero.NameWithExtensions(v.configName, SupportedExts...)
+ }
+
+ finder := locafero.Finder{
+ Paths: v.configPaths,
+ Names: names,
+ Type: locafero.FileTypeFile,
+ }
+
+ results, err := finder.Find(v.fs)
+ if err != nil {
+ return "", err
+ }
+
+ if len(results) == 0 {
+ return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
+ }
+
+ return results[0], nil
+}
diff --git a/vendor/github.com/spf13/viper/flags.go b/vendor/github.com/spf13/viper/flags.go
index b5ddbf5d4..de033ed58 100644
--- a/vendor/github.com/spf13/viper/flags.go
+++ b/vendor/github.com/spf13/viper/flags.go
@@ -30,8 +30,8 @@ func (p pflagValueSet) VisitAll(fn func(flag FlagValue)) {
})
}
-// pflagValue is a wrapper aroung *pflag.flag
-// that implements FlagValue
+// pflagValue is a wrapper around *pflag.flag
+// that implements FlagValue.
type pflagValue struct {
flag *pflag.Flag
}
diff --git a/vendor/github.com/spf13/viper/flake.lock b/vendor/github.com/spf13/viper/flake.lock
new file mode 100644
index 000000000..78da51090
--- /dev/null
+++ b/vendor/github.com/spf13/viper/flake.lock
@@ -0,0 +1,255 @@
+{
+ "nodes": {
+ "devenv": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "nix": "nix",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks"
+ },
+ "locked": {
+ "lastModified": 1687972261,
+ "narHash": "sha256-+mxvZfwMVoaZYETmuQWqTi/7T9UKoAE+WpdSQkOVJ2g=",
+ "owner": "cachix",
+ "repo": "devenv",
+ "rev": "e85df562088573305e55906eaa964341f8cb0d9f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "devenv",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1687762428,
+ "narHash": "sha256-DIf7mi45PKo+s8dOYF+UlXHzE0Wl/+k3tXUyAoAnoGE=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "37dd7bb15791c86d55c5121740a1887ab55ee836",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "locked": {
+ "lastModified": 1667395993,
+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "devenv",
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "lowdown-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1633514407,
+ "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "type": "github"
+ }
+ },
+ "nix": {
+ "inputs": {
+ "lowdown-src": "lowdown-src",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-regression": "nixpkgs-regression"
+ },
+ "locked": {
+ "lastModified": 1676545802,
+ "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=",
+ "owner": "domenkozar",
+ "repo": "nix",
+ "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "domenkozar",
+ "ref": "relaxed-flakes",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1678875422,
+ "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1685564631,
+ "narHash": "sha256-8ywr3AkblY4++3lIVxmrWZFzac7+f32ZEhH/A8pNscI=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "4f53efe34b3a8877ac923b9350c874e3dcd5dc0a",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-regression": {
+ "locked": {
+ "lastModified": 1643052045,
+ "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1678872516,
+ "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "9b8e5abb18324c7fe9f07cb100c3cd4a29cda8b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-22.11",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1687886075,
+ "narHash": "sha256-PeayJDDDy+uw1Ats4moZnRdL1OFuZm1Tj+KiHlD67+o=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "a565059a348422af5af9026b5174dc5c0dcefdae",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": [
+ "devenv",
+ "flake-compat"
+ ],
+ "flake-utils": "flake-utils",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1686050334,
+ "narHash": "sha256-R0mczWjDzBpIvM3XXhO908X5e2CQqjyh/gFbwZk/7/Q=",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "rev": "6881eb2ae5d8a3516e34714e7a90d9d95914c4dc",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "devenv": "devenv",
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs_2"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/vendor/github.com/spf13/viper/flake.nix b/vendor/github.com/spf13/viper/flake.nix
new file mode 100644
index 000000000..9b26c3fcf
--- /dev/null
+++ b/vendor/github.com/spf13/viper/flake.nix
@@ -0,0 +1,56 @@
+{
+ description = "Viper";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ devenv.url = "github:cachix/devenv";
+ };
+
+ outputs = inputs@{ flake-parts, ... }:
+ flake-parts.lib.mkFlake { inherit inputs; } {
+ imports = [
+ inputs.devenv.flakeModule
+ ];
+
+ systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ];
+
+ perSystem = { config, self', inputs', pkgs, system, ... }: rec {
+ devenv.shells = {
+ default = {
+ languages = {
+ go.enable = true;
+ };
+
+ pre-commit.hooks = {
+ nixpkgs-fmt.enable = true;
+ yamllint.enable = true;
+ };
+
+ packages = with pkgs; [
+ gnumake
+
+ golangci-lint
+ yamllint
+ ];
+
+ scripts = {
+ versions.exec = ''
+ go version
+ golangci-lint version
+ '';
+ };
+
+ enterShell = ''
+ versions
+ '';
+
+ # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767
+ containers = pkgs.lib.mkForce { };
+ };
+
+ ci = devenv.shells.default;
+ };
+ };
+ };
+}
diff --git a/vendor/github.com/spf13/viper/fs.go b/vendor/github.com/spf13/viper/fs.go
deleted file mode 100644
index ecb1769e5..000000000
--- a/vendor/github.com/spf13/viper/fs.go
+++ /dev/null
@@ -1,65 +0,0 @@
-//go:build go1.16 && finder
-// +build go1.16,finder
-
-package viper
-
-import (
- "errors"
- "io/fs"
- "path"
-)
-
-type finder struct {
- paths []string
- fileNames []string
- extensions []string
-
- withoutExtension bool
-}
-
-func (f finder) Find(fsys fs.FS) (string, error) {
- for _, searchPath := range f.paths {
- for _, fileName := range f.fileNames {
- for _, extension := range f.extensions {
- filePath := path.Join(searchPath, fileName+"."+extension)
-
- ok, err := fileExists(fsys, filePath)
- if err != nil {
- return "", err
- }
-
- if ok {
- return filePath, nil
- }
- }
-
- if f.withoutExtension {
- filePath := path.Join(searchPath, fileName)
-
- ok, err := fileExists(fsys, filePath)
- if err != nil {
- return "", err
- }
-
- if ok {
- return filePath, nil
- }
- }
- }
- }
-
- return "", nil
-}
-
-func fileExists(fsys fs.FS, filePath string) (bool, error) {
- fileInfo, err := fs.Stat(fsys, filePath)
- if err == nil {
- return !fileInfo.IsDir(), nil
- }
-
- if errors.Is(err, fs.ErrNotExist) {
- return false, nil
- }
-
- return false, err
-}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/decoder.go b/vendor/github.com/spf13/viper/internal/encoding/decoder.go
index f472e9ff1..8a7b1dbc9 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/decoder.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/decoder.go
@@ -5,9 +5,9 @@ import (
)
// Decoder decodes the contents of b into v.
-// It's primarily used for decoding contents of a file into a map[string]interface{}.
+// It's primarily used for decoding contents of a file into a map[string]any.
type Decoder interface {
- Decode(b []byte, v map[string]interface{}) error
+ Decode(b []byte, v map[string]any) error
}
const (
@@ -48,7 +48,7 @@ func (e *DecoderRegistry) RegisterDecoder(format string, enc Decoder) error {
}
// Decode calls the underlying Decoder based on the format.
-func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]interface{}) error {
+func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]any) error {
e.mu.RLock()
decoder, ok := e.decoders[format]
e.mu.RUnlock()
diff --git a/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go b/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
index 4485063b6..3ebc76f02 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
@@ -15,8 +15,8 @@ const keyDelimiter = "_"
// (commonly called as dotenv format).
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
- flattened := map[string]interface{}{}
+func (Codec) Encode(v map[string]any) ([]byte, error) {
+ flattened := map[string]any{}
flattened = flattenAndMergeMap(flattened, v, "", keyDelimiter)
@@ -40,7 +40,7 @@ func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
var buf bytes.Buffer
_, err := buf.Write(b)
diff --git a/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go b/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
index ce6e6efa3..8bfe0a9de 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
@@ -7,27 +7,27 @@ import (
)
// flattenAndMergeMap recursively flattens the given map into a new map
-// Code is based on the function with the same name in tha main package.
-// TODO: move it to a common place
-func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
+// Code is based on the function with the same name in the main package.
+// TODO: move it to a common place.
+func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
if shadow != nil && prefix != "" && shadow[prefix] != nil {
// prefix is shadowed => nothing more to flatten
return shadow
}
if shadow == nil {
- shadow = make(map[string]interface{})
+ shadow = make(map[string]any)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += delimiter
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
diff --git a/vendor/github.com/spf13/viper/internal/encoding/encoder.go b/vendor/github.com/spf13/viper/internal/encoding/encoder.go
index 2341bf235..659585962 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/encoder.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/encoder.go
@@ -5,9 +5,9 @@ import (
)
// Encoder encodes the contents of v into a byte representation.
-// It's primarily used for encoding a map[string]interface{} into a file format.
+// It's primarily used for encoding a map[string]any into a file format.
type Encoder interface {
- Encode(v map[string]interface{}) ([]byte, error)
+ Encode(v map[string]any) ([]byte, error)
}
const (
@@ -47,7 +47,7 @@ func (e *EncoderRegistry) RegisterEncoder(format string, enc Encoder) error {
return nil
}
-func (e *EncoderRegistry) Encode(format string, v map[string]interface{}) ([]byte, error) {
+func (e *EncoderRegistry) Encode(format string, v map[string]any) ([]byte, error) {
e.mu.RLock()
encoder, ok := e.encoders[format]
e.mu.RUnlock()
diff --git a/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go b/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
index 7fde8e4bc..d7fa8a1b7 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
@@ -12,7 +12,7 @@ import (
// TODO: add printer config to the codec?
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
b, err := json.Marshal(v)
if err != nil {
return nil, err
@@ -35,6 +35,6 @@ func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return hcl.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go b/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
index 9acd87fc3..d91cf59d2 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
@@ -19,11 +19,11 @@ type Codec struct {
LoadOptions LoadOptions
}
-func (c Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (c Codec) Encode(v map[string]any) ([]byte, error) {
cfg := ini.Empty()
ini.PrettyFormat = false
- flattened := map[string]interface{}{}
+ flattened := map[string]any{}
flattened = flattenAndMergeMap(flattened, v, "", c.keyDelimiter())
@@ -62,7 +62,7 @@ func (c Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (c Codec) Decode(b []byte, v map[string]interface{}) error {
+func (c Codec) Decode(b []byte, v map[string]any) error {
cfg := ini.Empty(c.LoadOptions)
err := cfg.Append(b)
diff --git a/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go b/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
index 8329856b5..490ab594e 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
@@ -15,22 +15,22 @@ import (
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
-func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
+func deepSearch(m map[string]any, path []string) map[string]any {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
- m3 := make(map[string]interface{})
+ m3 := make(map[string]any)
m[k] = m3
m = m3
continue
}
- m3, ok := m2.(map[string]interface{})
+ m3, ok := m2.(map[string]any)
if !ok {
// intermediate key is a value
// => replace with a new map
- m3 = make(map[string]interface{})
+ m3 = make(map[string]any)
m[k] = m3
}
// continue search from here
@@ -40,27 +40,27 @@ func deepSearch(m map[string]interface{}, path []string) map[string]interface{}
}
// flattenAndMergeMap recursively flattens the given map into a new map
-// Code is based on the function with the same name in tha main package.
-// TODO: move it to a common place
-func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
+// Code is based on the function with the same name in the main package.
+// TODO: move it to a common place.
+func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
if shadow != nil && prefix != "" && shadow[prefix] != nil {
// prefix is shadowed => nothing more to flatten
return shadow
}
if shadow == nil {
- shadow = make(map[string]interface{})
+ shadow = make(map[string]any)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += delimiter
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
diff --git a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
index b8a2251c1..e92e5172c 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
@@ -20,12 +20,12 @@ type Codec struct {
Properties *properties.Properties
}
-func (c *Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (c *Codec) Encode(v map[string]any) ([]byte, error) {
if c.Properties == nil {
c.Properties = properties.NewProperties()
}
- flattened := map[string]interface{}{}
+ flattened := map[string]any{}
flattened = flattenAndMergeMap(flattened, v, "", c.keyDelimiter())
@@ -54,7 +54,7 @@ func (c *Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (c *Codec) Decode(b []byte, v map[string]interface{}) error {
+func (c *Codec) Decode(b []byte, v map[string]any) error {
var err error
c.Properties, err = properties.Load(b, properties.UTF8)
if err != nil {
diff --git a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
index 93755cac1..6e1aff223 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
@@ -15,22 +15,22 @@ import (
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
-func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
+func deepSearch(m map[string]any, path []string) map[string]any {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
- m3 := make(map[string]interface{})
+ m3 := make(map[string]any)
m[k] = m3
m = m3
continue
}
- m3, ok := m2.(map[string]interface{})
+ m3, ok := m2.(map[string]any)
if !ok {
// intermediate key is a value
// => replace with a new map
- m3 = make(map[string]interface{})
+ m3 = make(map[string]any)
m[k] = m3
}
// continue search from here
@@ -40,27 +40,27 @@ func deepSearch(m map[string]interface{}, path []string) map[string]interface{}
}
// flattenAndMergeMap recursively flattens the given map into a new map
-// Code is based on the function with the same name in tha main package.
-// TODO: move it to a common place
-func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
+// Code is based on the function with the same name in the main package.
+// TODO: move it to a common place.
+func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
if shadow != nil && prefix != "" && shadow[prefix] != nil {
// prefix is shadowed => nothing more to flatten
return shadow
}
if shadow == nil {
- shadow = make(map[string]interface{})
+ shadow = make(map[string]any)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += delimiter
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
diff --git a/vendor/github.com/spf13/viper/internal/encoding/json/codec.go b/vendor/github.com/spf13/viper/internal/encoding/json/codec.go
index 1b7caaceb..da7546b5a 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/json/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/json/codec.go
@@ -7,11 +7,11 @@ import (
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for JSON encoding.
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
// TODO: expose prefix and indent in the Codec as setting?
return json.MarshalIndent(v, "", " ")
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return json.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go b/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
index a993c5994..c70aa8d28 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
@@ -7,10 +7,10 @@ import (
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding.
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
return toml.Marshal(v)
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return toml.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go b/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
index 82dc136a3..036879249 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
@@ -5,10 +5,10 @@ import "gopkg.in/yaml.v3"
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for YAML encoding.
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
return yaml.Marshal(v)
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return yaml.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/features/bind_struct.go b/vendor/github.com/spf13/viper/internal/features/bind_struct.go
new file mode 100644
index 000000000..89302c216
--- /dev/null
+++ b/vendor/github.com/spf13/viper/internal/features/bind_struct.go
@@ -0,0 +1,5 @@
+//go:build viper_bind_struct
+
+package features
+
+const BindStruct = true
diff --git a/vendor/github.com/spf13/viper/internal/features/bind_struct_default.go b/vendor/github.com/spf13/viper/internal/features/bind_struct_default.go
new file mode 100644
index 000000000..edfaf73b6
--- /dev/null
+++ b/vendor/github.com/spf13/viper/internal/features/bind_struct_default.go
@@ -0,0 +1,5 @@
+//go:build !viper_bind_struct
+
+package features
+
+const BindStruct = false
diff --git a/vendor/github.com/spf13/viper/logger.go b/vendor/github.com/spf13/viper/logger.go
index a64e1446c..8938053b3 100644
--- a/vendor/github.com/spf13/viper/logger.go
+++ b/vendor/github.com/spf13/viper/logger.go
@@ -1,77 +1,68 @@
package viper
import (
- "fmt"
+ "context"
- jww "github.com/spf13/jwalterweatherman"
+ slog "github.com/sagikazarmark/slog-shim"
)
// Logger is a unified interface for various logging use cases and practices, including:
// - leveled logging
// - structured logging
+//
+// Deprecated: use `log/slog` instead.
type Logger interface {
// Trace logs a Trace event.
//
// Even more fine-grained information than Debug events.
// Loggers not supporting this level should fall back to Debug.
- Trace(msg string, keyvals ...interface{})
+ Trace(msg string, keyvals ...any)
// Debug logs a Debug event.
//
// A verbose series of information events.
// They are useful when debugging the system.
- Debug(msg string, keyvals ...interface{})
+ Debug(msg string, keyvals ...any)
// Info logs an Info event.
//
// General information about what's happening inside the system.
- Info(msg string, keyvals ...interface{})
+ Info(msg string, keyvals ...any)
// Warn logs a Warn(ing) event.
//
// Non-critical events that should be looked at.
- Warn(msg string, keyvals ...interface{})
+ Warn(msg string, keyvals ...any)
// Error logs an Error event.
//
// Critical events that require immediate attention.
// Loggers commonly provide Fatal and Panic levels above Error level,
- // but exiting and panicing is out of scope for a logging library.
- Error(msg string, keyvals ...interface{})
+ // but exiting and panicking is out of scope for a logging library.
+ Error(msg string, keyvals ...any)
}
-type jwwLogger struct{}
-
-func (jwwLogger) Trace(msg string, keyvals ...interface{}) {
- jww.TRACE.Printf(jwwLogMessage(msg, keyvals...))
+// WithLogger sets a custom logger.
+func WithLogger(l *slog.Logger) Option {
+ return optionFunc(func(v *Viper) {
+ v.logger = l
+ })
}
-func (jwwLogger) Debug(msg string, keyvals ...interface{}) {
- jww.DEBUG.Printf(jwwLogMessage(msg, keyvals...))
-}
+type discardHandler struct{}
-func (jwwLogger) Info(msg string, keyvals ...interface{}) {
- jww.INFO.Printf(jwwLogMessage(msg, keyvals...))
+func (n *discardHandler) Enabled(_ context.Context, _ slog.Level) bool {
+ return false
}
-func (jwwLogger) Warn(msg string, keyvals ...interface{}) {
- jww.WARN.Printf(jwwLogMessage(msg, keyvals...))
+func (n *discardHandler) Handle(_ context.Context, _ slog.Record) error {
+ return nil
}
-func (jwwLogger) Error(msg string, keyvals ...interface{}) {
- jww.ERROR.Printf(jwwLogMessage(msg, keyvals...))
+func (n *discardHandler) WithAttrs(_ []slog.Attr) slog.Handler {
+ return n
}
-func jwwLogMessage(msg string, keyvals ...interface{}) string {
- out := msg
-
- if len(keyvals) > 0 && len(keyvals)%2 == 1 {
- keyvals = append(keyvals, nil)
- }
-
- for i := 0; i <= len(keyvals)-2; i += 2 {
- out = fmt.Sprintf("%s %v=%v", out, keyvals[i], keyvals[i+1])
- }
-
- return out
+func (n *discardHandler) WithGroup(_ string) slog.Handler {
+ return n
}
diff --git a/vendor/github.com/spf13/viper/util.go b/vendor/github.com/spf13/viper/util.go
index 95009a147..117c6ac31 100644
--- a/vendor/github.com/spf13/viper/util.go
+++ b/vendor/github.com/spf13/viper/util.go
@@ -18,6 +18,7 @@ import (
"strings"
"unicode"
+ slog "github.com/sagikazarmark/slog-shim"
"github.com/spf13/cast"
)
@@ -38,11 +39,11 @@ func (pe ConfigParseError) Unwrap() error {
// toCaseInsensitiveValue checks if the value is a map;
// if so, create a copy and lower-case the keys recursively.
-func toCaseInsensitiveValue(value interface{}) interface{} {
+func toCaseInsensitiveValue(value any) any {
switch v := value.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
value = copyAndInsensitiviseMap(cast.ToStringMap(v))
- case map[string]interface{}:
+ case map[string]any:
value = copyAndInsensitiviseMap(v)
}
@@ -51,15 +52,15 @@ func toCaseInsensitiveValue(value interface{}) interface{} {
// copyAndInsensitiviseMap behaves like insensitiviseMap, but creates a copy of
// any map it makes case insensitive.
-func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
- nm := make(map[string]interface{})
+func copyAndInsensitiviseMap(m map[string]any) map[string]any {
+ nm := make(map[string]any)
for key, val := range m {
lkey := strings.ToLower(key)
switch v := val.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
nm[lkey] = copyAndInsensitiviseMap(cast.ToStringMap(v))
- case map[string]interface{}:
+ case map[string]any:
nm[lkey] = copyAndInsensitiviseMap(v)
default:
nm[lkey] = v
@@ -69,23 +70,23 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
return nm
}
-func insensitiviseVal(val interface{}) interface{} {
- switch val.(type) {
- case map[interface{}]interface{}:
+func insensitiviseVal(val any) any {
+ switch v := val.(type) {
+ case map[any]any:
// nested map: cast and recursively insensitivise
val = cast.ToStringMap(val)
- insensitiviseMap(val.(map[string]interface{}))
- case map[string]interface{}:
+ insensitiviseMap(val.(map[string]any))
+ case map[string]any:
// nested map: recursively insensitivise
- insensitiviseMap(val.(map[string]interface{}))
- case []interface{}:
+ insensitiviseMap(v)
+ case []any:
// nested array: recursively insensitivise
- insensitiveArray(val.([]interface{}))
+ insensitiveArray(v)
}
return val
}
-func insensitiviseMap(m map[string]interface{}) {
+func insensitiviseMap(m map[string]any) {
for key, val := range m {
val = insensitiviseVal(val)
lower := strings.ToLower(key)
@@ -98,13 +99,13 @@ func insensitiviseMap(m map[string]interface{}) {
}
}
-func insensitiveArray(a []interface{}) {
+func insensitiveArray(a []any) {
for i, val := range a {
a[i] = insensitiviseVal(val)
}
}
-func absPathify(logger Logger, inPath string) string {
+func absPathify(logger *slog.Logger, inPath string) string {
logger.Info("trying to resolve absolute path", "path", inPath)
if inPath == "$HOME" || strings.HasPrefix(inPath, "$HOME"+string(os.PathSeparator)) {
@@ -155,7 +156,7 @@ func safeMul(a, b uint) uint {
return c
}
-// parseSizeInBytes converts strings like 1GB or 12 mb into an unsigned integer number of bytes
+// parseSizeInBytes converts strings like 1GB or 12 mb into an unsigned integer number of bytes.
func parseSizeInBytes(sizeStr string) uint {
sizeStr = strings.TrimSpace(sizeStr)
lastChar := len(sizeStr) - 1
@@ -197,22 +198,22 @@ func parseSizeInBytes(sizeStr string) uint {
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
-func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
+func deepSearch(m map[string]any, path []string) map[string]any {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
- m3 := make(map[string]interface{})
+ m3 := make(map[string]any)
m[k] = m3
m = m3
continue
}
- m3, ok := m2.(map[string]interface{})
+ m3, ok := m2.(map[string]any)
if !ok {
// intermediate key is a value
// => replace with a new map
- m3 = make(map[string]interface{})
+ m3 = make(map[string]any)
m[k] = m3
}
// continue search from here
diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go
index 7fb1e1913..20eb4da17 100644
--- a/vendor/github.com/spf13/viper/viper.go
+++ b/vendor/github.com/spf13/viper/viper.go
@@ -35,6 +35,7 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/mitchellh/mapstructure"
+ slog "github.com/sagikazarmark/slog-shim"
"github.com/spf13/afero"
"github.com/spf13/cast"
"github.com/spf13/pflag"
@@ -47,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.
@@ -76,7 +78,7 @@ type remoteConfigFactory interface {
WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
}
-// RemoteConfig is optional, see the remote package
+// RemoteConfig is optional, see the remote package.
var RemoteConfig remoteConfigFactory
// UnsupportedConfigError denotes encountering an unsupported
@@ -101,7 +103,7 @@ func (str UnsupportedRemoteProviderError) Error() string {
// pull the configuration from the remote provider.
type RemoteConfigError string
-// Error returns the formatted remote provider error
+// Error returns the formatted remote provider error.
func (rce RemoteConfigError) Error() string {
return fmt.Sprintf("Remote Configurations Error: %s", string(rce))
}
@@ -125,7 +127,7 @@ func (faee ConfigFileAlreadyExistsError) Error() string {
}
// A DecoderConfigOption can be passed to viper.Unmarshal to configure
-// mapstructure.DecoderConfig options
+// mapstructure.DecoderConfig options.
type DecoderConfigOption func(*mapstructure.DecoderConfig)
// DecodeHook returns a DecoderConfigOption which overrides the default
@@ -206,10 +208,10 @@ type Viper struct {
allowEmptyEnv bool
parents []string
- config map[string]interface{}
- override map[string]interface{}
- defaults map[string]interface{}
- kvstore map[string]interface{}
+ config map[string]any
+ override map[string]any
+ defaults map[string]any
+ kvstore map[string]any
pflags map[string]FlagValue
env map[string][]string
aliases map[string]string
@@ -217,7 +219,7 @@ type Viper struct {
onConfigChange func(fsnotify.Event)
- logger Logger
+ logger *slog.Logger
// TODO: should probably be protected with a mutex
encoderRegistry *encoding.EncoderRegistry
@@ -231,16 +233,16 @@ func New() *Viper {
v.configName = "config"
v.configPermissions = os.FileMode(0o644)
v.fs = afero.NewOsFs()
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
v.parents = []string{}
- v.override = make(map[string]interface{})
- v.defaults = make(map[string]interface{})
- v.kvstore = make(map[string]interface{})
+ v.override = make(map[string]any)
+ v.defaults = make(map[string]any)
+ v.kvstore = make(map[string]any)
v.pflags = make(map[string]FlagValue)
v.env = make(map[string][]string)
v.aliases = make(map[string]string)
v.typeByDefValue = false
- v.logger = jwwLogger{}
+ v.logger = slog.New(&discardHandler{})
v.resetEncoding()
@@ -301,10 +303,10 @@ func NewWithOptions(opts ...Option) *Viper {
func Reset() {
v = New()
SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
- SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
+ SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore", "nats"}
}
-// TODO: make this lazy initialization instead
+// TODO: make this lazy initialization instead.
func (v *Viper) resetEncoding() {
encoderRegistry := encoding.NewEncoderRegistry()
decoderRegistry := encoding.NewDecoderRegistry()
@@ -420,7 +422,7 @@ type RemoteProvider interface {
var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
// SupportedRemoteProviders are universally supported remote providers.
-var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
+var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore", "nats"}
// OnConfigChange sets the event handler that is called when a config file changes.
func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
@@ -438,7 +440,7 @@ func (v *Viper) WatchConfig() {
initWG := sync.WaitGroup{}
initWG.Add(1)
go func() {
- watcher, err := newWatcher()
+ watcher, err := fsnotify.NewWatcher()
if err != nil {
v.logger.Error(fmt.Sprintf("failed to create watcher: %s", err))
os.Exit(1)
@@ -523,6 +525,12 @@ func (v *Viper) SetEnvPrefix(in string) {
}
}
+func GetEnvPrefix() string { return v.GetEnvPrefix() }
+
+func (v *Viper) GetEnvPrefix() string {
+ return v.envPrefix
+}
+
func (v *Viper) mergeWithEnvPrefix(in string) string {
if v.envPrefix != "" {
return strings.ToUpper(v.envPrefix + "_" + in)
@@ -578,12 +586,12 @@ func (v *Viper) AddConfigPath(in string) {
// AddRemoteProvider adds a remote configuration source.
// Remote Providers are searched in the order they are added.
-// provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
-// endpoint is the url. etcd requires http://ip:port consul requires ip:port
+// provider is a string value: "etcd", "etcd3", "consul", "firestore" or "nats" are currently supported.
+// endpoint is the url. etcd requires http://ip:port, consul requires ip:port, nats requires nats://ip:port
// path is the path in the k/v store to retrieve configuration
// To retrieve a config file called myapp.json from /configs/myapp.json
// you should set path to /configs and set config name (SetConfigName()) to
-// "myapp"
+// "myapp".
func AddRemoteProvider(provider, endpoint, path string) error {
return v.AddRemoteProvider(provider, endpoint, path)
}
@@ -609,14 +617,14 @@ func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error {
// AddSecureRemoteProvider adds a remote configuration source.
// Secure Remote Providers are searched in the order they are added.
-// provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
+// provider is a string value: "etcd", "etcd3", "consul", "firestore" or "nats" are currently supported.
// endpoint is the url. etcd requires http://ip:port consul requires ip:port
// secretkeyring is the filepath to your openpgp secret keyring. e.g. /etc/secrets/myring.gpg
// path is the path in the k/v store to retrieve configuration
// To retrieve a config file called myapp.json from /configs/myapp.json
// you should set path to /configs and set config name (SetConfigName()) to
-// "myapp"
-// Secure Remote Providers are implemented with github.com/bketelsen/crypt
+// "myapp".
+// Secure Remote Providers are implemented with github.com/bketelsen/crypt.
func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring)
}
@@ -653,7 +661,7 @@ func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool {
// searchMap recursively searches for a value for path in source map.
// Returns nil if not found.
// Note: This assumes that the path entries and map keys are lower cased.
-func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} {
+func (v *Viper) searchMap(source map[string]any, path []string) any {
if len(path) == 0 {
return source
}
@@ -666,13 +674,13 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac
}
// Nested case
- switch next.(type) {
- case map[interface{}]interface{}:
+ switch next := next.(type) {
+ case map[any]any:
return v.searchMap(cast.ToStringMap(next), path[1:])
- case map[string]interface{}:
+ case map[string]any:
// Type assertion is safe here since it is only reached
// if the type of `next` is the same as the type being asserted
- return v.searchMap(next.(map[string]interface{}), path[1:])
+ return v.searchMap(next, path[1:])
default:
// got a value but nested key expected, return "nil" for not found
return nil
@@ -692,7 +700,7 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac
// in their keys).
//
// Note: This assumes that the path entries and map keys are lower cased.
-func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []string) interface{} {
+func (v *Viper) searchIndexableWithPathPrefixes(source any, path []string) any {
if len(path) == 0 {
return source
}
@@ -701,11 +709,11 @@ func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []strin
for i := len(path); i > 0; i-- {
prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim))
- var val interface{}
+ var val any
switch sourceIndexable := source.(type) {
- case []interface{}:
+ case []any:
val = v.searchSliceWithPathPrefixes(sourceIndexable, prefixKey, i, path)
- case map[string]interface{}:
+ case map[string]any:
val = v.searchMapWithPathPrefixes(sourceIndexable, prefixKey, i, path)
}
if val != nil {
@@ -722,11 +730,11 @@ func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []strin
// This function is part of the searchIndexableWithPathPrefixes recurring search and
// should not be called directly from functions other than searchIndexableWithPathPrefixes.
func (v *Viper) searchSliceWithPathPrefixes(
- sourceSlice []interface{},
+ sourceSlice []any,
prefixKey string,
pathIndex int,
path []string,
-) interface{} {
+) any {
// if the prefixKey is not a number or it is out of bounds of the slice
index, err := strconv.Atoi(prefixKey)
if err != nil || len(sourceSlice) <= index {
@@ -741,9 +749,9 @@ func (v *Viper) searchSliceWithPathPrefixes(
}
switch n := next.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])
- case map[string]interface{}, []interface{}:
+ case map[string]any, []any:
return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
default:
// got a value but nested key expected, do nothing and look for next prefix
@@ -758,11 +766,11 @@ func (v *Viper) searchSliceWithPathPrefixes(
// This function is part of the searchIndexableWithPathPrefixes recurring search and
// should not be called directly from functions other than searchIndexableWithPathPrefixes.
func (v *Viper) searchMapWithPathPrefixes(
- sourceMap map[string]interface{},
+ sourceMap map[string]any,
prefixKey string,
pathIndex int,
path []string,
-) interface{} {
+) any {
next, ok := sourceMap[prefixKey]
if !ok {
return nil
@@ -775,9 +783,9 @@ func (v *Viper) searchMapWithPathPrefixes(
// Nested case
switch n := next.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])
- case map[string]interface{}, []interface{}:
+ case map[string]any, []any:
return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
default:
// got a value but nested key expected, do nothing and look for next prefix
@@ -792,8 +800,8 @@ func (v *Viper) searchMapWithPathPrefixes(
// e.g., if "foo.bar" has a value in the given map, it “shadows”
//
// "foo.bar.baz" in a lower-priority map
-func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
- var parentVal interface{}
+func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]any) string {
+ var parentVal any
for i := 1; i < len(path); i++ {
parentVal = v.searchMap(m, path[0:i])
if parentVal == nil {
@@ -801,9 +809,9 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{})
return ""
}
switch parentVal.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
continue
- case map[string]interface{}:
+ case map[string]any:
continue
default:
// parentVal is a regular value which shadows "path"
@@ -818,12 +826,14 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{})
// e.g., if "foo.bar" has a value in the given map, it “shadows”
//
// "foo.bar.baz" in a lower-priority map
-func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
+func (v *Viper) isPathShadowedInFlatMap(path []string, mi any) string {
// unify input map
var m map[string]interface{}
- switch mi.(type) {
- case map[string]string, map[string]FlagValue:
- m = cast.ToStringMap(mi)
+ switch miv := mi.(type) {
+ case map[string]string:
+ m = castMapStringToMapInterface(miv)
+ case map[string]FlagValue:
+ m = castMapFlagToMapInterface(miv)
default:
return ""
}
@@ -887,9 +897,9 @@ func GetViper() *Viper {
// override, flag, env, config file, key/value store, default
//
// Get returns an interface. For a specific value use one of the Get____ methods.
-func Get(key string) interface{} { return v.Get(key) }
+func Get(key string) any { return v.Get(key) }
-func (v *Viper) Get(key string) interface{} {
+func (v *Viper) Get(key string) any {
lcaseKey := strings.ToLower(key)
val := v.find(lcaseKey, true)
if val == nil {
@@ -950,7 +960,8 @@ func (v *Viper) Sub(key string) *Viper {
}
if reflect.TypeOf(data).Kind() == reflect.Map {
- subv.parents = append(v.parents, strings.ToLower(key))
+ subv.parents = append([]string(nil), v.parents...)
+ subv.parents = append(subv.parents, strings.ToLower(key))
subv.automaticEnvApplied = v.automaticEnvApplied
subv.envPrefix = v.envPrefix
subv.envKeyReplacer = v.envKeyReplacer
@@ -1059,9 +1070,9 @@ func (v *Viper) GetStringSlice(key string) []string {
}
// GetStringMap returns the value associated with the key as a map of interfaces.
-func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) }
+func GetStringMap(key string) map[string]any { return v.GetStringMap(key) }
-func (v *Viper) GetStringMap(key string) map[string]interface{} {
+func (v *Viper) GetStringMap(key string) map[string]any {
return cast.ToStringMap(v.Get(key))
}
@@ -1089,27 +1100,58 @@ func (v *Viper) GetSizeInBytes(key string) uint {
}
// UnmarshalKey takes a single key and unmarshals it into a Struct.
-func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
+func UnmarshalKey(key string, rawVal any, opts ...DecoderConfigOption) error {
return v.UnmarshalKey(key, rawVal, opts...)
}
-func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
+func (v *Viper) UnmarshalKey(key string, rawVal any, opts ...DecoderConfigOption) error {
return decode(v.Get(key), defaultDecoderConfig(rawVal, opts...))
}
// Unmarshal unmarshals the config into a Struct. Make sure that the tags
// on the fields of the structure are properly set.
-func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
+func Unmarshal(rawVal any, opts ...DecoderConfigOption) error {
return v.Unmarshal(rawVal, opts...)
}
-func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
- return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
+func (v *Viper) Unmarshal(rawVal any, opts ...DecoderConfigOption) error {
+ 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), defaultDecoderConfig(rawVal, opts...))
+}
+
+func (v *Viper) decodeStructKeys(input any, opts ...DecoderConfigOption) ([]string, error) {
+ var structKeyMap map[string]any
+
+ err := decode(input, defaultDecoderConfig(&structKeyMap, opts...))
+ if err != nil {
+ return nil, err
+ }
+
+ flattenedStructKeyMap := v.flattenAndMergeMap(map[string]bool{}, structKeyMap, "")
+
+ r := make([]string, 0, len(flattenedStructKeyMap))
+ for v := range flattenedStructKeyMap {
+ r = append(r, v)
+ }
+
+ return r, nil
}
// defaultDecoderConfig returns default mapstructure.DecoderConfig with support
-// of time.Duration values & string slices
-func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
+// of time.Duration values & string slices.
+func defaultDecoderConfig(output any, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
c := &mapstructure.DecoderConfig{
Metadata: nil,
Result: output,
@@ -1125,8 +1167,8 @@ func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *maps
return c
}
-// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality
-func decode(input interface{}, config *mapstructure.DecoderConfig) error {
+// decode is a wrapper around mapstructure.Decode that mimics the WeakDecode functionality.
+func decode(input any, config *mapstructure.DecoderConfig) error {
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
return err
@@ -1136,15 +1178,28 @@ func decode(input interface{}, config *mapstructure.DecoderConfig) error {
// UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
// in the destination struct.
-func UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
+func UnmarshalExact(rawVal any, opts ...DecoderConfigOption) error {
return v.UnmarshalExact(rawVal, opts...)
}
-func (v *Viper) UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
+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
@@ -1237,9 +1292,9 @@ func (v *Viper) MustBindEnv(input ...string) {
// corresponds to a flag, the flag's default value is returned.
//
// Note: this assumes a lower-cased key given.
-func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
+func (v *Viper) find(lcaseKey string, flagDefault bool) any {
var (
- val interface{}
+ val any
exists bool
path = strings.Split(lcaseKey, v.keyDelim)
nested = len(path) > 1
@@ -1398,46 +1453,46 @@ func readAsCSV(val string) ([]string, error) {
}
// mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/master/string_to_string.go#L79
-// alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap
-func stringToStringConv(val string) interface{} {
+// alterations are: errors are swallowed, map[string]any is returned in order to enable cast.ToStringMap.
+func stringToStringConv(val string) any {
val = strings.Trim(val, "[]")
// An empty string would cause an empty map
- if len(val) == 0 {
- return map[string]interface{}{}
+ if val == "" {
+ return map[string]any{}
}
r := csv.NewReader(strings.NewReader(val))
ss, err := r.Read()
if err != nil {
return nil
}
- out := make(map[string]interface{}, len(ss))
+ out := make(map[string]any, len(ss))
for _, pair := range ss {
- kv := strings.SplitN(pair, "=", 2)
- if len(kv) != 2 {
+ k, vv, found := strings.Cut(pair, "=")
+ if !found {
return nil
}
- out[kv[0]] = kv[1]
+ out[k] = vv
}
return out
}
// mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/d5e0c0615acee7028e1e2740a11102313be88de1/string_to_int.go#L68
-// alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap
-func stringToIntConv(val string) interface{} {
+// alterations are: errors are swallowed, map[string]any is returned in order to enable cast.ToStringMap.
+func stringToIntConv(val string) any {
val = strings.Trim(val, "[]")
// An empty string would cause an empty map
- if len(val) == 0 {
- return map[string]interface{}{}
+ if val == "" {
+ return map[string]any{}
}
ss := strings.Split(val, ",")
- out := make(map[string]interface{}, len(ss))
+ out := make(map[string]any, len(ss))
for _, pair := range ss {
- kv := strings.SplitN(pair, "=", 2)
- if len(kv) != 2 {
+ k, vv, found := strings.Cut(pair, "=")
+ if !found {
return nil
}
var err error
- out[kv[0]], err = strconv.Atoi(kv[1])
+ out[k], err = strconv.Atoi(vv)
if err != nil {
return nil
}
@@ -1474,13 +1529,13 @@ func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
// RegisterAlias creates an alias that provides another accessor for the same key.
// This enables one to change a name without breaking the application.
-func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
+func RegisterAlias(alias, key string) { v.RegisterAlias(alias, key) }
-func (v *Viper) RegisterAlias(alias string, key string) {
+func (v *Viper) RegisterAlias(alias, key string) {
v.registerAlias(alias, strings.ToLower(key))
}
-func (v *Viper) registerAlias(alias string, key string) {
+func (v *Viper) registerAlias(alias, key string) {
alias = strings.ToLower(alias)
if alias != key && alias != v.realKey(key) {
_, exists := v.aliases[alias]
@@ -1538,9 +1593,9 @@ func (v *Viper) InConfig(key string) bool {
// SetDefault sets the default value for this key.
// SetDefault is case-insensitive for a key.
// Default only used when no value is provided by the user via flag, config or ENV.
-func SetDefault(key string, value interface{}) { v.SetDefault(key, value) }
+func SetDefault(key string, value any) { v.SetDefault(key, value) }
-func (v *Viper) SetDefault(key string, value interface{}) {
+func (v *Viper) SetDefault(key string, value any) {
// If alias passed in, then set the proper default
key = v.realKey(strings.ToLower(key))
value = toCaseInsensitiveValue(value)
@@ -1557,9 +1612,9 @@ func (v *Viper) SetDefault(key string, value interface{}) {
// Set is case-insensitive for a key.
// Will be used instead of values obtained via
// flags, config file, ENV, default, or key/value store.
-func Set(key string, value interface{}) { v.Set(key, value) }
+func Set(key string, value any) { v.Set(key, value) }
-func (v *Viper) Set(key string, value interface{}) {
+func (v *Viper) Set(key string, value any) {
// If alias passed in, then set the proper override
key = v.realKey(strings.ToLower(key))
value = toCaseInsensitiveValue(value)
@@ -1593,7 +1648,7 @@ func (v *Viper) ReadInConfig() error {
return err
}
- config := make(map[string]interface{})
+ config := make(map[string]any)
err = v.unmarshalReader(bytes.NewReader(file), config)
if err != nil {
@@ -1631,7 +1686,7 @@ func (v *Viper) MergeInConfig() error {
func ReadConfig(in io.Reader) error { return v.ReadConfig(in) }
func (v *Viper) ReadConfig(in io.Reader) error {
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
return v.unmarshalReader(in, v.config)
}
@@ -1639,7 +1694,7 @@ func (v *Viper) ReadConfig(in io.Reader) error {
func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
func (v *Viper) MergeConfig(in io.Reader) error {
- cfg := make(map[string]interface{})
+ cfg := make(map[string]any)
if err := v.unmarshalReader(in, cfg); err != nil {
return err
}
@@ -1648,11 +1703,11 @@ func (v *Viper) MergeConfig(in io.Reader) error {
// MergeConfigMap merges the configuration from the map given with an existing config.
// Note that the map given may be modified.
-func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) }
+func MergeConfigMap(cfg map[string]any) error { return v.MergeConfigMap(cfg) }
-func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error {
+func (v *Viper) MergeConfigMap(cfg map[string]any) error {
if v.config == nil {
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
}
insensitiviseMap(cfg)
mergeMaps(cfg, v.config, nil)
@@ -1717,7 +1772,7 @@ func (v *Viper) writeConfig(filename string, force bool) error {
return UnsupportedConfigError(configType)
}
if v.config == nil {
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
}
flags := os.O_CREATE | os.O_TRUNC | os.O_WRONLY
if !force {
@@ -1738,11 +1793,11 @@ func (v *Viper) writeConfig(filename string, force bool) error {
// Unmarshal a Reader into a map.
// Should probably be an unexported function.
-func unmarshalReader(in io.Reader, c map[string]interface{}) error {
+func unmarshalReader(in io.Reader, c map[string]any) error {
return v.unmarshalReader(in, c)
}
-func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
+func (v *Viper) unmarshalReader(in io.Reader, c map[string]any) error {
buf := new(bytes.Buffer)
buf.ReadFrom(in)
@@ -1776,7 +1831,7 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error {
return nil
}
-func keyExists(k string, m map[string]interface{}) string {
+func keyExists(k string, m map[string]any) string {
lk := strings.ToLower(k)
for mk := range m {
lmk := strings.ToLower(mk)
@@ -1788,33 +1843,33 @@ func keyExists(k string, m map[string]interface{}) string {
}
func castToMapStringInterface(
- src map[interface{}]interface{},
-) map[string]interface{} {
- tgt := map[string]interface{}{}
+ src map[any]any,
+) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[fmt.Sprintf("%v", k)] = v
}
return tgt
}
-func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} {
- tgt := map[string]interface{}{}
+func castMapStringSliceToMapInterface(src map[string][]string) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[k] = v
}
return tgt
}
-func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
- tgt := map[string]interface{}{}
+func castMapStringToMapInterface(src map[string]string) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[k] = v
}
return tgt
}
-func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} {
- tgt := map[string]interface{}{}
+func castMapFlagToMapInterface(src map[string]FlagValue) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[k] = v
}
@@ -1822,17 +1877,15 @@ func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{}
}
// mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's
-// insistence on parsing nested structures as `map[interface{}]interface{}`
+// insistence on parsing nested structures as `map[any]any`
// instead of using a `string` as the key for nest structures beyond one level
// deep. Both map types are supported as there is a go-yaml fork that uses
-// `map[string]interface{}` instead.
-func mergeMaps(
- src, tgt map[string]interface{}, itgt map[interface{}]interface{},
-) {
+// `map[string]any` instead.
+func mergeMaps(src, tgt map[string]any, itgt map[any]any) {
for sk, sv := range src {
tk := keyExists(sk, tgt)
if tk == "" {
- v.logger.Trace("", "tk", "\"\"", fmt.Sprintf("tgt[%s]", sk), sv)
+ v.logger.Debug("", "tk", "\"\"", fmt.Sprintf("tgt[%s]", sk), sv)
tgt[sk] = sv
if itgt != nil {
itgt[sk] = sv
@@ -1842,7 +1895,7 @@ func mergeMaps(
tv, ok := tgt[tk]
if !ok {
- v.logger.Trace("", fmt.Sprintf("ok[%s]", tk), false, fmt.Sprintf("tgt[%s]", sk), sv)
+ v.logger.Debug("", fmt.Sprintf("ok[%s]", tk), false, fmt.Sprintf("tgt[%s]", sk), sv)
tgt[sk] = sv
if itgt != nil {
itgt[sk] = sv
@@ -1853,7 +1906,7 @@ func mergeMaps(
svType := reflect.TypeOf(sv)
tvType := reflect.TypeOf(tv)
- v.logger.Trace(
+ v.logger.Debug(
"processing",
"key", sk,
"st", svType,
@@ -1863,12 +1916,12 @@ func mergeMaps(
)
switch ttv := tv.(type) {
- case map[interface{}]interface{}:
- v.logger.Trace("merging maps (must convert)")
- tsv, ok := sv.(map[interface{}]interface{})
+ case map[any]any:
+ v.logger.Debug("merging maps (must convert)")
+ tsv, ok := sv.(map[any]any)
if !ok {
v.logger.Error(
- "Could not cast sv to map[interface{}]interface{}",
+ "Could not cast sv to map[any]any",
"key", sk,
"st", svType,
"tt", tvType,
@@ -1881,12 +1934,12 @@ func mergeMaps(
ssv := castToMapStringInterface(tsv)
stv := castToMapStringInterface(ttv)
mergeMaps(ssv, stv, ttv)
- case map[string]interface{}:
- v.logger.Trace("merging maps")
- tsv, ok := sv.(map[string]interface{})
+ case map[string]any:
+ v.logger.Debug("merging maps")
+ tsv, ok := sv.(map[string]any)
if !ok {
v.logger.Error(
- "Could not cast sv to map[string]interface{}",
+ "Could not cast sv to map[string]any",
"key", sk,
"st", svType,
"tt", tvType,
@@ -1897,7 +1950,7 @@ func mergeMaps(
}
mergeMaps(tsv, ttv, nil)
default:
- v.logger.Trace("setting value")
+ v.logger.Debug("setting value")
tgt[tk] = sv
if itgt != nil {
itgt[tk] = sv
@@ -1948,7 +2001,7 @@ func (v *Viper) getKeyValueConfig() error {
return RemoteConfigError("No Files Found")
}
-func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
+func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]any, error) {
reader, err := RemoteConfig.Get(provider)
if err != nil {
return nil, err
@@ -1997,7 +2050,7 @@ func (v *Viper) watchKeyValueConfig() error {
return RemoteConfigError("No Files Found")
}
-func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
+func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]any, error) {
reader, err := RemoteConfig.Watch(provider)
if err != nil {
return nil, err
@@ -2007,7 +2060,7 @@ func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface
}
// AllKeys returns all keys holding a value, regardless of where they are set.
-// Nested keys are returned with a v.keyDelim separator
+// Nested keys are returned with a v.keyDelim separator.
func AllKeys() []string { return v.AllKeys() }
func (v *Viper) AllKeys() []string {
@@ -2036,7 +2089,7 @@ func (v *Viper) AllKeys() []string {
// it is skipped.
//
// The resulting set of paths is merged to the given shadow set at the same time.
-func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
+func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]any, prefix string) map[string]bool {
if shadow != nil && prefix != "" && shadow[prefix] {
// prefix is shadowed => nothing more to flatten
return shadow
@@ -2045,16 +2098,16 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac
shadow = make(map[string]bool)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += v.keyDelim
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
@@ -2069,7 +2122,7 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac
// mergeFlatMap merges the given maps, excluding values of the second map
// shadowed by values from the first map.
-func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
+func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]any) map[string]bool {
// scan keys
outer:
for k := range m {
@@ -2089,13 +2142,17 @@ outer:
return shadow
}
-// AllSettings merges all settings and returns them as a map[string]interface{}.
-func AllSettings() map[string]interface{} { return v.AllSettings() }
+// AllSettings merges all settings and returns them as a map[string]any.
+func AllSettings() map[string]any { return v.AllSettings() }
+
+func (v *Viper) AllSettings() map[string]any {
+ return v.getSettings(v.AllKeys())
+}
-func (v *Viper) AllSettings() map[string]interface{} {
- m := map[string]interface{}{}
+func (v *Viper) getSettings(keys []string) map[string]any {
+ m := map[string]any{}
// start from the list of keys, and construct the map one value at a time
- for _, k := range v.AllKeys() {
+ for _, k := range keys {
value := v.Get(k)
if value == nil {
// should not happen, since AllKeys() returns only keys holding a value,
diff --git a/vendor/github.com/spf13/viper/viper_go1_16.go b/vendor/github.com/spf13/viper/viper_go1_16.go
deleted file mode 100644
index e10172fa3..000000000
--- a/vendor/github.com/spf13/viper/viper_go1_16.go
+++ /dev/null
@@ -1,32 +0,0 @@
-//go:build go1.16 && finder
-// +build go1.16,finder
-
-package viper
-
-import (
- "fmt"
-
- "github.com/spf13/afero"
-)
-
-// Search all configPaths for any config file.
-// Returns the first path that exists (and is a config file).
-func (v *Viper) findConfigFile() (string, error) {
- finder := finder{
- paths: v.configPaths,
- fileNames: []string{v.configName},
- extensions: SupportedExts,
- withoutExtension: v.configType != "",
- }
-
- file, err := finder.Find(afero.NewIOFS(v.fs))
- if err != nil {
- return "", err
- }
-
- if file == "" {
- return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
- }
-
- return file, nil
-}
diff --git a/vendor/github.com/spf13/viper/watch.go b/vendor/github.com/spf13/viper/watch.go
deleted file mode 100644
index 1ce84eaf8..000000000
--- a/vendor/github.com/spf13/viper/watch.go
+++ /dev/null
@@ -1,12 +0,0 @@
-//go:build darwin || dragonfly || freebsd || openbsd || linux || netbsd || solaris || windows
-// +build darwin dragonfly freebsd openbsd linux netbsd solaris windows
-
-package viper
-
-import "github.com/fsnotify/fsnotify"
-
-type watcher = fsnotify.Watcher
-
-func newWatcher() (*watcher, error) {
- return fsnotify.NewWatcher()
-}
diff --git a/vendor/github.com/spf13/viper/watch_unsupported.go b/vendor/github.com/spf13/viper/watch_unsupported.go
deleted file mode 100644
index 7e2715377..000000000
--- a/vendor/github.com/spf13/viper/watch_unsupported.go
+++ /dev/null
@@ -1,32 +0,0 @@
-//go:build appengine || (!darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows)
-// +build appengine !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows
-
-package viper
-
-import (
- "fmt"
- "runtime"
-
- "github.com/fsnotify/fsnotify"
-)
-
-func newWatcher() (*watcher, error) {
- return &watcher{}, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS)
-}
-
-type watcher struct {
- Events chan fsnotify.Event
- Errors chan error
-}
-
-func (*watcher) Close() error {
- return nil
-}
-
-func (*watcher) Add(name string) error {
- return nil
-}
-
-func (*watcher) Remove(name string) error {
- return nil
-}
diff --git a/vendor/github.com/subosito/gotenv/CHANGELOG.md b/vendor/github.com/subosito/gotenv/CHANGELOG.md
index 757caad26..c4fe7d326 100644
--- a/vendor/github.com/subosito/gotenv/CHANGELOG.md
+++ b/vendor/github.com/subosito/gotenv/CHANGELOG.md
@@ -1,5 +1,42 @@
# Changelog
+## [1.5.0] - 2023-08-15
+
+### Fixed
+
+- Use io.Reader instead of custom Reader
+
+## [1.5.0] - 2023-08-15
+
+### Added
+
+- Support for reading UTF16 files
+
+### Fixed
+
+- Scanner error handling
+- Reader error handling
+
+## [1.4.2] - 2023-01-11
+
+### Fixed
+
+- Env var initialization
+
+### Changed
+
+- More consitent line splitting
+
+## [1.4.1] - 2022-08-23
+
+### Fixed
+
+- Missing file close
+
+### Changed
+
+- Updated dependencies
+
## [1.4.0] - 2022-06-02
### Added
diff --git a/vendor/github.com/subosito/gotenv/gotenv.go b/vendor/github.com/subosito/gotenv/gotenv.go
index dc013e1e0..1191d3587 100644
--- a/vendor/github.com/subosito/gotenv/gotenv.go
+++ b/vendor/github.com/subosito/gotenv/gotenv.go
@@ -12,6 +12,9 @@ import (
"sort"
"strconv"
"strings"
+
+ "golang.org/x/text/encoding/unicode"
+ "golang.org/x/text/transform"
)
const (
@@ -20,9 +23,13 @@ const (
// Pattern for detecting valid variable within a value
variablePattern = `(\\)?(\$)(\{?([A-Z0-9_]+)?\}?)`
+)
- // Byte order mark character
- bom = "\xef\xbb\xbf"
+// Byte order mark character
+var (
+ bomUTF8 = []byte("\xEF\xBB\xBF")
+ bomUTF16LE = []byte("\xFF\xFE")
+ bomUTF16BE = []byte("\xFE\xFF")
)
// Env holds key/value pair of valid environment variable
@@ -203,19 +210,40 @@ func splitLines(data []byte, atEOF bool) (advance int, token []byte, err error)
func strictParse(r io.Reader, override bool) (Env, error) {
env := make(Env)
- scanner := bufio.NewScanner(r)
- scanner.Split(splitLines)
- firstLine := true
+ buf := new(bytes.Buffer)
+ tee := io.TeeReader(r, buf)
- for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
+ // There can be a maximum of 3 BOM bytes.
+ bomByteBuffer := make([]byte, 3)
+ _, err := tee.Read(bomByteBuffer)
+ if err != nil && err != io.EOF {
+ return env, err
+ }
+
+ z := io.MultiReader(buf, r)
+
+ // We chooes a different scanner depending on file encoding.
+ var scanner *bufio.Scanner
- if firstLine {
- line = strings.TrimPrefix(line, bom)
- firstLine = false
+ if bytes.HasPrefix(bomByteBuffer, bomUTF8) {
+ scanner = bufio.NewScanner(transform.NewReader(z, unicode.UTF8BOM.NewDecoder()))
+ } else if bytes.HasPrefix(bomByteBuffer, bomUTF16LE) {
+ scanner = bufio.NewScanner(transform.NewReader(z, unicode.UTF16(unicode.LittleEndian, unicode.ExpectBOM).NewDecoder()))
+ } else if bytes.HasPrefix(bomByteBuffer, bomUTF16BE) {
+ scanner = bufio.NewScanner(transform.NewReader(z, unicode.UTF16(unicode.BigEndian, unicode.ExpectBOM).NewDecoder()))
+ } else {
+ scanner = bufio.NewScanner(z)
+ }
+
+ scanner.Split(splitLines)
+
+ for scanner.Scan() {
+ if err := scanner.Err(); err != nil {
+ return env, err
}
+ line := strings.TrimSpace(scanner.Text())
if line == "" || line[0] == '#' {
continue
}
@@ -263,7 +291,7 @@ func strictParse(r io.Reader, override bool) (Env, error) {
}
}
- return env, nil
+ return env, scanner.Err()
}
var (