summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2022-05-29 15:03:51 -0400
committerDave Henderson <dhenderson@gmail.com>2022-05-30 14:06:32 -0400
commitc0b93d7ebdfd27badbb41eb62ca0bd77b0252308 (patch)
tree2f3b3e17023f4819cf69dee8953ea44463588bae
parent9ae9a6a5182342f775383646058807222947f483 (diff)
Support URLs for nested templates
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
-rw-r--r--config.go3
-rw-r--r--data/datasource.go2
-rw-r--r--docs/content/config.md14
-rw-r--r--docs/content/usage.md24
-rw-r--r--go.mod93
-rw-r--r--go.sum186
-rw-r--r--gomplate.go63
-rw-r--r--gomplate_test.go64
-rw-r--r--internal/cmd/config.go10
-rw-r--r--internal/cmd/main.go8
-rw-r--r--internal/config/configfile.go115
-rw-r--r--internal/config/configfile_test.go136
-rw-r--r--internal/config/types.go93
-rw-r--r--internal/config/types_test.go88
-rw-r--r--internal/tests/integration/nested_templates_test.go8
-rw-r--r--template.go136
-rw-r--r--template_test.go102
-rw-r--r--template_unix_test.go16
-rw-r--r--template_windows_test.go16
19 files changed, 799 insertions, 378 deletions
diff --git a/config.go b/config.go
index f9000551..e47e2df1 100644
--- a/config.go
+++ b/config.go
@@ -128,7 +128,6 @@ func (o *Config) toNewConfig() (*config.Config, error) {
OutMode: o.OutMode,
LDelim: o.LDelim,
RDelim: o.RDelim,
- Templates: o.Templates,
Stdin: os.Stdin,
Stdout: &iohelpers.NopCloser{Writer: o.Out},
Stderr: os.Stderr,
@@ -137,7 +136,7 @@ func (o *Config) toNewConfig() (*config.Config, error) {
if err != nil {
return nil, err
}
- err = cfg.ParseDataSourceFlags(o.DataSources, o.Contexts, o.DataSourceHeaders)
+ err = cfg.ParseDataSourceFlags(o.DataSources, o.Contexts, o.Templates, o.DataSourceHeaders)
if err != nil {
return nil, err
}
diff --git a/data/datasource.go b/data/datasource.go
index c010f89d..adeb4a4b 100644
--- a/data/datasource.go
+++ b/data/datasource.go
@@ -103,7 +103,7 @@ func (d *Data) Cleanup() {
// Deprecated: will be replaced in future
func NewData(datasourceArgs, headerArgs []string) (*Data, error) {
cfg := &config.Config{}
- err := cfg.ParseDataSourceFlags(datasourceArgs, nil, headerArgs)
+ err := cfg.ParseDataSourceFlags(datasourceArgs, nil, nil, headerArgs)
if err != nil {
return nil, err
}
diff --git a/docs/content/config.md b/docs/content/config.md
index 01a21324..9e488e8a 100644
--- a/docs/content/config.md
+++ b/docs/content/config.md
@@ -406,7 +406,19 @@ suppressEmpty: true
See [`--template`/`-t`](../usage/#template-t).
-An array of template references. Can be just a path or an alias and a path:
+```yaml
+templates:
+ t:
+ url: file:///foo/bar/helloworld.tmpl
+ remote:
+ url: https://example.com/api/v1/someremotetemplate
+ header:
+ Authorization: ["Basic aGF4MHI6c3dvcmRmaXNoCg=="]
+ dir: foo/bar/
+```
+
+_(Deprecated)_ Can also be an array of template references. Can be just a path,
+or an alias and a path:
```yaml
templates:
diff --git a/docs/content/usage.md b/docs/content/usage.md
index e51181bd..1a918791 100644
--- a/docs/content/usage.md
+++ b/docs/content/usage.md
@@ -189,10 +189,30 @@ Use `--left-delim`/`--right-delim` or set `$GOMPLATE_LEFT_DELIM`/`$GOMPLATE_RIGH
### `--template`/`-t`
-Add a nested template that can be referenced by the main input template(s) with the [`template`](https://golang.org/pkg/text/template/#hdr-Actions) built-in or the functions in the [`tmpl`](../functions/tmpl/) namespace. Specify multiple times to add multiple template references.
+Add a nested template or directory of templates that can be referenced by the
+main input template(s) with the [`template`](https://golang.org/pkg/text/template/#hdr-Actions)
+built-in or the functions in the [`tmpl`](../functions/tmpl/) namespace. Specify
+multiple times to add multiple template references.
-A few different forms are valid:
+Similar to data sources, the value is a `alias=url` pair, where `alias` is the
+template name and `url` is an optionally-relative URL to the template file or
+directory. Note that currently only `file:` URLs are supported.
+
+In addition to the `alias=url` form, in certain cases the alias may be omitted,
+in which case the `url` will be used as the `alias`. When referencing a
+directory, all files in the directory will be included, available to be
+referenced as `alias/<filename>`.
+
+Some examples:
+
+- `--template foo=file:///tmp/foo.tmpl`
+ - References a file `/tmp/foo.tmpl`
+ - It will be available as a template named `foo`:
+ ```console
+ $ gomplate --template foo=file:///tmp/foo.tmpl -i 'here are the contents of the template: [ {{ template "foo" }} ]'
+ here are the contents of the template: [ hello, world! ]
+ ```
- `--template mytemplate.t`
- References a file `mytemplate.t` in the current working directory.
- It will be available as a template named `mytemplate.t`:
diff --git a/go.mod b/go.mod
index 506992db..28ad6e59 100644
--- a/go.mod
+++ b/go.mod
@@ -6,18 +6,19 @@ require (
github.com/Masterminds/goutils v1.1.1
github.com/Shopify/ejson v1.3.3
github.com/apparentlymart/go-cidr v1.1.0
- github.com/aws/aws-sdk-go v1.44.21
+ github.com/aws/aws-sdk-go v1.44.24
github.com/docker/libkv v0.2.2-0.20180912205406-458977154600
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa
github.com/go-git/go-billy/v5 v5.3.1
github.com/go-git/go-git/v5 v5.4.2
github.com/google/uuid v1.3.0
github.com/gosimple/slug v1.12.0
+ github.com/hairyhenderson/go-fsimpl v0.0.0-20220529183339-9deae3e35047
github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf
github.com/hashicorp/consul/api v1.12.0
github.com/hashicorp/go-sockaddr v1.0.2
- github.com/hashicorp/vault/api v1.5.0
- github.com/johannesboyne/gofakes3 v0.0.0-20220314170512-33c13122505e
+ github.com/hashicorp/vault/api v1.6.0
+ github.com/johannesboyne/gofakes3 v0.0.0-20220517215058-83a58ec253b6
github.com/joho/godotenv v1.4.0
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.26.1
@@ -27,86 +28,88 @@ require (
github.com/ugorji/go/codec v1.2.7
github.com/zealic/xignore v0.3.3
go.etcd.io/bbolt v1.3.6
- gocloud.dev v0.25.0
- golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
- golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
+ gocloud.dev v0.25.1-0.20220408200107-09b10f7359f7
+ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/text v0.3.7
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
+ gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.2.0
inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6
k8s.io/client-go v0.24.0
)
require (
- cloud.google.com/go v0.100.2 // indirect
- cloud.google.com/go/compute v1.5.0 // indirect
+ cloud.google.com/go v0.102.0 // indirect
+ cloud.google.com/go/compute v1.6.1 // indirect
cloud.google.com/go/iam v0.3.0 // indirect
- cloud.google.com/go/storage v1.21.0 // indirect
+ cloud.google.com/go/storage v1.22.1 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
- github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f // indirect
+ github.com/ProtonMail/go-crypto v0.0.0-20220517143526-88bb52951d5b // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
- github.com/armon/go-metrics v0.3.10 // indirect
+ github.com/armon/go-metrics v0.4.0 // indirect
github.com/armon/go-radix v1.0.0 // indirect
- github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect
+ github.com/aws/aws-sdk-go-v2 v1.16.4 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect
- github.com/aws/aws-sdk-go-v2/config v1.15.3 // indirect
- github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect
- github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 // indirect
- github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 // indirect
- github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 // indirect
- github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 // indirect
- github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 // indirect
+ github.com/aws/aws-sdk-go-v2/config v1.15.9 // indirect
+ github.com/aws/aws-sdk-go-v2/credentials v1.12.4 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.14 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.11 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 // indirect
- github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 // indirect
- github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect
- github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.5 // indirect
+ github.com/aws/aws-sdk-go-v2/service/s3 v1.26.10 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sso v1.11.7 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sts v1.16.6 // indirect
github.com/aws/smithy-go v1.11.2 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect
- github.com/emirpasic/gods v1.12.0 // indirect
+ github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
- github.com/google/go-cmp v0.5.7 // indirect
+ github.com/google/go-cmp v0.5.8 // indirect
github.com/google/wire v0.5.0 // indirect
- github.com/googleapis/gax-go/v2 v2.2.0 // indirect
+ github.com/googleapis/gax-go/v2 v2.4.0 // indirect
+ github.com/googleapis/go-type-adapters v1.0.0 // indirect
github.com/gosimple/unidecode v1.0.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
- github.com/hashicorp/go-plugin v1.4.3 // indirect
- github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
+ github.com/hashicorp/go-plugin v1.4.4 // indirect
+ github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 // indirect
- github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4 // indirect
+ github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
- github.com/hashicorp/go-uuid v1.0.2 // indirect
- github.com/hashicorp/go-version v1.4.0 // indirect
+ github.com/hashicorp/go-uuid v1.0.3 // indirect
+ github.com/hashicorp/go-version v1.5.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.9.7 // indirect
- github.com/hashicorp/vault/sdk v0.4.1 // indirect
+ github.com/hashicorp/vault/sdk v0.5.0 // indirect
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
- github.com/imdario/mergo v0.3.12 // indirect
+ github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
- github.com/kevinburke/ssh_config v1.1.0 // indirect
+ github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
- github.com/mitchellh/mapstructure v1.4.3 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
@@ -121,15 +124,15 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go4.org/intern v0.0.0-20220301175310-a089fc204883 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect
- golang.org/x/net v0.0.0-20220401154927-543a649e0bdd // indirect
- golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect
- golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
+ golang.org/x/net v0.0.0-20220526153639-5463443f8c37 // indirect
+ golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 // indirect
+ golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
golang.org/x/tools v0.1.10 // indirect
- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
- google.golang.org/api v0.74.0 // indirect
+ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
+ google.golang.org/api v0.81.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect
- google.golang.org/grpc v1.45.0 // indirect
+ google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58 // indirect
+ google.golang.org/grpc v1.46.2 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
diff --git a/go.sum b/go.sum
index bbeb04f3..8dfe2050 100644
--- a/go.sum
+++ b/go.sum
@@ -30,8 +30,9 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=
-cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
+cloud.google.com/go v0.102.0 h1:DAq3r8y4mDgyB/ZPJ9v/5VJNqjgJAxTn6ZYLlUywOu8=
+cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -41,8 +42,10 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw=
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
-cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
+cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
+cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=
+cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
@@ -66,8 +69,9 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
-cloud.google.com/go/storage v1.21.0 h1:HwnT2u2D309SFDHQII6m18HlrCi3jAXhUMTLOWXYH14=
cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA=
+cloud.google.com/go/storage v1.22.1 h1:F6IlQJZrZM++apn9V5/VfS3gbTUYg98PS3EMQAzqtfg=
+cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=
cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM=
contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
@@ -119,8 +123,8 @@ github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
-github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f h1:J2FzIrXN82q5uyUraeJpLIm7U6PffRwje2ORho5yIik=
-github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
+github.com/ProtonMail/go-crypto v0.0.0-20220517143526-88bb52951d5b h1:lcbBNuQhppsc7A5gjdHmdlqUqJfgGMylBdGyDs0j7G8=
+github.com/ProtonMail/go-crypto v0.0.0-20220517143526-88bb52951d5b/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/ejson v1.3.3 h1:dPzgmvFhUPTJIzwdF5DaqbwW1dWaoR8ADKRdSTy6Mss=
@@ -139,8 +143,8 @@ github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/Y
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
-github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo=
-github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
+github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q=
+github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@@ -151,45 +155,61 @@ github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo
github.com/aws/aws-sdk-go v1.17.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
-github.com/aws/aws-sdk-go v1.44.21 h1:xZBdJmgkTQuIrbq5jSi5gyUwyz4eRTvjmLoT+c+Ao/A=
-github.com/aws/aws-sdk-go v1.44.21/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
-github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA=
+github.com/aws/aws-sdk-go v1.44.24 h1:3nOkwJBJLiGBmJKWp3z0utyXuBkxyGkRRwWjrTItJaY=
+github.com/aws/aws-sdk-go v1.44.24/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
+github.com/aws/aws-sdk-go-v2 v1.16.4 h1:swQTEQUyJF/UkEA94/Ga55miiKFoXmm/Zd67XHgmjSg=
+github.com/aws/aws-sdk-go-v2 v1.16.4/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 h1:SdK4Ppk5IzLs64ZMvr6MrSficMtjY2oS0WOORXTlxwU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM=
-github.com/aws/aws-sdk-go-v2/config v1.15.3 h1:5AlQD0jhVXlGzwo+VORKiUuogkG7pQcLJNzIzK7eodw=
github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg=
-github.com/aws/aws-sdk-go-v2/credentials v1.11.2 h1:RQQ5fzclAKJyY5TvF+fkjJEwzK4hnxQCLOu5JXzDmQo=
+github.com/aws/aws-sdk-go-v2/config v1.15.9 h1:TK5yNEnFDQ9iaO04gJS/3Y+eW8BioQiCUafW75/Wc3Q=
+github.com/aws/aws-sdk-go-v2/config v1.15.9/go.mod h1:rv/l/TbZo67kp99v/3Kb0qV6Fm1KEtKyruEV2GvVfgs=
github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 h1:LWPg5zjHV9oz/myQr4wMs0gi4CjnDN/ILmyZUFYXZsU=
+github.com/aws/aws-sdk-go-v2/credentials v1.12.4 h1:xggwS+qxCukXRVXJBJWQJGyUsvuxGC8+J1kKzv2cxuw=
+github.com/aws/aws-sdk-go-v2/credentials v1.12.4/go.mod h1:7g+GGSp7xtR823o1jedxKmqRZGqLdoHQfI4eFasKKxs=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk=
-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 h1:ir7iEq78s4txFGgwcLqD6q9IIPzTQNRJXulJd9h/zQo=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5 h1:YPxclBeE07HsLQE8vtjC8T2emcTjM9nzqsnDi2fv5UM=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5/go.mod h1:WAPnuhG5IQ/i6DETFl5NmX3kKqCzw7aau9NHAGcm4QE=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 h1:onz/VaaxZ7Z4V+WIN9Txly9XLTmoOh1oJ8XcAC3pako=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.14 h1:qpJmFbypCfwPok5PGTSnQy1NKbv4Hn8xGsee9l4xOPE=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.14/go.mod h1:IOYB+xOZik8YgdTlnDSwbvKmCkikA3nVue8/Qnfzs0c=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 h1:9stUQR/u2KXU6HkFJYlqnZEjBnbgrVbG6I5HN09xZh0=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.11 h1:gsqHplNh1DaQunEKZISK56wlpbCg0yKxNVvGWCFuF1k=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.11/go.mod h1:tmUB6jakq5DFNcXsXOA/ZQ7/C8VnSKYkx58OI7Fh79g=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM=
-github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 h1:by9P+oy3P/CwggN4ClnW2D4oL91QV7pBzBICi1chZvQ=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5 h1:PLFj+M2PgIDHG//hw3T0O0KLI4itVtAjtxrZx4AHPLg=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5/go.mod h1:fV1AaS2gFc1tM0RCb015FJ0pvWVUfJZANzjwoO4YakM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12 h1:j0VqrjtgsY1Bx27tD0ysay36/K4kFMWRp9K3ieO9nLU=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12/go.mod h1:00c7+ALdPh4YeEUPXJzyU0Yy01nPGOq2+9rUaz05z9g=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.2 h1:1fs9WkbFcMawQjxEI0B5L0SqvBhJZebxWM6Z3x/qHWY=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.2/go.mod h1:0jDVeWUFPbI3sOfsXXAsIdiawXcn7VBLx/IlFVTRP64=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 h1:T4pFel53bkHjL2mMo+4DKE6r6AuoZnM0fg7k1/ratr4=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc=
-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 h1:I0dcwWitE752hVSMrsLCxqNQ+UdEp3nACx2bYNMQq+k=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 h1:Gh1Gpyh01Yvn7ilO/b/hr01WgNpaszfbKMUgqM186xQ=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.6 h1:9mvDAsMiN+07wcfGM+hJ1J3dOKZ2YOpDiPZ6ufRJcgw=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.6/go.mod h1:Eus+Z2iBIEfhOvhSdMTcscNOMy6n3X9/BJV0Zgax98w=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw=
-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 h1:BKjwCJPnANbkwQ8vzSbaZDKawwagDubrH/z/c0X+kbQ=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5 h1:gRW1ZisKc93EWEORNJRvy/ZydF3o6xLSveJHdi1Oa0U=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5/go.mod h1:ZbkttHXaVn3bBo/wpJbQGiiIWR90eTBUVBrEHUEQlho=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.5 h1:DyPYkrH4R2zn+Pdu6hM3VTuPsQYAE6x2WB24X85Sgw0=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.5/go.mod h1:XtL92YWo0Yq80iN3AgYRERJqohg4TozrqRlxYhHGJ7g=
github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g=
-github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 h1:rMPtwA7zzkSQZhhz9U3/SoIDz/NZ7Q+iRn4EIO8rSyU=
github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.26.10 h1:GWdLZK0r1AK5sKb8rhB9bEXqXCK8WNuyv4TBAD6ZviQ=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.26.10/go.mod h1:+O7qJxF8nLorAhuIVhYTHse6okjHJJm4EwhhzvpnkT0=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw=
github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM=
github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0=
-github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 h1:frW4ikGcxfAEDfmQqWgMLp+F1n4nRo9sF39OcIb5BkQ=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU=
-github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrKydRYhOvcD1NYP9Q=
+github.com/aws/aws-sdk-go-v2/service/sso v1.11.7 h1:suAGD+RyiHWPPihZzY+jw4mCZlOFWgmdjb2AeTenz7c=
+github.com/aws/aws-sdk-go-v2/service/sso v1.11.7/go.mod h1:TFVe6Rr2joVLsYQ1ABACXgOC6lXip/qpX2x5jWg/A9w=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8=
+github.com/aws/aws-sdk-go-v2/service/sts v1.16.6 h1:aYToU0/iazkMY67/BYLt3r6/LT/mUtarLAF5mGof1Kg=
+github.com/aws/aws-sdk-go-v2/service/sts v1.16.6/go.mod h1:rP1rEOKAGZoXp4iGDxSXFvODAtXpm34Egf0lL0eshaQ=
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
@@ -217,6 +237,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -242,8 +263,9 @@ github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJ
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -252,6 +274,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
@@ -383,8 +406,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE=
github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk=
github.com/google/go-replayers/httpreplay v1.1.1 h1:H91sIMlt1NZzN7R+/ASswyouLJfW0WLW7fhyUFvDEkY=
@@ -427,8 +451,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
-github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
+github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
+github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=
+github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
+github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
+github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@@ -440,6 +468,8 @@ github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6
github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/hairyhenderson/go-fsimpl v0.0.0-20220529183339-9deae3e35047 h1:nSSfN9G8O8XXDqB3aDEHJ8K+0llYYToNlTcWOe1Pti8=
+github.com/hairyhenderson/go-fsimpl v0.0.0-20220529183339-9deae3e35047/go.mod h1:30RY4Ey+bg+BGKBufZE2IEmxk7hok9U9mjdgZYomwN4=
github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf h1:I1sbT4ZbIt9i+hB1zfKw2mE8C12TuGxPiW7YmtLbPa4=
github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf/go.mod h1:jDHmWDKZY6MIIYltYYfW4Rs7hQ50oS4qf/6spSiZAxY=
github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok=
@@ -471,12 +501,13 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
-github.com/hashicorp/go-plugin v1.4.3 h1:DXmvivbWD5qdiBts9TpBC7BYL1Aia5sxbRgQB+v6UZM=
github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
+github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
+github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
-github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4=
-github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
+github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
+github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=
@@ -484,8 +515,8 @@ github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtf
github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 h1:p4AKXPPS24tO8Wc8i1gLvSKdmkiSY5xuju57czJ/IJQ=
github.com/hashicorp/go-secure-stdlib/mlock v0.1.2/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
-github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4 h1:hrIH/qrOTHfG9a1Jz6Z2jQf7Xe77AaD464W1fCFLwPQ=
-github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
+github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5 h1:MBgwAFPUbfuI0+tmDU/aeM1MARvdbqWmiieXIalKqDE=
+github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
@@ -497,11 +528,12 @@ github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjG
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4=
-github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
+github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
@@ -515,10 +547,10 @@ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/serf v0.9.7 h1:hkdgbqizGQHuU5IPqYM1JdSMV8nKfpuOnZYXssk9muY=
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
-github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28=
-github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM=
-github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo=
-github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0=
+github.com/hashicorp/vault/api v1.6.0 h1:B8UUYod1y1OoiGHq9GtpiqSnGOUEWHaA26AY8RQEDY4=
+github.com/hashicorp/vault/api v1.6.0/go.mod h1:h1K70EO2DgnBaTz5IsL6D5ERsNt5Pce93ueVS2+t0Xc=
+github.com/hashicorp/vault/sdk v0.5.0 h1:EED7p0OCU3OY5SAqJwSANofY1YKMytm+jDHDQ2EzGVQ=
+github.com/hashicorp/vault/sdk v0.5.0/go.mod h1:UJZHlfwj7qUJG8g22CuxUgkdJouFrBNvBHCyx8XAPdo=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I=
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
@@ -526,8 +558,9 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
+github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
@@ -580,8 +613,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
-github.com/johannesboyne/gofakes3 v0.0.0-20220314170512-33c13122505e h1:vyS7N0o/a00uLggd0QtEh3sGlK1Uhuu/YyVczES6/sw=
-github.com/johannesboyne/gofakes3 v0.0.0-20220314170512-33c13122505e/go.mod h1:LIAXxPvcUXwOcTIj9LSNSUpE9/eMHalTWxsP/kmWxQI=
+github.com/johannesboyne/gofakes3 v0.0.0-20220517215058-83a58ec253b6 h1:Twy/cqAmdLarn9QEiRvyX5eUyuKFxqMEiy5GQGIqwjo=
+github.com/johannesboyne/gofakes3 v0.0.0-20220517215058-83a58ec253b6/go.mod h1:LIAXxPvcUXwOcTIj9LSNSUpE9/eMHalTWxsP/kmWxQI=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
@@ -594,8 +627,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
-github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o=
-github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -633,8 +666,7 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
-github.com/mattn/go-ieproxy v0.0.3 h1:YkaHmK1CzE5C4O7A3hv3TCbfNDPSCf0RKZFX+VhBeYk=
-github.com/mattn/go-ieproxy v0.0.3/go.mod h1:6ZpRmhBaYuBX1U2za+9rC9iCGLsSp2tftelZne7CPko=
+github.com/mattn/go-ieproxy v0.0.6 h1:tVDlituRyeHMMkHpGpUu8CJG+hxPMwbYCkIUK2PUCbo=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -664,9 +696,9 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
@@ -832,8 +864,8 @@ go4.org/intern v0.0.0-20220301175310-a089fc204883 h1:pq5gAii+wMY+DsJ5r9I6T7CHjHx
go4.org/intern v0.0.0-20220301175310-a089fc204883/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 h1:Tx9kY6yUkLge/pFG7IEMwDZy6CS2ajFc9TvQdPCW0uA=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
-gocloud.dev v0.25.0 h1:Y7vDq8xj7SyM848KXf32Krda2e6jQ4CLh/mTeCSqXtk=
-gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y=
+gocloud.dev v0.25.1-0.20220408200107-09b10f7359f7 h1:esuNxgk6HkmcadSJQCFnGOfyufN1GW1gtFJDwUbmYOw=
+gocloud.dev v0.25.1-0.20220408200107-09b10f7359f7/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -857,8 +889,8 @@ golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
-golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -947,12 +979,15 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc=
golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8=
+golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -972,8 +1007,10 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw=
+golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -985,6 +1022,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1068,7 +1106,6 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1076,8 +1113,11 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
@@ -1098,8 +1138,9 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
+golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -1172,8 +1213,10 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -1215,8 +1258,12 @@ google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7
google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80=
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
-google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
+google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
+google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
+google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
+google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8=
+google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1268,6 +1315,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
@@ -1310,8 +1358,18 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
-google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de h1:9Ti5SG2U4cAcluryUo/sFay3TQKoxiFMfaT0pbizU7k=
google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58 h1:a221mAAEAzq4Lz6ZWRkcS8ptb2mxoxYSt4N68aRyQHM=
+google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1341,8 +1399,10 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ=
+google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -1388,8 +1448,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I=
gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/gomplate.go b/gomplate.go
index 15190d62..a0d37b91 100644
--- a/gomplate.go
+++ b/gomplate.go
@@ -8,7 +8,6 @@ import (
"fmt"
"io"
"os"
- "path"
"path/filepath"
"strings"
"text/template"
@@ -18,14 +17,13 @@ import (
"github.com/hairyhenderson/gomplate/v3/internal/config"
"github.com/pkg/errors"
"github.com/rs/zerolog"
- "github.com/spf13/afero"
)
// gomplate -
type gomplate struct {
tmplctx interface{}
funcMap template.FuncMap
- nestedTemplates templateAliases
+ nestedTemplates config.Templates
leftDelim, rightDelim string
}
@@ -45,10 +43,8 @@ func (g *gomplate) runTemplate(ctx context.Context, t *tplate) error {
return tmpl.Execute(t.target, g.tmplctx)
}
-type templateAliases map[string]string
-
// newGomplate -
-func newGomplate(funcMap template.FuncMap, leftDelim, rightDelim string, nested templateAliases, tctx interface{}) *gomplate {
+func newGomplate(funcMap template.FuncMap, leftDelim, rightDelim string, nested config.Templates, tctx interface{}) *gomplate {
return &gomplate{
leftDelim: leftDelim,
rightDelim: rightDelim,
@@ -58,53 +54,6 @@ func newGomplate(funcMap template.FuncMap, leftDelim, rightDelim string, nested
}
}
-func parseTemplateArgs(templateArgs []string) (templateAliases, error) {
- nested := templateAliases{}
- for _, templateArg := range templateArgs {
- err := parseTemplateArg(templateArg, nested)
- if err != nil {
- return nil, err
- }
- }
- return nested, nil
-}
-
-func parseTemplateArg(templateArg string, ta templateAliases) error {
- parts := strings.SplitN(templateArg, "=", 2)
- pth := parts[0]
- alias := ""
- if len(parts) > 1 {
- alias = parts[0]
- pth = parts[1]
- }
-
- switch fi, err := fs.Stat(pth); {
- case err != nil:
- return err
- case fi.IsDir():
- files, err := afero.ReadDir(fs, pth)
- if err != nil {
- return err
- }
- prefix := pth
- if alias != "" {
- prefix = alias
- }
- for _, f := range files {
- if !f.IsDir() { // one-level only
- ta[path.Join(prefix, f.Name())] = path.Join(pth, f.Name())
- }
- }
- default:
- if alias != "" {
- ta[alias] = pth
- } else {
- ta[pth] = pth
- }
- }
- return nil
-}
-
// RunTemplates - run all gomplate templates specified by the given configuration
//
// Deprecated: use Run instead
@@ -123,7 +72,7 @@ func Run(ctx context.Context, cfg *config.Config) error {
Metrics = newMetrics()
defer runCleanupHooks()
- // reset defaults before validation
+ // apply defaults before validation
cfg.ApplyDefaults()
err := cfg.Validate()
@@ -135,10 +84,6 @@ func Run(ctx context.Context, cfg *config.Config) error {
log.Debug().Str("data", fmt.Sprintf("%+v", d)).Msg("created data from config")
addCleanupHook(d.Cleanup)
- nested, err := parseTemplateArgs(cfg.Templates)
- if err != nil {
- return err
- }
aliases := []string{}
for k := range cfg.Context {
@@ -154,7 +99,7 @@ func Run(ctx context.Context, cfg *config.Config) error {
if err != nil {
return err
}
- g := newGomplate(funcMap, cfg.LDelim, cfg.RDelim, nested, c)
+ g := newGomplate(funcMap, cfg.LDelim, cfg.RDelim, cfg.Templates, c)
return g.runTemplates(ctx, cfg)
}
diff --git a/gomplate_test.go b/gomplate_test.go
index 89f36831..0d621ab7 100644
--- a/gomplate_test.go
+++ b/gomplate_test.go
@@ -8,8 +8,6 @@ import (
"path/filepath"
"testing"
- "github.com/spf13/afero"
-
"text/template"
"github.com/hairyhenderson/gomplate/v3/aws"
@@ -166,68 +164,6 @@ func TestRunTemplates(t *testing.T) {
assert.Equal(t, 0, Metrics.Errors)
}
-func TestParseTemplateArg(t *testing.T) {
- fs = afero.NewMemMapFs()
- afero.WriteFile(fs, "foo.t", []byte("hi"), 0600)
- _ = fs.MkdirAll("dir", 0755)
- afero.WriteFile(fs, "dir/foo.t", []byte("hi"), 0600)
- afero.WriteFile(fs, "dir/bar.t", []byte("hi"), 0600)
-
- err := parseTemplateArg("bogus.t", templateAliases{})
- assert.Error(t, err)
-
- testdata := []struct {
- expected map[string]string
- arg string
- }{
- {map[string]string{"foo.t": "foo.t"}, "foo.t"},
- {map[string]string{"foo": "foo.t"}, "foo=foo.t"},
- {map[string]string{"dir/foo.t": "dir/foo.t"}, "dir/foo.t"},
- {map[string]string{"foo": "dir/foo.t"}, "foo=dir/foo.t"},
- {map[string]string{"dir/foo.t": "dir/foo.t", "dir/bar.t": "dir/bar.t"}, "dir/"},
- {map[string]string{"t/foo.t": "dir/foo.t", "t/bar.t": "dir/bar.t"}, "t=dir/"},
- }
-
- for _, d := range testdata {
- nested := templateAliases{}
- err := parseTemplateArg(d.arg, nested)
- assert.NoError(t, err, d.arg)
- assert.Equal(t, templateAliases(d.expected), nested, d.arg)
- }
-}
-
-func TestParseTemplateArgs(t *testing.T) {
- fs = afero.NewMemMapFs()
- afero.WriteFile(fs, "foo.t", []byte("hi"), 0600)
- _ = fs.MkdirAll("dir", 0755)
- afero.WriteFile(fs, "dir/foo.t", []byte("hi"), 0600)
- afero.WriteFile(fs, "dir/bar.t", []byte("hi"), 0600)
-
- args := []string{"foo.t",
- "foo=foo.t",
- "bar=dir/foo.t",
- "dir/",
- "t=dir/",
- }
-
- expected := map[string]string{
- "foo.t": "foo.t",
- "foo": "foo.t",
- "bar": "dir/foo.t",
- "dir/foo.t": "dir/foo.t",
- "dir/bar.t": "dir/bar.t",
- "t/foo.t": "dir/foo.t",
- "t/bar.t": "dir/bar.t",
- }
-
- nested, err := parseTemplateArgs(args)
- assert.NoError(t, err)
- assert.Equal(t, templateAliases(expected), nested)
-
- _, err = parseTemplateArgs([]string{"bogus.t"})
- assert.Error(t, err)
-}
-
func TestSimpleNamer(t *testing.T) {
n := simpleNamer("out/")
out, err := n(context.Background(), "file")
diff --git a/internal/cmd/config.go b/internal/cmd/config.go
index d48c6b63..cdcc1d3e 100644
--- a/internal/cmd/config.go
+++ b/internal/cmd/config.go
@@ -126,10 +126,6 @@ func cobraConfig(cmd *cobra.Command, args []string) (cfg *config.Config, err err
if err != nil {
return nil, err
}
- cfg.Templates, err = getStringSlice(cmd, "template")
- if err != nil {
- return nil, err
- }
cfg.OutputDir, err = getString(cmd, "output-dir")
if err != nil {
return nil, err
@@ -173,11 +169,15 @@ func cobraConfig(cmd *cobra.Command, args []string) (cfg *config.Config, err err
if err != nil {
return nil, err
}
+ ts, err := getStringSlice(cmd, "template")
+ if err != nil {
+ return nil, err
+ }
hdr, err := getStringSlice(cmd, "datasource-header")
if err != nil {
return nil, err
}
- err = cfg.ParseDataSourceFlags(ds, cx, hdr)
+ err = cfg.ParseDataSourceFlags(ds, cx, ts, hdr)
if err != nil {
return nil, err
}
diff --git a/internal/cmd/main.go b/internal/cmd/main.go
index c87a3ee2..f52e3e29 100644
--- a/internal/cmd/main.go
+++ b/internal/cmd/main.go
@@ -7,6 +7,7 @@ import (
"os/exec"
"os/signal"
+ "github.com/hairyhenderson/go-fsimpl/filefs"
"github.com/hairyhenderson/gomplate/v3"
"github.com/hairyhenderson/gomplate/v3/env"
"github.com/hairyhenderson/gomplate/v3/version"
@@ -166,6 +167,13 @@ func InitFlags(command *cobra.Command) {
func Main(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
ctx = initLogger(ctx, stderr)
+ // inject a default filesystem provider for file:// URLs
+ // TODO: expand this to support other schemes!
+ if gomplate.FSProviderFromContext(ctx) == nil {
+ // allow this to be overridden by tests
+ ctx = gomplate.ContextWithFSProvider(ctx, filefs.FS)
+ }
+
command := NewGomplateCmd()
InitFlags(command)
command.SetArgs(args)
diff --git a/internal/config/configfile.go b/internal/config/configfile.go
index 687c232b..8bfdd0b7 100644
--- a/internal/config/configfile.go
+++ b/internal/config/configfile.go
@@ -36,6 +36,15 @@ type Config struct {
Stdout io.Writer `yaml:"-"`
Stderr io.Writer `yaml:"-"`
+ DataSources map[string]DataSource `yaml:"datasources,omitempty"`
+ Context map[string]DataSource `yaml:"context,omitempty"`
+ Plugins map[string]PluginConfig `yaml:"plugins,omitempty"`
+ Templates Templates `yaml:"templates,omitempty"`
+
+ // Extra HTTP headers not attached to pre-defined datsources. Potentially
+ // used by datasources defined in the template.
+ ExtraHeaders map[string]http.Header `yaml:"-"`
+
// internal use only, can't be injected in YAML
PostExecInput io.Reader `yaml:"-"`
@@ -54,16 +63,6 @@ type Config struct {
PostExec []string `yaml:"postExec,omitempty,flow"`
- DataSources map[string]DataSource `yaml:"datasources,omitempty"`
- Context map[string]DataSource `yaml:"context,omitempty"`
- Plugins map[string]PluginConfig `yaml:"plugins,omitempty"`
-
- // Extra HTTP headers not attached to pre-defined datsources. Potentially
- // used by datasources defined in the template.
- ExtraHeaders map[string]http.Header `yaml:"-"`
-
- Templates []string `yaml:"templates,omitempty"`
-
PluginTimeout time.Duration `yaml:"pluginTimeout,omitempty"`
ExecPipe bool `yaml:"execPipe,omitempty"`
@@ -251,8 +250,10 @@ func (c *Config) MergeFrom(o *Config) *Config {
if !isZero(o.RDelim) {
c.RDelim = o.RDelim
}
- if !isZero(o.Templates) {
+ if c.Templates == nil {
c.Templates = o.Templates
+ } else {
+ mergeDataSources(c.Templates, o.Templates)
}
if c.DataSources == nil {
c.DataSources = o.DataSources
@@ -273,9 +274,44 @@ func (c *Config) MergeFrom(o *Config) *Config {
return c
}
-// ParseDataSourceFlags - sets the DataSources and Context fields from the
-// key=value format flags as provided at the command-line
-func (c *Config) ParseDataSourceFlags(datasources, contexts, headers []string) error {
+// ParseDataSourceFlags - sets DataSources, Context, and Templates fields from
+// the key=value format flags as provided at the command-line
+// Unreferenced headers will be set in c.ExtraHeaders
+func (c *Config) ParseDataSourceFlags(datasources, contexts, templates, headers []string) error {
+ err := c.parseResources(datasources, contexts, templates)
+ if err != nil {
+ return err
+ }
+
+ hdrs, err := parseHeaderArgs(headers)
+ if err != nil {
+ return err
+ }
+
+ for k, v := range hdrs {
+ if d, ok := c.Context[k]; ok {
+ d.Header = v
+ c.Context[k] = d
+ delete(hdrs, k)
+ }
+ if d, ok := c.DataSources[k]; ok {
+ d.Header = v
+ c.DataSources[k] = d
+ delete(hdrs, k)
+ }
+ if t, ok := c.Templates[k]; ok {
+ t.Header = v
+ c.Templates[k] = t
+ delete(hdrs, k)
+ }
+ }
+ if len(hdrs) > 0 {
+ c.ExtraHeaders = hdrs
+ }
+ return nil
+}
+
+func (c *Config) parseResources(datasources, contexts, templates []string) error {
for _, d := range datasources {
k, ds, err := parseDatasourceArg(d)
if err != nil {
@@ -296,27 +332,17 @@ func (c *Config) ParseDataSourceFlags(datasources, contexts, headers []string) e
}
c.Context[k] = ds
}
-
- hdrs, err := parseHeaderArgs(headers)
- if err != nil {
- return err
- }
-
- for k, v := range hdrs {
- if d, ok := c.Context[k]; ok {
- d.Header = v
- c.Context[k] = d
- delete(hdrs, k)
+ for _, t := range templates {
+ k, ds, err := parseTemplateArg(t)
+ if err != nil {
+ return err
}
- if d, ok := c.DataSources[k]; ok {
- d.Header = v
- c.DataSources[k] = d
- delete(hdrs, k)
+ if c.Templates == nil {
+ c.Templates = map[string]DataSource{}
}
+ c.Templates[k] = ds
}
- if len(hdrs) > 0 {
- c.ExtraHeaders = hdrs
- }
+
return nil
}
@@ -336,21 +362,20 @@ func (c *Config) ParsePluginFlags(plugins []string) error {
return nil
}
-func parseDatasourceArg(value string) (key string, ds DataSource, err error) {
- parts := strings.SplitN(value, "=", 2)
- if len(parts) == 1 {
- f := parts[0]
- key = strings.SplitN(value, ".", 2)[0]
- if path.Base(f) != f {
- err = fmt.Errorf("invalid datasource (%s): must provide an alias with files not in working directory", value)
- return key, ds, err
+func parseDatasourceArg(value string) (alias string, ds DataSource, err error) {
+ alias, u, _ := strings.Cut(value, "=")
+ if u == "" {
+ u = alias
+ alias, _, _ = strings.Cut(value, ".")
+ if path.Base(u) != u {
+ err = fmt.Errorf("invalid argument (%s): must provide an alias with files not in working directory", value)
+ return alias, ds, err
}
- ds.URL, err = ParseSourceURL(f)
- } else if len(parts) == 2 {
- key = parts[0]
- ds.URL, err = ParseSourceURL(parts[1])
}
- return key, ds, err
+
+ ds.URL, err = ParseSourceURL(u)
+
+ return alias, ds, err
}
func parseHeaderArgs(headerArgs []string) (map[string]http.Header, error) {
diff --git a/internal/config/configfile_test.go b/internal/config/configfile_test.go
index 567ded60..458306a1 100644
--- a/internal/config/configfile_test.go
+++ b/internal/config/configfile_test.go
@@ -383,21 +383,65 @@ func TestMergeFrom(t *testing.T) {
}
assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ // test template merging & a few other things
+ cfg = &Config{
+ InputDir: "indir/",
+ ExcludeGlob: []string{"*.txt"},
+ Templates: Templates{
+ "foo": {
+ URL: mustURL("file:///foo.yaml"),
+ },
+ "bar": {
+ URL: mustURL("stdin:///"),
+ Header: http.Header{"Accept": {"application/json"}},
+ },
+ },
+ }
+ other = &Config{
+ ExcludeGlob: []string{"*.yaml"},
+ OutputMap: "${ .in }.out",
+ OutMode: "600",
+ LDelim: "${",
+ RDelim: "}",
+ Templates: Templates{
+ "foo": {URL: mustURL("https://example.com/foo.yaml")},
+ "baz": {URL: mustURL("vault:///baz")},
+ },
+ }
+ expected = &Config{
+ InputDir: "indir/",
+ ExcludeGlob: []string{"*.yaml"},
+ OutputMap: "${ .in }.out",
+ OutMode: "600",
+ LDelim: "${",
+ RDelim: "}",
+ Templates: Templates{
+ "foo": {URL: mustURL("https://example.com/foo.yaml")},
+ "bar": {
+ URL: mustURL("stdin:///"),
+ Header: http.Header{"Accept": {"application/json"}},
+ },
+ "baz": {URL: mustURL("vault:///baz")},
+ },
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
}
func TestParseDataSourceFlags(t *testing.T) {
t.Parallel()
cfg := &Config{}
- err := cfg.ParseDataSourceFlags(nil, nil, nil)
+ err := cfg.ParseDataSourceFlags(nil, nil, nil, nil)
assert.NoError(t, err)
assert.EqualValues(t, &Config{}, cfg)
cfg = &Config{}
- err = cfg.ParseDataSourceFlags([]string{"foo/bar/baz.json"}, nil, nil)
+ err = cfg.ParseDataSourceFlags([]string{"foo/bar/baz.json"}, nil, nil, nil)
assert.Error(t, err)
cfg = &Config{}
- err = cfg.ParseDataSourceFlags([]string{"baz=foo/bar/baz.json"}, nil, nil)
+ err = cfg.ParseDataSourceFlags([]string{"baz=foo/bar/baz.json"}, nil, nil, nil)
assert.NoError(t, err)
expected := &Config{
DataSources: map[string]DataSource{
@@ -410,6 +454,7 @@ func TestParseDataSourceFlags(t *testing.T) {
err = cfg.ParseDataSourceFlags(
[]string{"baz=foo/bar/baz.json"},
nil,
+ nil,
[]string{"baz=Accept: application/json"})
assert.NoError(t, err)
assert.EqualValues(t, &Config{
@@ -427,6 +472,7 @@ func TestParseDataSourceFlags(t *testing.T) {
err = cfg.ParseDataSourceFlags(
[]string{"baz=foo/bar/baz.json"},
[]string{"foo=http://example.com"},
+ nil,
[]string{"foo=Accept: application/json",
"bar=Authorization: Basic xxxxx"})
assert.NoError(t, err)
@@ -446,6 +492,28 @@ func TestParseDataSourceFlags(t *testing.T) {
"bar": {"Authorization": {"Basic xxxxx"}},
},
}, cfg)
+
+ cfg = &Config{}
+ err = cfg.ParseDataSourceFlags(
+ nil,
+ nil,
+ []string{"foo=http://example.com", "file.tmpl", "tmpldir/"},
+ []string{"foo=Accept: application/json",
+ "bar=Authorization: Basic xxxxx"})
+ assert.NoError(t, err)
+ assert.EqualValues(t, &Config{
+ Templates: Templates{
+ "foo": {
+ URL: mustURL("http://example.com"),
+ Header: http.Header{"Accept": {"application/json"}},
+ },
+ "file.tmpl": {URL: mustURL("file.tmpl")},
+ "tmpldir/": {URL: mustURL("tmpldir/")},
+ },
+ ExtraHeaders: map[string]http.Header{
+ "bar": {"Authorization": {"Basic xxxxx"}},
+ },
+ }, cfg)
}
func TestParsePluginFlags(t *testing.T) {
@@ -478,7 +546,10 @@ pluginTimeout: 5s
RDelim: "R",
Input: "foo",
OutputFiles: []string{"-"},
- Templates: []string{"foo=foo.t", "bar=bar.t"},
+ Templates: Templates{
+ "foo": {URL: mustURL("https://www.example.com/foo.tmpl")},
+ "bar": {URL: mustURL("/tmp/bar.t")},
+ },
}
expected = `---
in: foo
@@ -486,17 +557,22 @@ outputFiles: ['-']
leftDelim: L
rightDelim: R
templates:
- - foo=foo.t
- - bar=bar.t
+ foo:
+ url: https://www.example.com/foo.tmpl
+ bar:
+ url: file:///tmp/bar.t
`
- assert.Equal(t, expected, c.String())
+ assert.YAMLEq(t, expected, c.String())
c = &Config{
LDelim: "L",
RDelim: "R",
Input: "long input that should be truncated",
OutputFiles: []string{"-"},
- Templates: []string{"foo=foo.t", "bar=bar.t"},
+ Templates: Templates{
+ "foo": {URL: mustURL("https://www.example.com/foo.tmpl")},
+ "bar": {URL: mustURL("/tmp/bar.t")},
+ },
}
expected = `---
in: long inp...
@@ -504,10 +580,12 @@ outputFiles: ['-']
leftDelim: L
rightDelim: R
templates:
- - foo=foo.t
- - bar=bar.t
+ foo:
+ url: https://www.example.com/foo.tmpl
+ bar:
+ url: file:///tmp/bar.t
`
- assert.Equal(t, expected, c.String())
+ assert.YAMLEq(t, expected, c.String())
c = &Config{
InputDir: "in/",
@@ -748,9 +826,9 @@ func TestAbsFileURL(t *testing.T) {
}
func TestParseDatasourceArgNoAlias(t *testing.T) {
- key, ds, err := parseDatasourceArg("foo.json")
+ alias, ds, err := parseDatasourceArg("foo.json")
assert.NoError(t, err)
- assert.Equal(t, "foo", key)
+ assert.Equal(t, "foo", alias)
assert.Equal(t, "file", ds.URL.Scheme)
_, _, err = parseDatasourceArg("../foo.json")
@@ -761,60 +839,60 @@ func TestParseDatasourceArgNoAlias(t *testing.T) {
}
func TestParseDatasourceArgWithAlias(t *testing.T) {
- key, ds, err := parseDatasourceArg("data=foo.json")
+ alias, ds, err := parseDatasourceArg("data=foo.json")
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "file", ds.URL.Scheme)
assert.True(t, ds.URL.IsAbs())
- key, ds, err = parseDatasourceArg("data=/otherdir/foo.json")
+ alias, ds, err = parseDatasourceArg("data=/otherdir/foo.json")
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "file", ds.URL.Scheme)
assert.True(t, ds.URL.IsAbs())
assert.Equal(t, "/otherdir/foo.json", ds.URL.Path)
if runtime.GOOS == "windows" {
- key, ds, err = parseDatasourceArg("data=foo.json")
+ alias, ds, err = parseDatasourceArg("data=foo.json")
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "file", ds.URL.Scheme)
assert.True(t, ds.URL.IsAbs())
assert.Equalf(t, byte(':'), ds.URL.Path[1], "Path was %s", ds.URL.Path)
- key, ds, err = parseDatasourceArg(`data=\otherdir\foo.json`)
+ alias, ds, err = parseDatasourceArg(`data=\otherdir\foo.json`)
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "file", ds.URL.Scheme)
assert.True(t, ds.URL.IsAbs())
assert.Equal(t, `/otherdir/foo.json`, ds.URL.Path)
- key, ds, err = parseDatasourceArg("data=C:\\windowsdir\\foo.json")
+ alias, ds, err = parseDatasourceArg("data=C:\\windowsdir\\foo.json")
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "file", ds.URL.Scheme)
assert.True(t, ds.URL.IsAbs())
assert.Equal(t, "C:/windowsdir/foo.json", ds.URL.Path)
- key, ds, err = parseDatasourceArg("data=\\\\somehost\\share\\foo.json")
+ alias, ds, err = parseDatasourceArg("data=\\\\somehost\\share\\foo.json")
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "file", ds.URL.Scheme)
assert.Equal(t, "somehost", ds.URL.Host)
assert.True(t, ds.URL.IsAbs())
assert.Equal(t, "/share/foo.json", ds.URL.Path)
}
- key, ds, err = parseDatasourceArg("data=sftp://example.com/blahblah/foo.json")
+ alias, ds, err = parseDatasourceArg("data=sftp://example.com/blahblah/foo.json")
assert.NoError(t, err)
- assert.Equal(t, "data", key)
+ assert.Equal(t, "data", alias)
assert.Equal(t, "sftp", ds.URL.Scheme)
assert.True(t, ds.URL.IsAbs())
assert.Equal(t, "/blahblah/foo.json", ds.URL.Path)
- key, ds, err = parseDatasourceArg("merged=merge:./foo.yaml|http://example.com/bar.json%3Ffoo=bar")
+ alias, ds, err = parseDatasourceArg("merged=merge:./foo.yaml|http://example.com/bar.json%3Ffoo=bar")
assert.NoError(t, err)
- assert.Equal(t, "merged", key)
+ assert.Equal(t, "merged", alias)
assert.Equal(t, "merge", ds.URL.Scheme)
assert.Equal(t, "./foo.yaml|http://example.com/bar.json%3Ffoo=bar", ds.URL.Opaque)
}
diff --git a/internal/config/types.go b/internal/config/types.go
new file mode 100644
index 00000000..042ba533
--- /dev/null
+++ b/internal/config/types.go
@@ -0,0 +1,93 @@
+package config
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+)
+
+// Templates - a map of templates. We can't just use map[string]DataSource,
+// because we need to be able to marshal both the old (array of '[k=]v' strings)
+// and the new (proper map) formats.
+//
+// Note that templates use the DataSource type, since they have the exact same
+// shape.
+// TODO: get rid of this and just use map[string]DataSource once the legacy
+// [k=]v array format is no longer supported
+type Templates map[string]DataSource
+
+// UnmarshalYAML - satisfy the yaml.Umarshaler interface
+func (t *Templates) UnmarshalYAML(value *yaml.Node) error {
+ // first attempt to unmarshal as a map[string]DataSource
+ err := value.Decode(map[string]DataSource(*t))
+ if err == nil {
+ return nil
+ }
+
+ // if that fails, try to unmarshal as an array of '[k=]v' strings
+ err = t.unmarshalYAMLArray(value)
+ if err != nil {
+ return fmt.Errorf("could not unmarshal templates as map or array: %w", err)
+ }
+
+ return nil
+}
+
+func (t *Templates) unmarshalYAMLArray(value *yaml.Node) error {
+ a := []string{}
+ err := value.Decode(&a)
+ if err != nil {
+ return fmt.Errorf("could not unmarshal templates as array: %w", err)
+ }
+
+ ts := Templates{}
+ for _, s := range a {
+ alias, pth, _ := strings.Cut(s, "=")
+ if pth == "" {
+ // when alias is omitted, the path and alias are identical
+ pth = alias
+ }
+
+ u, err := ParseSourceURL(pth)
+ if err != nil {
+ return fmt.Errorf("could not parse template URL %q: %w", pth, err)
+ }
+
+ ts[alias] = DataSource{
+ URL: u,
+ }
+ }
+
+ *t = ts
+
+ return nil
+}
+
+func (t Templates) MarshalYAML() (interface{}, error) {
+ type rawTemplate struct {
+ Header http.Header `yaml:"header,omitempty,flow"`
+ URL string `yaml:"url"`
+ }
+
+ m := map[string]rawTemplate{}
+ for k, v := range t {
+ m[k] = rawTemplate{
+ Header: v.Header,
+ URL: v.URL.String(),
+ }
+ }
+ return m, nil
+}
+
+func parseTemplateArg(value string) (alias string, ds DataSource, err error) {
+ alias, u, _ := strings.Cut(value, "=")
+ if u == "" {
+ u = alias
+ }
+
+ ds.URL, err = ParseSourceURL(u)
+
+ return alias, ds, err
+}
diff --git a/internal/config/types_test.go b/internal/config/types_test.go
new file mode 100644
index 00000000..93afd068
--- /dev/null
+++ b/internal/config/types_test.go
@@ -0,0 +1,88 @@
+package config
+
+import (
+ "net/http"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "gopkg.in/yaml.v3"
+)
+
+func TestTemplates_UnmarshalYAML(t *testing.T) {
+ in := `t:
+ url: foo/bar/helloworld.tmpl
+templatedir:
+ url: templatedir/
+dir:
+ url: foo/bar/
+mytemplate.t:
+ url: mytemplate.t
+remote:
+ url: https://example.com/foo/bar/helloworld.tmpl
+ header:
+ Accept: [text/plain, text/template]`
+ out := Templates{}
+ err := yaml.Unmarshal([]byte(in), &out)
+ assert.NoError(t, err)
+ assert.EqualValues(t, Templates{
+ "t": {URL: mustURL("foo/bar/helloworld.tmpl")},
+ "templatedir": {URL: mustURL("templatedir/")},
+ "dir": {URL: mustURL("foo/bar/")},
+ "mytemplate.t": {URL: mustURL("mytemplate.t")},
+ "remote": {
+ URL: mustURL("https://example.com/foo/bar/helloworld.tmpl"),
+ Header: http.Header{"Accept": {"text/plain", "text/template"}},
+ },
+ }, out)
+
+ // legacy array format
+ in = `- t=foo/bar/helloworld.tmpl
+- templatedir/
+- dir=foo/bar/
+- mytemplate.t
+- remote=https://example.com/foo/bar/helloworld.tmpl`
+ out = Templates{}
+ err = yaml.Unmarshal([]byte(in), &out)
+ assert.NoError(t, err)
+ assert.EqualValues(t, Templates{
+ "t": {URL: mustURL("foo/bar/helloworld.tmpl")},
+ "templatedir/": {URL: mustURL("templatedir/")},
+ "dir": {URL: mustURL("foo/bar/")},
+ "mytemplate.t": {URL: mustURL("mytemplate.t")},
+ "remote": {URL: mustURL("https://example.com/foo/bar/helloworld.tmpl")},
+ }, out)
+
+ // invalid format
+ in = `"neither an array nor a map"`
+ out = Templates{}
+ err = yaml.Unmarshal([]byte(in), &out)
+ assert.Error(t, err)
+
+ // invalid URL
+ in = `- t="not a:valid url"`
+ out = Templates{}
+ err = yaml.Unmarshal([]byte(in), &out)
+ assert.Error(t, err)
+}
+
+func TestParseTemplateArg(t *testing.T) {
+ data := []struct {
+ ds DataSource
+ in string
+ alias string
+ }{
+ {in: "t=foo/bar/helloworld.tmpl", alias: "t", ds: DataSource{URL: mustURL("foo/bar/helloworld.tmpl")}},
+ {in: "templatedir/", alias: "templatedir/", ds: DataSource{URL: mustURL("templatedir/")}},
+ {in: "dir=foo/bar/", alias: "dir", ds: DataSource{URL: mustURL("foo/bar/")}},
+ {in: "mytemplate.t", alias: "mytemplate.t", ds: DataSource{URL: mustURL("mytemplate.t")}},
+ {in: "remote=https://example.com/foo/bar/helloworld.tmpl",
+ alias: "remote", ds: DataSource{URL: mustURL("https://example.com/foo/bar/helloworld.tmpl")}},
+ }
+
+ for _, d := range data {
+ alias, ds, err := parseTemplateArg(d.in)
+ assert.NoError(t, err)
+ assert.Equal(t, d.alias, alias)
+ assert.EqualValues(t, d.ds, ds)
+ }
+}
diff --git a/internal/tests/integration/nested_templates_test.go b/internal/tests/integration/nested_templates_test.go
index 07fdb3f1..aadd412f 100644
--- a/internal/tests/integration/nested_templates_test.go
+++ b/internal/tests/integration/nested_templates_test.go
@@ -38,4 +38,12 @@ func TestNestedTemplates(t *testing.T) {
{{ template "templates/two.t" "two"}}`).
withDir(tmpDir.Path()).run()
assertSuccess(t, o, e, err, "one\n1: two 2: two ")
+
+ // referencing a dir without a trailing / is undocumented, but works
+ // currently - I don't want to break it...
+ o, e, err = cmd(t, "-t", "templates",
+ "-i", `{{ template "templates/one.t" "one"}}
+{{ template "templates/two.t" "two"}}`).
+ withDir(tmpDir.Path()).run()
+ assertSuccess(t, o, e, err, "one\n1: two 2: two ")
}
diff --git a/template.go b/template.go
index e161a800..81ecbf14 100644
--- a/template.go
+++ b/template.go
@@ -4,11 +4,15 @@ import (
"context"
"fmt"
"io"
+ "io/fs"
"io/ioutil"
"os"
+ "path"
"path/filepath"
+ "strings"
"text/template"
+ "github.com/hairyhenderson/go-fsimpl"
"github.com/hairyhenderson/gomplate/v3/internal/config"
"github.com/hairyhenderson/gomplate/v3/internal/iohelpers"
"github.com/hairyhenderson/gomplate/v3/tmpl"
@@ -21,7 +25,7 @@ import (
const gomplateignore = ".gomplateignore"
// for overriding in tests
-var fs = afero.NewOsFs()
+var aferoFS = afero.NewOsFs()
// tplate - models a gomplate template file...
type tplate struct {
@@ -53,6 +57,23 @@ func copyFuncMap(funcMap template.FuncMap) template.FuncMap {
return newFuncMap
}
+var fsProviderCtxKey = struct{}{}
+
+// ContextWithFSProvider returns a context with the given FSProvider. Should
+// only be used in tests.
+func ContextWithFSProvider(ctx context.Context, fsp fsimpl.FSProvider) context.Context {
+ return context.WithValue(ctx, fsProviderCtxKey, fsp)
+}
+
+// FSProviderFromContext returns the FSProvider from the context, if any
+func FSProviderFromContext(ctx context.Context) fsimpl.FSProvider {
+ if fsp, ok := ctx.Value(fsProviderCtxKey).(fsimpl.FSProvider); ok {
+ return fsp
+ }
+
+ return nil
+}
+
// toGoTemplate - parses t.contents as a Go template named t.name with the
// configured funcMap, delimiters, and nested templates.
func (t *tplate) toGoTemplate(ctx context.Context, g *gomplate) (tmpl *template.Template, err error) {
@@ -69,24 +90,101 @@ func (t *tplate) toGoTemplate(ctx context.Context, g *gomplate) (tmpl *template.
if err != nil {
return nil, err
}
- for alias, path := range g.nestedTemplates {
- // nolint: gosec
- b, err := ioutil.ReadFile(path)
+
+ err = parseNestedTemplates(ctx, g.nestedTemplates, tmpl)
+ if err != nil {
+ return nil, fmt.Errorf("parse nested templates: %w", err)
+ }
+
+ return tmpl, nil
+}
+
+func parseNestedTemplates(ctx context.Context, nested config.Templates, tmpl *template.Template) error {
+ fsp := FSProviderFromContext(ctx)
+
+ for alias, n := range nested {
+ u := *n.URL
+
+ fname := path.Base(u.Path)
+ if strings.HasSuffix(u.Path, "/") {
+ fname = "."
+ }
+
+ u.Path = path.Dir(u.Path)
+
+ fsys, err := fsp.New(&u)
if err != nil {
- return nil, err
+ return fmt.Errorf("filesystem provider for %q unavailable: %w", &u, err)
}
- _, err = tmpl.New(alias).Parse(string(b))
+
+ // inject context & header in case they're useful...
+ fsys = fsimpl.WithContextFS(ctx, fsys)
+ fsys = fsimpl.WithHeaderFS(n.Header, fsys)
+
+ // valid fs.FS paths have no trailing slash
+ fname = strings.TrimRight(fname, "/")
+
+ // first determine if the template path is a directory, in which case we
+ // need to load all the files in the directory (but not recursively)
+ fi, err := fs.Stat(fsys, fname)
if err != nil {
- return nil, err
+ return fmt.Errorf("stat %q: %w", fname, err)
+ }
+
+ if fi.IsDir() {
+ err = parseNestedTemplateDir(ctx, fsys, alias, fname, tmpl)
+ } else {
+ err = parseNestedTemplate(ctx, fsys, alias, fname, tmpl)
+ }
+
+ if err != nil {
+ return err
}
}
- return tmpl, nil
+
+ return nil
+}
+
+func parseNestedTemplateDir(ctx context.Context, fsys fs.FS, alias, fname string, tmpl *template.Template) error {
+ files, err := fs.ReadDir(fsys, fname)
+ if err != nil {
+ return fmt.Errorf("readDir %q: %w", fname, err)
+ }
+
+ for _, f := range files {
+ if !f.IsDir() {
+ err = parseNestedTemplate(ctx, fsys,
+ path.Join(alias, f.Name()),
+ path.Join(fname, f.Name()),
+ tmpl,
+ )
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func parseNestedTemplate(ctx context.Context, fsys fs.FS, alias, fname string, tmpl *template.Template) error {
+ b, err := fs.ReadFile(fsys, fname)
+ if err != nil {
+ return fmt.Errorf("readFile %q: %w", fname, err)
+ }
+
+ _, err = tmpl.New(alias).Parse(string(b))
+ if err != nil {
+ return fmt.Errorf("parse nested template %q: %w", fname, err)
+ }
+
+ return nil
}
// loadContents - reads the template
func (t *tplate) loadContents(in io.Reader) ([]byte, error) {
if in == nil {
- f, err := fs.OpenFile(t.name, os.O_RDONLY, 0)
+ f, err := aferoFS.OpenFile(t.name, os.O_RDONLY, 0)
if err != nil {
return nil, fmt.Errorf("failed to open %s: %w", t.name, err)
}
@@ -153,14 +251,14 @@ func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(
func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer func(context.Context, string) (string, error), excludeGlob []string, mode os.FileMode, modeOverride bool) ([]*tplate, error) {
dir = filepath.Clean(dir)
- dirStat, err := fs.Stat(dir)
+ dirStat, err := aferoFS.Stat(dir)
if err != nil {
return nil, fmt.Errorf("couldn't stat %s: %w", dir, err)
}
dirMode := dirStat.Mode()
templates := make([]*tplate, 0)
- matcher := xignore.NewMatcher(fs)
+ matcher := xignore.NewMatcher(aferoFS)
// work around bug in xignore - a basedir of '.' doesn't work
basedir := dir
@@ -191,7 +289,7 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
}
// Ensure file parent dirs
- if err = fs.MkdirAll(filepath.Dir(outFile), dirMode); err != nil {
+ if err = aferoFS.MkdirAll(filepath.Dir(outFile), dirMode); err != nil {
return nil, err
}
@@ -213,7 +311,7 @@ func fileToTemplates(cfg *config.Config, inFile, outFile string, mode os.FileMod
source = string(b)
} else {
- si, err := fs.Stat(inFile)
+ si, err := aferoFS.Stat(inFile)
if err != nil {
return nil, err
}
@@ -223,7 +321,7 @@ func fileToTemplates(cfg *config.Config, inFile, outFile string, mode os.FileMod
// we read the file and store in memory immediately, to prevent leaking
// file descriptors.
- f, err := fs.OpenFile(inFile, os.O_RDONLY, 0)
+ f, err := aferoFS.OpenFile(inFile, os.O_RDONLY, 0)
if err != nil {
return nil, fmt.Errorf("failed to open %s: %w", inFile, err)
}
@@ -285,7 +383,7 @@ func openOutFile(filename string, dirMode, mode os.FileMode, modeOverride bool,
func createOutFile(filename string, dirMode, mode os.FileMode, modeOverride bool) (out io.WriteCloser, err error) {
mode = iohelpers.NormalizeFileMode(mode.Perm())
if modeOverride {
- err = fs.Chmod(filename, mode)
+ err = aferoFS.Chmod(filename, mode)
if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("failed to chmod output file '%s' with mode %q: %w", filename, mode, err)
}
@@ -293,11 +391,11 @@ func createOutFile(filename string, dirMode, mode os.FileMode, modeOverride bool
open := func() (out io.WriteCloser, err error) {
// Ensure file parent dirs
- if err = fs.MkdirAll(filepath.Dir(filename), dirMode); err != nil {
+ if err = aferoFS.MkdirAll(filepath.Dir(filename), dirMode); err != nil {
return nil, err
}
- out, err = fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
+ out, err = aferoFS.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
if err != nil {
return out, fmt.Errorf("failed to open output file '%s' for writing: %w", filename, err)
}
@@ -306,7 +404,7 @@ func createOutFile(filename string, dirMode, mode os.FileMode, modeOverride bool
}
// if the output file already exists, we'll use a SameSkipper
- fi, err := fs.Stat(filename)
+ fi, err := aferoFS.Stat(filename)
if err != nil {
// likely means the file just doesn't exist - further errors will be more useful
return iohelpers.LazyWriteCloser(open), nil
@@ -317,7 +415,7 @@ func createOutFile(filename string, dirMode, mode os.FileMode, modeOverride bool
}
out = iohelpers.SameSkipper(iohelpers.LazyReadCloser(func() (io.ReadCloser, error) {
- return fs.OpenFile(filename, os.O_RDONLY, mode)
+ return aferoFS.OpenFile(filename, os.O_RDONLY, mode)
}), open)
return out, err
diff --git a/template_test.go b/template_test.go
index fc730693..b5511fc2 100644
--- a/template_test.go
+++ b/template_test.go
@@ -4,9 +4,13 @@ import (
"bytes"
"context"
"io"
+ "net/url"
"os"
"testing"
+ "testing/fstest"
+ "text/template"
+ "github.com/hairyhenderson/go-fsimpl"
"github.com/hairyhenderson/gomplate/v3/internal/config"
"github.com/hairyhenderson/gomplate/v3/internal/iohelpers"
"github.com/spf13/afero"
@@ -16,10 +20,10 @@ import (
)
func TestOpenOutFile(t *testing.T) {
- origfs := fs
- defer func() { fs = origfs }()
- fs = afero.NewMemMapFs()
- _ = fs.Mkdir("/tmp", 0777)
+ origfs := aferoFS
+ defer func() { aferoFS = origfs }()
+ aferoFS = afero.NewMemMapFs()
+ _ = aferoFS.Mkdir("/tmp", 0777)
cfg := &config.Config{Stdout: &bytes.Buffer{}}
f, err := openOutFile("/tmp/foo", 0755, 0644, false, nil, false)
@@ -30,7 +34,7 @@ func TestOpenOutFile(t *testing.T) {
err = wc.Close()
assert.NoError(t, err)
- i, err := fs.Stat("/tmp/foo")
+ i, err := aferoFS.Stat("/tmp/foo")
assert.NoError(t, err)
assert.Equal(t, iohelpers.NormalizeFileMode(0644), i.Mode())
@@ -42,11 +46,11 @@ func TestOpenOutFile(t *testing.T) {
}
func TestLoadContents(t *testing.T) {
- origfs := fs
- defer func() { fs = origfs }()
- fs = afero.NewMemMapFs()
+ origfs := aferoFS
+ defer func() { aferoFS = origfs }()
+ aferoFS = afero.NewMemMapFs()
- afero.WriteFile(fs, "foo", []byte("contents"), 0644)
+ afero.WriteFile(aferoFS, "foo", []byte("contents"), 0644)
tmpl := &tplate{name: "foo"}
b, err := tmpl.loadContents(nil)
@@ -57,14 +61,14 @@ func TestLoadContents(t *testing.T) {
func TestGatherTemplates(t *testing.T) {
ctx := context.Background()
- origfs := fs
- defer func() { fs = origfs }()
- fs = afero.NewMemMapFs()
- afero.WriteFile(fs, "foo", []byte("bar"), 0600)
+ origfs := aferoFS
+ defer func() { aferoFS = origfs }()
+ aferoFS = afero.NewMemMapFs()
+ afero.WriteFile(aferoFS, "foo", []byte("bar"), 0600)
- afero.WriteFile(fs, "in/1", []byte("foo"), 0644)
- afero.WriteFile(fs, "in/2", []byte("bar"), 0644)
- afero.WriteFile(fs, "in/3", []byte("baz"), 0644)
+ afero.WriteFile(aferoFS, "in/1", []byte("foo"), 0644)
+ afero.WriteFile(aferoFS, "in/2", []byte("bar"), 0644)
+ afero.WriteFile(aferoFS, "in/3", []byte("baz"), 0644)
cfg := &config.Config{
Stdin: &bytes.Buffer{},
@@ -95,17 +99,17 @@ func TestGatherTemplates(t *testing.T) {
assert.Equal(t, iohelpers.NormalizeFileMode(0644), templates[0].mode)
// out file is created only on demand
- _, err = fs.Stat("out")
+ _, err = aferoFS.Stat("out")
assert.Error(t, err)
assert.True(t, os.IsNotExist(err))
_, err = templates[0].target.Write([]byte("hello world"))
assert.NoError(t, err)
- info, err := fs.Stat("out")
+ info, err := aferoFS.Stat("out")
require.NoError(t, err)
assert.Equal(t, iohelpers.NormalizeFileMode(0644), info.Mode())
- fs.Remove("out")
+ aferoFS.Remove("out")
cfg = &config.Config{
InputFiles: []string{"foo"},
@@ -122,10 +126,10 @@ func TestGatherTemplates(t *testing.T) {
_, err = templates[0].target.Write([]byte("hello world"))
assert.NoError(t, err)
- info, err = fs.Stat("out")
+ info, err = aferoFS.Stat("out")
assert.NoError(t, err)
assert.Equal(t, iohelpers.NormalizeFileMode(0600), info.Mode())
- fs.Remove("out")
+ aferoFS.Remove("out")
cfg = &config.Config{
InputFiles: []string{"foo"},
@@ -143,10 +147,10 @@ func TestGatherTemplates(t *testing.T) {
_, err = templates[0].target.Write([]byte("hello world"))
assert.NoError(t, err)
- info, err = fs.Stat("out")
+ info, err = aferoFS.Stat("out")
assert.NoError(t, err)
assert.Equal(t, iohelpers.NormalizeFileMode(0755), info.Mode())
- fs.Remove("out")
+ aferoFS.Remove("out")
templates, err = gatherTemplates(ctx, &config.Config{
InputDir: "in",
@@ -155,16 +159,58 @@ func TestGatherTemplates(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, templates, 3)
assert.Equal(t, "foo", templates[0].contents)
- fs.Remove("out")
+ aferoFS.Remove("out")
}
func TestCreateOutFile(t *testing.T) {
- origfs := fs
- defer func() { fs = origfs }()
- fs = afero.NewMemMapFs()
- _ = fs.Mkdir("in", 0755)
+ origfs := aferoFS
+ defer func() { aferoFS = origfs }()
+ aferoFS = afero.NewMemMapFs()
+ _ = aferoFS.Mkdir("in", 0755)
_, err := createOutFile("in", 0755, 0644, false)
assert.Error(t, err)
assert.IsType(t, &os.PathError{}, err)
}
+
+func TestParseNestedTemplates(t *testing.T) {
+ ctx := context.Background()
+
+ // in-memory test filesystem
+ fsys := fstest.MapFS{
+ "foo.t": {Data: []byte("hello world"), Mode: 0o600},
+ }
+ fsp := fsimpl.WrappedFSProvider(fsys, "file")
+ ctx = ContextWithFSProvider(ctx, fsp)
+
+ // simple test with single template
+ u, _ := url.Parse("file:///foo.t")
+ nested := config.Templates{"foo": {URL: u}}
+
+ tmpl, _ := template.New("root").Parse(`{{ template "foo" }}`)
+
+ err := parseNestedTemplates(ctx, nested, tmpl)
+ assert.NoError(t, err)
+
+ out := bytes.Buffer{}
+ err = tmpl.Execute(&out, nil)
+ assert.NoError(t, err)
+ assert.Equal(t, "hello world", out.String())
+
+ // test with directory of templates
+ fsys["dir/foo.t"] = &fstest.MapFile{Data: []byte("foo"), Mode: 0o600}
+ fsys["dir/bar.t"] = &fstest.MapFile{Data: []byte("bar"), Mode: 0o600}
+
+ u, _ = url.Parse("file:///dir/")
+ nested["dir"] = config.DataSource{URL: u}
+
+ tmpl, _ = template.New("root").Parse(`{{ template "dir/foo.t" }} {{ template "dir/bar.t" }}`)
+
+ err = parseNestedTemplates(ctx, nested, tmpl)
+ assert.NoError(t, err)
+
+ out = bytes.Buffer{}
+ err = tmpl.Execute(&out, nil)
+ assert.NoError(t, err)
+ assert.Equal(t, "foo bar", out.String())
+}
diff --git a/template_unix_test.go b/template_unix_test.go
index 2cfce793..94e3e206 100644
--- a/template_unix_test.go
+++ b/template_unix_test.go
@@ -14,20 +14,20 @@ import (
func TestWalkDir(t *testing.T) {
ctx := context.Background()
- origfs := fs
- defer func() { fs = origfs }()
- fs = afero.NewMemMapFs()
+ origfs := aferoFS
+ defer func() { aferoFS = origfs }()
+ aferoFS = afero.NewMemMapFs()
cfg := &config.Config{}
_, err := walkDir(ctx, cfg, "/indir", simpleNamer("/outdir"), nil, 0, false)
assert.Error(t, err)
- _ = fs.MkdirAll("/indir/one", 0777)
- _ = fs.MkdirAll("/indir/two", 0777)
- afero.WriteFile(fs, "/indir/one/foo", []byte("foo"), 0644)
- afero.WriteFile(fs, "/indir/one/bar", []byte("bar"), 0664)
- afero.WriteFile(fs, "/indir/two/baz", []byte("baz"), 0644)
+ _ = aferoFS.MkdirAll("/indir/one", 0777)
+ _ = aferoFS.MkdirAll("/indir/two", 0777)
+ afero.WriteFile(aferoFS, "/indir/one/foo", []byte("foo"), 0644)
+ afero.WriteFile(aferoFS, "/indir/one/bar", []byte("bar"), 0664)
+ afero.WriteFile(aferoFS, "/indir/two/baz", []byte("baz"), 0644)
templates, err := walkDir(ctx, cfg, "/indir", simpleNamer("/outdir"), []string{"*/two"}, 0, false)
diff --git a/template_windows_test.go b/template_windows_test.go
index 3990aa9f..00374e2c 100644
--- a/template_windows_test.go
+++ b/template_windows_test.go
@@ -14,20 +14,20 @@ import (
func TestWalkDir(t *testing.T) {
ctx := context.Background()
- origfs := fs
- defer func() { fs = origfs }()
- fs = afero.NewMemMapFs()
+ origfs := aferoFS
+ defer func() { aferoFS = origfs }()
+ aferoFS = afero.NewMemMapFs()
cfg := &config.Config{}
_, err := walkDir(ctx, cfg, `C:\indir`, simpleNamer(`C:\outdir`), nil, 0, false)
assert.Error(t, err)
- _ = fs.MkdirAll(`C:\indir\one`, 0777)
- _ = fs.MkdirAll(`C:\indir\two`, 0777)
- afero.WriteFile(fs, `C:\indir\one\foo`, []byte("foo"), 0644)
- afero.WriteFile(fs, `C:\indir\one\bar`, []byte("bar"), 0644)
- afero.WriteFile(fs, `C:\indir\two\baz`, []byte("baz"), 0644)
+ _ = aferoFS.MkdirAll(`C:\indir\one`, 0777)
+ _ = aferoFS.MkdirAll(`C:\indir\two`, 0777)
+ afero.WriteFile(aferoFS, `C:\indir\one\foo`, []byte("foo"), 0644)
+ afero.WriteFile(aferoFS, `C:\indir\one\bar`, []byte("bar"), 0644)
+ afero.WriteFile(aferoFS, `C:\indir\two\baz`, []byte("baz"), 0644)
templates, err := walkDir(ctx, cfg, `C:\indir`, simpleNamer(`C:\outdir`), []string{`*\two`}, 0, false)