mirror of
https://github.com/Luzifer/vault-openvpn.git
synced 2024-12-26 06:41:20 +00:00
Switch to dep from Godeps
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
06cdbefd48
commit
b4cc42902e
1627 changed files with 381966 additions and 16003 deletions
163
Godeps/Godeps.json
generated
163
Godeps/Godeps.json
generated
|
@ -1,163 +0,0 @@
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Luzifer/vault-openvpn",
|
|
||||||
"GoVersion": "go1.8",
|
|
||||||
"GodepVersion": "v79",
|
|
||||||
"Deps": [
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Luzifer/rconfig",
|
|
||||||
"Comment": "v1.1.0",
|
|
||||||
"Rev": "c27bd3a64b5b19556914d9fec69922cf3852d585"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Sirupsen/logrus",
|
|
||||||
"Comment": "v0.10.0-38-g3ec0642",
|
|
||||||
"Rev": "3ec0642a7fb6488f65b06f9040adc67e3990296a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/fatih/structs",
|
|
||||||
"Rev": "3fe2facc32a7fbde4b29c0f85604dc1dd22836d2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/errwrap",
|
|
||||||
"Rev": "7554cd9344cec97297fa6649b055a8c98c2a1e55"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/go-cleanhttp",
|
|
||||||
"Rev": "ad28ea4487f05916463e2423a55166280e8254b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/go-multierror",
|
|
||||||
"Rev": "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/go-rootcerts",
|
|
||||||
"Rev": "6bb64b370b90e7ef1fa532be9e591a81c3493e00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/hcl/ast",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/hcl/parser",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/hcl/scanner",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/hcl/strconv",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/hcl/token",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/json/parser",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/json/scanner",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/hcl/json/token",
|
|
||||||
"Rev": "ef8133da8cda503718a74741312bf50821e6de79"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/vault/api",
|
|
||||||
"Comment": "v0.7.0-190-g4490e93",
|
|
||||||
"Rev": "4490e93395fb70c3a25ade1fe88f363561a7d584"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/vault/helper/certutil",
|
|
||||||
"Comment": "v0.7.0-190-g4490e93",
|
|
||||||
"Rev": "4490e93395fb70c3a25ade1fe88f363561a7d584"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/vault/helper/compressutil",
|
|
||||||
"Comment": "v0.7.0-190-g4490e93",
|
|
||||||
"Rev": "4490e93395fb70c3a25ade1fe88f363561a7d584"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/vault/helper/errutil",
|
|
||||||
"Comment": "v0.7.0-190-g4490e93",
|
|
||||||
"Rev": "4490e93395fb70c3a25ade1fe88f363561a7d584"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/vault/helper/jsonutil",
|
|
||||||
"Comment": "v0.7.0-190-g4490e93",
|
|
||||||
"Rev": "4490e93395fb70c3a25ade1fe88f363561a7d584"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-runewidth",
|
|
||||||
"Comment": "v0.0.2-1-g14207d2",
|
|
||||||
"Rev": "14207d285c6c197daabb5c9793d63e7af9ab2d50"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mitchellh/go-homedir",
|
|
||||||
"Rev": "981ab348d865cf048eb7d17e78ac7192632d8415"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mitchellh/mapstructure",
|
|
||||||
"Rev": "ca63d7c062ee3c9f34db231e352b60012b4fd0c1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/olekukonko/tablewriter",
|
|
||||||
"Rev": "febf2d34b54a69ce7530036c7503b1c9fbfdf0bb"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/sethgrid/pester",
|
|
||||||
"Rev": "4f4c0a67b6496764028e1ab9fd8dfb630282ed2f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/spf13/pflag",
|
|
||||||
"Rev": "c7e63cf4530bcd3ba943729cee0efeff2ebea63f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/http2",
|
|
||||||
"Rev": "f09c4662a0bd6bd8943ac7b4931e185df9471da4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/http2/hpack",
|
|
||||||
"Rev": "f09c4662a0bd6bd8943ac7b4931e185df9471da4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/idna",
|
|
||||||
"Rev": "f09c4662a0bd6bd8943ac7b4931e185df9471da4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/lex/httplex",
|
|
||||||
"Rev": "f09c4662a0bd6bd8943ac7b4931e185df9471da4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/sys/unix",
|
|
||||||
"Rev": "8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/secure/bidirule",
|
|
||||||
"Rev": "2df9074612f50810d82416d2229398a1e7188c5c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
|
||||||
"Rev": "2df9074612f50810d82416d2229398a1e7188c5c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/unicode/bidi",
|
|
||||||
"Rev": "2df9074612f50810d82416d2229398a1e7188c5c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/unicode/norm",
|
|
||||||
"Rev": "2df9074612f50810d82416d2229398a1e7188c5c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/yaml.v2",
|
|
||||||
"Rev": "31c299268d302dd0aa9a0dcf765a3d58971ac83f"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
5
Godeps/Readme
generated
5
Godeps/Readme
generated
|
@ -1,5 +0,0 @@
|
||||||
This directory tree is generated automatically by godep.
|
|
||||||
|
|
||||||
Please do not edit.
|
|
||||||
|
|
||||||
See https://github.com/tools/godep for more information.
|
|
102
Gopkg.lock
generated
Normal file
102
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/Luzifer/rconfig"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "c27bd3a64b5b19556914d9fec69922cf3852d585"
|
||||||
|
version = "v1.1.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/Sirupsen/logrus"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "3ec0642a7fb6488f65b06f9040adc67e3990296a"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/fatih/structs"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "3fe2facc32a7fbde4b29c0f85604dc1dd22836d2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/hashicorp/errwrap"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "7554cd9344cec97297fa6649b055a8c98c2a1e55"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/hashicorp/go-cleanhttp"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "ad28ea4487f05916463e2423a55166280e8254b5"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/hashicorp/go-multierror"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/hashicorp/go-rootcerts"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/hashicorp/hcl"
|
||||||
|
packages = [".","hcl/ast","hcl/parser","hcl/scanner","hcl/strconv","hcl/token","json/parser","json/scanner","json/token"]
|
||||||
|
revision = "ef8133da8cda503718a74741312bf50821e6de79"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/hashicorp/vault"
|
||||||
|
packages = ["api","helper/certutil","helper/compressutil","helper/errutil","helper/jsonutil"]
|
||||||
|
revision = "4490e93395fb70c3a25ade1fe88f363561a7d584"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/mattn/go-runewidth"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "14207d285c6c197daabb5c9793d63e7af9ab2d50"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/mitchellh/go-homedir"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "981ab348d865cf048eb7d17e78ac7192632d8415"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/mitchellh/mapstructure"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "ca63d7c062ee3c9f34db231e352b60012b4fd0c1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/olekukonko/tablewriter"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "febf2d34b54a69ce7530036c7503b1c9fbfdf0bb"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/sethgrid/pester"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "4f4c0a67b6496764028e1ab9fd8dfb630282ed2f"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/spf13/pflag"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "c7e63cf4530bcd3ba943729cee0efeff2ebea63f"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "golang.org/x/net"
|
||||||
|
packages = ["http2","http2/hpack","idna","lex/httplex"]
|
||||||
|
revision = "f09c4662a0bd6bd8943ac7b4931e185df9471da4"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "golang.org/x/sys"
|
||||||
|
packages = ["unix"]
|
||||||
|
revision = "8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/yaml.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "31c299268d302dd0aa9a0dcf765a3d58971ac83f"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "338132dcce86eed0dc26d5c2a448092d59a299761c47da97aed0c6e98e8c355d"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
41
Gopkg.toml
Normal file
41
Gopkg.toml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/Luzifer/rconfig"
|
||||||
|
version = "1.1.0"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/Sirupsen/logrus"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/hashicorp/vault"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/mitchellh/go-homedir"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/olekukonko/tablewriter"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "gopkg.in/yaml.v2"
|
70
vendor/github.com/Luzifer/rconfig/bool_test.go
generated
vendored
Normal file
70
vendor/github.com/Luzifer/rconfig/bool_test.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing bool parsing", func() {
|
||||||
|
type t struct {
|
||||||
|
Test1 bool `default:"true"`
|
||||||
|
Test2 bool `default:"false" flag:"test2"`
|
||||||
|
Test3 bool `default:"true" flag:"test3,t"`
|
||||||
|
Test4 bool `flag:"test4"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--test2",
|
||||||
|
"-t",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test1).To(Equal(true))
|
||||||
|
Expect(cfg.Test2).To(Equal(true))
|
||||||
|
Expect(cfg.Test3).To(Equal(true))
|
||||||
|
Expect(cfg.Test4).To(Equal(false))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var _ = Describe("Testing to set bool from ENV with default", func() {
|
||||||
|
type t struct {
|
||||||
|
Test1 bool `default:"true" env:"TEST1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
os.Unsetenv("TEST1")
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test1).To(Equal(true))
|
||||||
|
})
|
||||||
|
})
|
41
vendor/github.com/Luzifer/rconfig/duration_test.go
generated
vendored
Normal file
41
vendor/github.com/Luzifer/rconfig/duration_test.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Duration", func() {
|
||||||
|
type t struct {
|
||||||
|
Test time.Duration `flag:"duration"`
|
||||||
|
TestS time.Duration `flag:"other-duration,o"`
|
||||||
|
TestDef time.Duration `default:"30h"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--duration=23s", "-o", "45m",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test).To(Equal(23 * time.Second))
|
||||||
|
Expect(cfg.TestS).To(Equal(45 * time.Minute))
|
||||||
|
|
||||||
|
Expect(cfg.TestDef).To(Equal(30 * time.Hour))
|
||||||
|
})
|
||||||
|
})
|
56
vendor/github.com/Luzifer/rconfig/errors_test.go
generated
vendored
Normal file
56
vendor/github.com/Luzifer/rconfig/errors_test.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing errors", func() {
|
||||||
|
|
||||||
|
It("should not accept string as int", func() {
|
||||||
|
Expect(parse(&struct {
|
||||||
|
A int `default:"a"`
|
||||||
|
}{}, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not accept string as float", func() {
|
||||||
|
Expect(parse(&struct {
|
||||||
|
A float32 `default:"a"`
|
||||||
|
}{}, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not accept string as uint", func() {
|
||||||
|
Expect(parse(&struct {
|
||||||
|
A uint `default:"a"`
|
||||||
|
}{}, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not accept string as uint in sub-struct", func() {
|
||||||
|
Expect(parse(&struct {
|
||||||
|
B struct {
|
||||||
|
A uint `default:"a"`
|
||||||
|
}
|
||||||
|
}{}, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not accept string slice as int slice", func() {
|
||||||
|
Expect(parse(&struct {
|
||||||
|
A []int `default:"a,bn"`
|
||||||
|
}{}, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not accept variables not being pointers", func() {
|
||||||
|
cfg := struct {
|
||||||
|
A string `default:"a"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
Expect(parse(cfg, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not accept variables not being pointers to structs", func() {
|
||||||
|
cfg := "test"
|
||||||
|
|
||||||
|
Expect(parse(cfg, []string{})).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
37
vendor/github.com/Luzifer/rconfig/example_test.go
generated
vendored
Normal file
37
vendor/github.com/Luzifer/rconfig/example_test.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleParse() {
|
||||||
|
// We're building an example configuration with a sub-struct to be filled
|
||||||
|
// by the Parse command.
|
||||||
|
config := struct {
|
||||||
|
Username string `default:"unknown" flag:"user,u" description:"Your name"`
|
||||||
|
Details struct {
|
||||||
|
Age int `default:"25" flag:"age" description:"Your age"`
|
||||||
|
}
|
||||||
|
}{}
|
||||||
|
|
||||||
|
// To have more relieable results we're setting os.Args to a known value.
|
||||||
|
// In real-life use cases you wouldn't do this but parse the original
|
||||||
|
// commandline arguments.
|
||||||
|
os.Args = []string{
|
||||||
|
"example",
|
||||||
|
"--user=Luzifer",
|
||||||
|
}
|
||||||
|
|
||||||
|
Parse(&config)
|
||||||
|
|
||||||
|
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
||||||
|
config.Username,
|
||||||
|
config.Details.Age)
|
||||||
|
|
||||||
|
// You can also show an usage message for your user
|
||||||
|
Usage()
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Hello Luzifer, happy birthday for your 25th birthday.
|
||||||
|
}
|
44
vendor/github.com/Luzifer/rconfig/float_test.go
generated
vendored
Normal file
44
vendor/github.com/Luzifer/rconfig/float_test.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing float parsing", func() {
|
||||||
|
type t struct {
|
||||||
|
Test32 float32 `flag:"float32"`
|
||||||
|
Test32P float32 `flag:"float32p,3"`
|
||||||
|
Test64 float64 `flag:"float64"`
|
||||||
|
Test64P float64 `flag:"float64p,6"`
|
||||||
|
TestDef float32 `default:"66.256"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--float32=5.5", "-3", "6.6",
|
||||||
|
"--float64=7.7", "-6", "8.8",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test32).To(Equal(float32(5.5)))
|
||||||
|
Expect(cfg.Test32P).To(Equal(float32(6.6)))
|
||||||
|
Expect(cfg.Test64).To(Equal(float64(7.7)))
|
||||||
|
Expect(cfg.Test64P).To(Equal(float64(8.8)))
|
||||||
|
|
||||||
|
Expect(cfg.TestDef).To(Equal(float32(66.256)))
|
||||||
|
})
|
||||||
|
})
|
109
vendor/github.com/Luzifer/rconfig/general_test.go
generated
vendored
Normal file
109
vendor/github.com/Luzifer/rconfig/general_test.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing general parsing", func() {
|
||||||
|
type t struct {
|
||||||
|
Test string `default:"foo" env:"shell" flag:"shell" description:"Test"`
|
||||||
|
Test2 string `default:"blub" env:"testvar" flag:"testvar,t" description:"Test"`
|
||||||
|
DefaultFlag string `default:"goo"`
|
||||||
|
SadFlag string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
Context("with defined arguments", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--shell=test23",
|
||||||
|
"-t", "bla",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have parsed the expected values", func() {
|
||||||
|
Expect(cfg.Test).To(Equal("test23"))
|
||||||
|
Expect(cfg.Test2).To(Equal("bla"))
|
||||||
|
Expect(cfg.SadFlag).To(Equal(""))
|
||||||
|
Expect(cfg.DefaultFlag).To(Equal("goo"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with no arguments", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have used the default value", func() {
|
||||||
|
Expect(cfg.Test).To(Equal("foo"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with no arguments and set env", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{}
|
||||||
|
os.Setenv("shell", "test546")
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
os.Unsetenv("shell")
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have used the value from env", func() {
|
||||||
|
Expect(cfg.Test).To(Equal("test546"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with additional arguments", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--shell=test23",
|
||||||
|
"-t", "bla",
|
||||||
|
"positional1", "positional2",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have parsed the expected values", func() {
|
||||||
|
Expect(cfg.Test).To(Equal("test23"))
|
||||||
|
Expect(cfg.Test2).To(Equal("bla"))
|
||||||
|
Expect(cfg.SadFlag).To(Equal(""))
|
||||||
|
Expect(cfg.DefaultFlag).To(Equal("goo"))
|
||||||
|
})
|
||||||
|
It("should have detected the positional arguments", func() {
|
||||||
|
Expect(Args()).To(Equal([]string{"positional1", "positional2"}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
54
vendor/github.com/Luzifer/rconfig/int_test.go
generated
vendored
Normal file
54
vendor/github.com/Luzifer/rconfig/int_test.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing int parsing", func() {
|
||||||
|
type t struct {
|
||||||
|
Test int `flag:"int"`
|
||||||
|
TestP int `flag:"intp,i"`
|
||||||
|
Test8 int8 `flag:"int8"`
|
||||||
|
Test8P int8 `flag:"int8p,8"`
|
||||||
|
Test32 int32 `flag:"int32"`
|
||||||
|
Test32P int32 `flag:"int32p,3"`
|
||||||
|
Test64 int64 `flag:"int64"`
|
||||||
|
Test64P int64 `flag:"int64p,6"`
|
||||||
|
TestDef int8 `default:"66"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--int=1", "-i", "2",
|
||||||
|
"--int8=3", "-8", "4",
|
||||||
|
"--int32=5", "-3", "6",
|
||||||
|
"--int64=7", "-6", "8",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test).To(Equal(1))
|
||||||
|
Expect(cfg.TestP).To(Equal(2))
|
||||||
|
Expect(cfg.Test8).To(Equal(int8(3)))
|
||||||
|
Expect(cfg.Test8P).To(Equal(int8(4)))
|
||||||
|
Expect(cfg.Test32).To(Equal(int32(5)))
|
||||||
|
Expect(cfg.Test32P).To(Equal(int32(6)))
|
||||||
|
Expect(cfg.Test64).To(Equal(int64(7)))
|
||||||
|
Expect(cfg.Test64P).To(Equal(int64(8)))
|
||||||
|
|
||||||
|
Expect(cfg.TestDef).To(Equal(int8(66)))
|
||||||
|
})
|
||||||
|
})
|
40
vendor/github.com/Luzifer/rconfig/os-args_test.go
generated
vendored
Normal file
40
vendor/github.com/Luzifer/rconfig/os-args_test.go
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package rconfig_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/Luzifer/rconfig"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing os.Args", func() {
|
||||||
|
type t struct {
|
||||||
|
A string `default:"a" flag:"a"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = Parse(&cfg)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("With only valid arguments", func() {
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
os.Args = []string{"--a=bar"}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.A).To(Equal("bar"))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
87
vendor/github.com/Luzifer/rconfig/precedence_test.go
generated
vendored
Normal file
87
vendor/github.com/Luzifer/rconfig/precedence_test.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Precedence", func() {
|
||||||
|
|
||||||
|
type t struct {
|
||||||
|
A int `default:"1" vardefault:"a" env:"a" flag:"avar,a" description:"a"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
cfg t
|
||||||
|
args []string
|
||||||
|
vardefaults map[string]string
|
||||||
|
)
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
SetVariableDefaults(vardefaults)
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("Provided: Flag, Env, Default, VarDefault", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
args = []string{"-a", "5"}
|
||||||
|
os.Setenv("a", "8")
|
||||||
|
vardefaults = map[string]string{
|
||||||
|
"a": "3",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have used the flag value", func() {
|
||||||
|
Expect(cfg.A).To(Equal(5))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("Provided: Env, Default, VarDefault", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
args = []string{}
|
||||||
|
os.Setenv("a", "8")
|
||||||
|
vardefaults = map[string]string{
|
||||||
|
"a": "3",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have used the env value", func() {
|
||||||
|
Expect(cfg.A).To(Equal(8))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("Provided: Default, VarDefault", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
args = []string{}
|
||||||
|
os.Unsetenv("a")
|
||||||
|
vardefaults = map[string]string{
|
||||||
|
"a": "3",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have used the vardefault value", func() {
|
||||||
|
Expect(cfg.A).To(Equal(3))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("Provided: Default", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
args = []string{}
|
||||||
|
os.Unsetenv("a")
|
||||||
|
vardefaults = map[string]string{}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have used the default value", func() {
|
||||||
|
Expect(cfg.A).To(Equal(1))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
13
vendor/github.com/Luzifer/rconfig/rconfig_suite_test.go
generated
vendored
Normal file
13
vendor/github.com/Luzifer/rconfig/rconfig_suite_test.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package rconfig_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRconfig(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "Rconfig Suite")
|
||||||
|
}
|
51
vendor/github.com/Luzifer/rconfig/slice_test.go
generated
vendored
Normal file
51
vendor/github.com/Luzifer/rconfig/slice_test.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing slices", func() {
|
||||||
|
type t struct {
|
||||||
|
Int []int `default:"1,2,3" flag:"int"`
|
||||||
|
String []string `default:"a,b,c" flag:"string"`
|
||||||
|
IntP []int `default:"1,2,3" flag:"intp,i"`
|
||||||
|
StringP []string `default:"a,b,c" flag:"stringp,s"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--int=4,5", "-s", "hallo,welt",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values for int-slice", func() {
|
||||||
|
Expect(len(cfg.Int)).To(Equal(2))
|
||||||
|
Expect(cfg.Int).To(Equal([]int{4, 5}))
|
||||||
|
Expect(cfg.Int).NotTo(Equal([]int{5, 4}))
|
||||||
|
})
|
||||||
|
It("should have the expected values for int-shorthand-slice", func() {
|
||||||
|
Expect(len(cfg.IntP)).To(Equal(3))
|
||||||
|
Expect(cfg.IntP).To(Equal([]int{1, 2, 3}))
|
||||||
|
})
|
||||||
|
It("should have the expected values for string-slice", func() {
|
||||||
|
Expect(len(cfg.String)).To(Equal(3))
|
||||||
|
Expect(cfg.String).To(Equal([]string{"a", "b", "c"}))
|
||||||
|
})
|
||||||
|
It("should have the expected values for string-shorthand-slice", func() {
|
||||||
|
Expect(len(cfg.StringP)).To(Equal(2))
|
||||||
|
Expect(cfg.StringP).To(Equal([]string{"hallo", "welt"}))
|
||||||
|
})
|
||||||
|
})
|
36
vendor/github.com/Luzifer/rconfig/sub-struct_test.go
generated
vendored
Normal file
36
vendor/github.com/Luzifer/rconfig/sub-struct_test.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing sub-structs", func() {
|
||||||
|
type t struct {
|
||||||
|
Test string `default:"blubb"`
|
||||||
|
Sub struct {
|
||||||
|
Test string `default:"Hallo"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test).To(Equal("blubb"))
|
||||||
|
Expect(cfg.Sub.Test).To(Equal("Hallo"))
|
||||||
|
})
|
||||||
|
})
|
59
vendor/github.com/Luzifer/rconfig/uint_test.go
generated
vendored
Normal file
59
vendor/github.com/Luzifer/rconfig/uint_test.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing uint parsing", func() {
|
||||||
|
type t struct {
|
||||||
|
Test uint `flag:"int"`
|
||||||
|
TestP uint `flag:"intp,i"`
|
||||||
|
Test8 uint8 `flag:"int8"`
|
||||||
|
Test8P uint8 `flag:"int8p,8"`
|
||||||
|
Test16 uint16 `flag:"int16"`
|
||||||
|
Test16P uint16 `flag:"int16p,1"`
|
||||||
|
Test32 uint32 `flag:"int32"`
|
||||||
|
Test32P uint32 `flag:"int32p,3"`
|
||||||
|
Test64 uint64 `flag:"int64"`
|
||||||
|
Test64P uint64 `flag:"int64p,6"`
|
||||||
|
TestDef uint8 `default:"66"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
args []string
|
||||||
|
cfg t
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
args = []string{
|
||||||
|
"--int=1", "-i", "2",
|
||||||
|
"--int8=3", "-8", "4",
|
||||||
|
"--int32=5", "-3", "6",
|
||||||
|
"--int64=7", "-6", "8",
|
||||||
|
"--int16=9", "-1", "10",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.Test).To(Equal(uint(1)))
|
||||||
|
Expect(cfg.TestP).To(Equal(uint(2)))
|
||||||
|
Expect(cfg.Test8).To(Equal(uint8(3)))
|
||||||
|
Expect(cfg.Test8P).To(Equal(uint8(4)))
|
||||||
|
Expect(cfg.Test32).To(Equal(uint32(5)))
|
||||||
|
Expect(cfg.Test32P).To(Equal(uint32(6)))
|
||||||
|
Expect(cfg.Test64).To(Equal(uint64(7)))
|
||||||
|
Expect(cfg.Test64P).To(Equal(uint64(8)))
|
||||||
|
Expect(cfg.Test16).To(Equal(uint16(9)))
|
||||||
|
Expect(cfg.Test16P).To(Equal(uint16(10)))
|
||||||
|
|
||||||
|
Expect(cfg.TestDef).To(Equal(uint8(66)))
|
||||||
|
})
|
||||||
|
})
|
122
vendor/github.com/Luzifer/rconfig/vardefault_test.go
generated
vendored
Normal file
122
vendor/github.com/Luzifer/rconfig/vardefault_test.go
generated
vendored
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
package rconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Testing variable defaults", func() {
|
||||||
|
|
||||||
|
type t struct {
|
||||||
|
MySecretValue string `default:"secret" env:"foo" vardefault:"my_secret_value"`
|
||||||
|
MyUsername string `default:"luzifer" vardefault:"username"`
|
||||||
|
SomeVar string `flag:"var" description:"some variable"`
|
||||||
|
IntVar int64 `vardefault:"int_var" default:"23"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
cfg t
|
||||||
|
args = []string{}
|
||||||
|
vardefaults = map[string]string{
|
||||||
|
"my_secret_value": "veryverysecretkey",
|
||||||
|
"unkownkey": "hi there",
|
||||||
|
"int_var": "42",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cfg = t{}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
err = parse(&cfg, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("With manually provided variables", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
SetVariableDefaults(vardefaults)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.IntVar).To(Equal(int64(42)))
|
||||||
|
Expect(cfg.MySecretValue).To(Equal("veryverysecretkey"))
|
||||||
|
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||||
|
Expect(cfg.SomeVar).To(Equal(""))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("With defaults from YAML data", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
yamlData := []byte("---\nmy_secret_value: veryverysecretkey\nunknownkey: hi there\nint_var: 42\n")
|
||||||
|
SetVariableDefaults(VarDefaultsFromYAML(yamlData))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.IntVar).To(Equal(int64(42)))
|
||||||
|
Expect(cfg.MySecretValue).To(Equal("veryverysecretkey"))
|
||||||
|
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||||
|
Expect(cfg.SomeVar).To(Equal(""))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("With defaults from YAML file", func() {
|
||||||
|
var tmp *os.File
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
tmp, _ = ioutil.TempFile("", "")
|
||||||
|
yamlData := "---\nmy_secret_value: veryverysecretkey\nunknownkey: hi there\nint_var: 42\n"
|
||||||
|
tmp.WriteString(yamlData)
|
||||||
|
SetVariableDefaults(VarDefaultsFromYAMLFile(tmp.Name()))
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
tmp.Close()
|
||||||
|
os.Remove(tmp.Name())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.IntVar).To(Equal(int64(42)))
|
||||||
|
Expect(cfg.MySecretValue).To(Equal("veryverysecretkey"))
|
||||||
|
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||||
|
Expect(cfg.SomeVar).To(Equal(""))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("With defaults from invalid YAML data", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
yamlData := []byte("---\nmy_secret_value = veryverysecretkey\nunknownkey = hi there\nint_var = 42\n")
|
||||||
|
SetVariableDefaults(VarDefaultsFromYAML(yamlData))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.IntVar).To(Equal(int64(23)))
|
||||||
|
Expect(cfg.MySecretValue).To(Equal("secret"))
|
||||||
|
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||||
|
Expect(cfg.SomeVar).To(Equal(""))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("With defaults from non existent YAML file", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
file := "/tmp/this_file_should_not_exist_146e26723r"
|
||||||
|
SetVariableDefaults(VarDefaultsFromYAMLFile(file))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||||
|
It("should have the expected values", func() {
|
||||||
|
Expect(cfg.IntVar).To(Equal(int64(23)))
|
||||||
|
Expect(cfg.MySecretValue).To(Equal("secret"))
|
||||||
|
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||||
|
Expect(cfg.SomeVar).To(Equal(""))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
74
vendor/github.com/Sirupsen/logrus/alt_exit_test.go
generated
vendored
Normal file
74
vendor/github.com/Sirupsen/logrus/alt_exit_test.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRegister(t *testing.T) {
|
||||||
|
current := len(handlers)
|
||||||
|
RegisterExitHandler(func() {})
|
||||||
|
if len(handlers) != current+1 {
|
||||||
|
t.Fatalf("can't add handler")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandler(t *testing.T) {
|
||||||
|
gofile := "/tmp/testprog.go"
|
||||||
|
if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
|
||||||
|
t.Fatalf("can't create go file")
|
||||||
|
}
|
||||||
|
|
||||||
|
outfile := "/tmp/testprog.out"
|
||||||
|
arg := time.Now().UTC().String()
|
||||||
|
err := exec.Command("go", "run", gofile, outfile, arg).Run()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("completed normally, should have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(outfile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("can't read output file %s", outfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(data) != arg {
|
||||||
|
t.Fatalf("bad data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testprog = []byte(`
|
||||||
|
// Test program for atexit, gets output file and data as arguments and writes
|
||||||
|
// data to output file in atexit handler.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
var outfile = ""
|
||||||
|
var data = ""
|
||||||
|
|
||||||
|
func handler() {
|
||||||
|
ioutil.WriteFile(outfile, []byte(data), 0666)
|
||||||
|
}
|
||||||
|
|
||||||
|
func badHandler() {
|
||||||
|
n := 0
|
||||||
|
fmt.Println(1/n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
outfile = flag.Arg(0)
|
||||||
|
data = flag.Arg(1)
|
||||||
|
|
||||||
|
logrus.RegisterExitHandler(handler)
|
||||||
|
logrus.RegisterExitHandler(badHandler)
|
||||||
|
logrus.Fatal("Bye bye")
|
||||||
|
}
|
||||||
|
`)
|
77
vendor/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
Normal file
77
vendor/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEntryWithError(t *testing.T) {
|
||||||
|
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
ErrorKey = "error"
|
||||||
|
}()
|
||||||
|
|
||||||
|
err := fmt.Errorf("kaboom at layer %d", 4711)
|
||||||
|
|
||||||
|
assert.Equal(err, WithError(err).Data["error"])
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &bytes.Buffer{}
|
||||||
|
entry := NewEntry(logger)
|
||||||
|
|
||||||
|
assert.Equal(err, entry.WithError(err).Data["error"])
|
||||||
|
|
||||||
|
ErrorKey = "err"
|
||||||
|
|
||||||
|
assert.Equal(err, entry.WithError(err).Data["err"])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEntryPanicln(t *testing.T) {
|
||||||
|
errBoom := fmt.Errorf("boom time")
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
p := recover()
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
|
||||||
|
switch pVal := p.(type) {
|
||||||
|
case *Entry:
|
||||||
|
assert.Equal(t, "kaboom", pVal.Message)
|
||||||
|
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||||
|
default:
|
||||||
|
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &bytes.Buffer{}
|
||||||
|
entry := NewEntry(logger)
|
||||||
|
entry.WithField("err", errBoom).Panicln("kaboom")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEntryPanicf(t *testing.T) {
|
||||||
|
errBoom := fmt.Errorf("boom again")
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
p := recover()
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
|
||||||
|
switch pVal := p.(type) {
|
||||||
|
case *Entry:
|
||||||
|
assert.Equal(t, "kaboom true", pVal.Message)
|
||||||
|
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||||
|
default:
|
||||||
|
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &bytes.Buffer{}
|
||||||
|
entry := NewEntry(logger)
|
||||||
|
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
|
||||||
|
}
|
50
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
Normal file
50
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logrus.New()
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.Formatter = new(logrus.JSONFormatter)
|
||||||
|
log.Formatter = new(logrus.TextFormatter) // default
|
||||||
|
log.Level = logrus.DebugLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"err": err,
|
||||||
|
"number": 100,
|
||||||
|
}).Fatal("The ice breaks!")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "walrus",
|
||||||
|
"number": 8,
|
||||||
|
}).Debug("Started observing beach")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "walrus",
|
||||||
|
"size": 10,
|
||||||
|
}).Info("A group of walrus emerges from the ocean")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"number": 122,
|
||||||
|
}).Warn("The group's number increased tremendously!")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"temperature": -4,
|
||||||
|
}).Debug("Temperature changes")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "orca",
|
||||||
|
"size": 9009,
|
||||||
|
}).Panic("It's over 9000!")
|
||||||
|
}
|
30
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
Normal file
30
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logrus.New()
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.Formatter = new(logrus.TextFormatter) // default
|
||||||
|
log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "walrus",
|
||||||
|
"size": 10,
|
||||||
|
}).Info("A group of walrus emerges from the ocean")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"number": 122,
|
||||||
|
}).Warn("The group's number increased tremendously!")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"number": 100,
|
||||||
|
}).Fatal("The ice breaks!")
|
||||||
|
}
|
98
vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
Normal file
98
vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// smallFields is a small size data set for benchmarking
|
||||||
|
var smallFields = Fields{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": "qux",
|
||||||
|
"one": "two",
|
||||||
|
"three": "four",
|
||||||
|
}
|
||||||
|
|
||||||
|
// largeFields is a large size data set for benchmarking
|
||||||
|
var largeFields = Fields{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": "qux",
|
||||||
|
"one": "two",
|
||||||
|
"three": "four",
|
||||||
|
"five": "six",
|
||||||
|
"seven": "eight",
|
||||||
|
"nine": "ten",
|
||||||
|
"eleven": "twelve",
|
||||||
|
"thirteen": "fourteen",
|
||||||
|
"fifteen": "sixteen",
|
||||||
|
"seventeen": "eighteen",
|
||||||
|
"nineteen": "twenty",
|
||||||
|
"a": "b",
|
||||||
|
"c": "d",
|
||||||
|
"e": "f",
|
||||||
|
"g": "h",
|
||||||
|
"i": "j",
|
||||||
|
"k": "l",
|
||||||
|
"m": "n",
|
||||||
|
"o": "p",
|
||||||
|
"q": "r",
|
||||||
|
"s": "t",
|
||||||
|
"u": "v",
|
||||||
|
"w": "x",
|
||||||
|
"y": "z",
|
||||||
|
"this": "will",
|
||||||
|
"make": "thirty",
|
||||||
|
"entries": "yeah",
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorFields = Fields{
|
||||||
|
"foo": fmt.Errorf("bar"),
|
||||||
|
"baz": fmt.Errorf("qux"),
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkErrorTextFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSmallTextFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkLargeTextFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSmallJSONFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &JSONFormatter{}, smallFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkLargeJSONFormatter(b *testing.B) {
|
||||||
|
doBenchmark(b, &JSONFormatter{}, largeFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
|
||||||
|
entry := &Entry{
|
||||||
|
Time: time.Time{},
|
||||||
|
Level: InfoLevel,
|
||||||
|
Message: "message",
|
||||||
|
Data: fields,
|
||||||
|
}
|
||||||
|
var d []byte
|
||||||
|
var err error
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
d, err = formatter.Format(entry)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
b.SetBytes(int64(len(d)))
|
||||||
|
}
|
||||||
|
}
|
122
vendor/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
Normal file
122
vendor/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestHook struct {
|
||||||
|
Fired bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *TestHook) Fire(entry *Entry) error {
|
||||||
|
hook.Fired = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *TestHook) Levels() []Level {
|
||||||
|
return []Level{
|
||||||
|
DebugLevel,
|
||||||
|
InfoLevel,
|
||||||
|
WarnLevel,
|
||||||
|
ErrorLevel,
|
||||||
|
FatalLevel,
|
||||||
|
PanicLevel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHookFires(t *testing.T) {
|
||||||
|
hook := new(TestHook)
|
||||||
|
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
assert.Equal(t, hook.Fired, false)
|
||||||
|
|
||||||
|
log.Print("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, hook.Fired, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyHook struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *ModifyHook) Fire(entry *Entry) error {
|
||||||
|
entry.Data["wow"] = "whale"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *ModifyHook) Levels() []Level {
|
||||||
|
return []Level{
|
||||||
|
DebugLevel,
|
||||||
|
InfoLevel,
|
||||||
|
WarnLevel,
|
||||||
|
ErrorLevel,
|
||||||
|
FatalLevel,
|
||||||
|
PanicLevel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHookCanModifyEntry(t *testing.T) {
|
||||||
|
hook := new(ModifyHook)
|
||||||
|
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
log.WithField("wow", "elephant").Print("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["wow"], "whale")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCanFireMultipleHooks(t *testing.T) {
|
||||||
|
hook1 := new(ModifyHook)
|
||||||
|
hook2 := new(TestHook)
|
||||||
|
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Hooks.Add(hook1)
|
||||||
|
log.Hooks.Add(hook2)
|
||||||
|
|
||||||
|
log.WithField("wow", "elephant").Print("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["wow"], "whale")
|
||||||
|
assert.Equal(t, hook2.Fired, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorHook struct {
|
||||||
|
Fired bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *ErrorHook) Fire(entry *Entry) error {
|
||||||
|
hook.Fired = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *ErrorHook) Levels() []Level {
|
||||||
|
return []Level{
|
||||||
|
ErrorLevel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
|
||||||
|
hook := new(ErrorHook)
|
||||||
|
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
log.Info("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, hook.Fired, false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorHookShouldFireOnError(t *testing.T) {
|
||||||
|
hook := new(ErrorHook)
|
||||||
|
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
log.Error("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, hook.Fired, true)
|
||||||
|
})
|
||||||
|
}
|
39
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
Normal file
39
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"log/syslog"
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log := logrus.New()
|
||||||
|
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"log/syslog"
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log := logrus.New()
|
||||||
|
hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
54
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
Normal file
54
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// +build !windows,!nacl,!plan9
|
||||||
|
|
||||||
|
package logrus_syslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"log/syslog"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SyslogHook to send logs via syslog.
|
||||||
|
type SyslogHook struct {
|
||||||
|
Writer *syslog.Writer
|
||||||
|
SyslogNetwork string
|
||||||
|
SyslogRaddr string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a hook to be added to an instance of logger. This is called with
|
||||||
|
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||||
|
// `if err == nil { log.Hooks.Add(hook) }`
|
||||||
|
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||||
|
w, err := syslog.Dial(network, raddr, priority, tag)
|
||||||
|
return &SyslogHook{w, network, raddr}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||||
|
line, err := entry.String()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch entry.Level {
|
||||||
|
case logrus.PanicLevel:
|
||||||
|
return hook.Writer.Crit(line)
|
||||||
|
case logrus.FatalLevel:
|
||||||
|
return hook.Writer.Crit(line)
|
||||||
|
case logrus.ErrorLevel:
|
||||||
|
return hook.Writer.Err(line)
|
||||||
|
case logrus.WarnLevel:
|
||||||
|
return hook.Writer.Warning(line)
|
||||||
|
case logrus.InfoLevel:
|
||||||
|
return hook.Writer.Info(line)
|
||||||
|
case logrus.DebugLevel:
|
||||||
|
return hook.Writer.Debug(line)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||||
|
return logrus.AllLevels
|
||||||
|
}
|
26
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
Normal file
26
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package logrus_syslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"log/syslog"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLocalhostAddAndPrint(t *testing.T) {
|
||||||
|
log := logrus.New()
|
||||||
|
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to connect to local syslog.")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
|
||||||
|
for _, level := range hook.Levels() {
|
||||||
|
if len(log.Hooks[level]) != 1 {
|
||||||
|
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Congratulations!")
|
||||||
|
}
|
67
vendor/github.com/Sirupsen/logrus/hooks/test/test.go
generated
vendored
Normal file
67
vendor/github.com/Sirupsen/logrus/hooks/test/test.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// test.Hook is a hook designed for dealing with logs in test scenarios.
|
||||||
|
type Hook struct {
|
||||||
|
Entries []*logrus.Entry
|
||||||
|
}
|
||||||
|
|
||||||
|
// Installs a test hook for the global logger.
|
||||||
|
func NewGlobal() *Hook {
|
||||||
|
|
||||||
|
hook := new(Hook)
|
||||||
|
logrus.AddHook(hook)
|
||||||
|
|
||||||
|
return hook
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Installs a test hook for a given local logger.
|
||||||
|
func NewLocal(logger *logrus.Logger) *Hook {
|
||||||
|
|
||||||
|
hook := new(Hook)
|
||||||
|
logger.Hooks.Add(hook)
|
||||||
|
|
||||||
|
return hook
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a discarding logger and installs the test hook.
|
||||||
|
func NewNullLogger() (*logrus.Logger, *Hook) {
|
||||||
|
|
||||||
|
logger := logrus.New()
|
||||||
|
logger.Out = ioutil.Discard
|
||||||
|
|
||||||
|
return logger, NewLocal(logger)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Hook) Fire(e *logrus.Entry) error {
|
||||||
|
t.Entries = append(t.Entries, e)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Hook) Levels() []logrus.Level {
|
||||||
|
return logrus.AllLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastEntry returns the last entry that was logged or nil.
|
||||||
|
func (t *Hook) LastEntry() (l *logrus.Entry) {
|
||||||
|
|
||||||
|
if i := len(t.Entries) - 1; i < 0 {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return t.Entries[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset removes all Entries from this test hook.
|
||||||
|
func (t *Hook) Reset() {
|
||||||
|
t.Entries = make([]*logrus.Entry, 0)
|
||||||
|
}
|
39
vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go
generated
vendored
Normal file
39
vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAllHooks(t *testing.T) {
|
||||||
|
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
logger, hook := NewNullLogger()
|
||||||
|
assert.Nil(hook.LastEntry())
|
||||||
|
assert.Equal(0, len(hook.Entries))
|
||||||
|
|
||||||
|
logger.Error("Hello error")
|
||||||
|
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
||||||
|
assert.Equal("Hello error", hook.LastEntry().Message)
|
||||||
|
assert.Equal(1, len(hook.Entries))
|
||||||
|
|
||||||
|
logger.Warn("Hello warning")
|
||||||
|
assert.Equal(logrus.WarnLevel, hook.LastEntry().Level)
|
||||||
|
assert.Equal("Hello warning", hook.LastEntry().Message)
|
||||||
|
assert.Equal(2, len(hook.Entries))
|
||||||
|
|
||||||
|
hook.Reset()
|
||||||
|
assert.Nil(hook.LastEntry())
|
||||||
|
assert.Equal(0, len(hook.Entries))
|
||||||
|
|
||||||
|
hook = NewGlobal()
|
||||||
|
|
||||||
|
logrus.Error("Hello error")
|
||||||
|
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
||||||
|
assert.Equal("Hello error", hook.LastEntry().Message)
|
||||||
|
assert.Equal(1, len(hook.Entries))
|
||||||
|
|
||||||
|
}
|
120
vendor/github.com/Sirupsen/logrus/json_formatter_test.go
generated
vendored
Normal file
120
vendor/github.com/Sirupsen/logrus/json_formatter_test.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestErrorNotLost(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(b, &entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry["error"] != "wild walrus" {
|
||||||
|
t.Fatal("Error field not set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(b, &entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry["omg"] != "wild walrus" {
|
||||||
|
t.Fatal("Error field not set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFieldClashWithTime(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithField("time", "right now!"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(b, &entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry["fields.time"] != "right now!" {
|
||||||
|
t.Fatal("fields.time not set to original time field")
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry["time"] != "0001-01-01T00:00:00Z" {
|
||||||
|
t.Fatal("time field not set to current time, was: ", entry["time"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFieldClashWithMsg(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithField("msg", "something"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(b, &entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry["fields.msg"] != "something" {
|
||||||
|
t.Fatal("fields.msg not set to original msg field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFieldClashWithLevel(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithField("level", "something"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(b, &entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry["fields.level"] != "something" {
|
||||||
|
t.Fatal("fields.level not set to original level field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJSONEntryEndsWithNewline(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithField("level", "something"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b[len(b)-1] != '\n' {
|
||||||
|
t.Fatal("Expected JSON log entry to end with a newline")
|
||||||
|
}
|
||||||
|
}
|
61
vendor/github.com/Sirupsen/logrus/logger_bench_test.go
generated
vendored
Normal file
61
vendor/github.com/Sirupsen/logrus/logger_bench_test.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// smallFields is a small size data set for benchmarking
|
||||||
|
var loggerFields = Fields{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": "qux",
|
||||||
|
"one": "two",
|
||||||
|
"three": "four",
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkDummyLogger(b *testing.B) {
|
||||||
|
nullf, err := os.OpenFile("/dev/null", os.O_WRONLY, 0666)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
defer nullf.Close()
|
||||||
|
doLoggerBenchmark(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkDummyLoggerNoLock(b *testing.B) {
|
||||||
|
nullf, err := os.OpenFile("/dev/null", os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
defer nullf.Close()
|
||||||
|
doLoggerBenchmarkNoLock(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doLoggerBenchmark(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
|
||||||
|
logger := Logger{
|
||||||
|
Out: out,
|
||||||
|
Level: InfoLevel,
|
||||||
|
Formatter: formatter,
|
||||||
|
}
|
||||||
|
entry := logger.WithFields(fields)
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
entry.Info("aaa")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func doLoggerBenchmarkNoLock(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
|
||||||
|
logger := Logger{
|
||||||
|
Out: out,
|
||||||
|
Level: InfoLevel,
|
||||||
|
Formatter: formatter,
|
||||||
|
}
|
||||||
|
logger.SetNoLock()
|
||||||
|
entry := logger.WithFields(fields)
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
entry.Info("aaa")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
361
vendor/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
Normal file
361
vendor/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
var fields Fields
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &buffer
|
||||||
|
logger.Formatter = new(JSONFormatter)
|
||||||
|
|
||||||
|
log(logger)
|
||||||
|
|
||||||
|
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assertions(fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &buffer
|
||||||
|
logger.Formatter = &TextFormatter{
|
||||||
|
DisableColors: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
log(logger)
|
||||||
|
|
||||||
|
fields := make(map[string]string)
|
||||||
|
for _, kv := range strings.Split(buffer.String(), " ") {
|
||||||
|
if !strings.Contains(kv, "=") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
kvArr := strings.Split(kv, "=")
|
||||||
|
key := strings.TrimSpace(kvArr[0])
|
||||||
|
val := kvArr[1]
|
||||||
|
if kvArr[1][0] == '"' {
|
||||||
|
var err error
|
||||||
|
val, err = strconv.Unquote(val)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
fields[key] = val
|
||||||
|
}
|
||||||
|
assertions(fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrint(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Print("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test")
|
||||||
|
assert.Equal(t, fields["level"], "info")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfo(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Info("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test")
|
||||||
|
assert.Equal(t, fields["level"], "info")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWarn(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Warn("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test")
|
||||||
|
assert.Equal(t, fields["level"], "warning")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Infoln("test", "test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test test")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Infoln("test", 10)
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test 10")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Infoln(10, 10)
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "10 10")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Infoln(10, 10)
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "10 10")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Info("test", 10)
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test10")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.Info("test", "test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "testtest")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
var fields Fields
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &buffer
|
||||||
|
logger.Formatter = new(JSONFormatter)
|
||||||
|
|
||||||
|
localLog := logger.WithFields(Fields{
|
||||||
|
"key1": "value1",
|
||||||
|
})
|
||||||
|
|
||||||
|
localLog.WithField("key2", "value2").Info("test")
|
||||||
|
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "value2", fields["key2"])
|
||||||
|
assert.Equal(t, "value1", fields["key1"])
|
||||||
|
|
||||||
|
buffer = bytes.Buffer{}
|
||||||
|
fields = Fields{}
|
||||||
|
localLog.Info("test")
|
||||||
|
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
_, ok := fields["key2"]
|
||||||
|
assert.Equal(t, false, ok)
|
||||||
|
assert.Equal(t, "value1", fields["key1"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.WithField("msg", "hello").Info("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.WithField("msg", "hello").Info("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["msg"], "test")
|
||||||
|
assert.Equal(t, fields["fields.msg"], "hello")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.WithField("time", "hello").Info("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["fields.time"], "hello")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
|
||||||
|
LogAndAssertJSON(t, func(log *Logger) {
|
||||||
|
log.WithField("level", 1).Info("test")
|
||||||
|
}, func(fields Fields) {
|
||||||
|
assert.Equal(t, fields["level"], "info")
|
||||||
|
assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
|
||||||
|
LogAndAssertText(t, func(log *Logger) {
|
||||||
|
ll := log.WithField("herp", "derp")
|
||||||
|
ll.Info("hello")
|
||||||
|
ll.Info("bye")
|
||||||
|
}, func(fields map[string]string) {
|
||||||
|
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
|
||||||
|
if _, ok := fields[fieldName]; ok {
|
||||||
|
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
|
||||||
|
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
var fields Fields
|
||||||
|
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &buffer
|
||||||
|
logger.Formatter = new(JSONFormatter)
|
||||||
|
|
||||||
|
llog := logger.WithField("context", "eating raw fish")
|
||||||
|
|
||||||
|
llog.Info("looks delicious")
|
||||||
|
|
||||||
|
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||||
|
assert.NoError(t, err, "should have decoded first message")
|
||||||
|
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||||
|
assert.Equal(t, fields["msg"], "looks delicious")
|
||||||
|
assert.Equal(t, fields["context"], "eating raw fish")
|
||||||
|
|
||||||
|
buffer.Reset()
|
||||||
|
|
||||||
|
llog.Warn("omg it is!")
|
||||||
|
|
||||||
|
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||||
|
assert.NoError(t, err, "should have decoded second message")
|
||||||
|
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||||
|
assert.Equal(t, fields["msg"], "omg it is!")
|
||||||
|
assert.Equal(t, fields["context"], "eating raw fish")
|
||||||
|
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertLevelToString(t *testing.T) {
|
||||||
|
assert.Equal(t, "debug", DebugLevel.String())
|
||||||
|
assert.Equal(t, "info", InfoLevel.String())
|
||||||
|
assert.Equal(t, "warning", WarnLevel.String())
|
||||||
|
assert.Equal(t, "error", ErrorLevel.String())
|
||||||
|
assert.Equal(t, "fatal", FatalLevel.String())
|
||||||
|
assert.Equal(t, "panic", PanicLevel.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseLevel(t *testing.T) {
|
||||||
|
l, err := ParseLevel("panic")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, PanicLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("PANIC")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, PanicLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("fatal")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, FatalLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("FATAL")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, FatalLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("error")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, ErrorLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("ERROR")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, ErrorLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("warn")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, WarnLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("WARN")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, WarnLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("warning")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, WarnLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("WARNING")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, WarnLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("info")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, InfoLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("INFO")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, InfoLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("debug")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, DebugLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("DEBUG")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, DebugLevel, l)
|
||||||
|
|
||||||
|
l, err = ParseLevel("invalid")
|
||||||
|
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSetLevelRace(t *testing.T) {
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(i int) {
|
||||||
|
defer wg.Done()
|
||||||
|
if i%2 == 0 {
|
||||||
|
SetLevel(InfoLevel)
|
||||||
|
} else {
|
||||||
|
GetLevel()
|
||||||
|
}
|
||||||
|
}(i)
|
||||||
|
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoggingRace(t *testing.T) {
|
||||||
|
logger := New()
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(100)
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
go func() {
|
||||||
|
logger.Info("info")
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile test
|
||||||
|
func TestLogrusInterface(t *testing.T) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
fn := func(l FieldLogger) {
|
||||||
|
b := l.WithField("key", "value")
|
||||||
|
b.Debug("Test")
|
||||||
|
}
|
||||||
|
// test logger
|
||||||
|
logger := New()
|
||||||
|
logger.Out = &buffer
|
||||||
|
fn(logger)
|
||||||
|
|
||||||
|
// test Entry
|
||||||
|
e := logger.WithField("another", "value")
|
||||||
|
fn(e)
|
||||||
|
}
|
61
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
Normal file
61
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQuoting(t *testing.T) {
|
||||||
|
tf := &TextFormatter{DisableColors: true}
|
||||||
|
|
||||||
|
checkQuoting := func(q bool, value interface{}) {
|
||||||
|
b, _ := tf.Format(WithField("test", value))
|
||||||
|
idx := bytes.Index(b, ([]byte)("test="))
|
||||||
|
cont := bytes.Contains(b[idx+5:], []byte{'"'})
|
||||||
|
if cont != q {
|
||||||
|
if q {
|
||||||
|
t.Errorf("quoting expected for: %#v", value)
|
||||||
|
} else {
|
||||||
|
t.Errorf("quoting not expected for: %#v", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkQuoting(false, "abcd")
|
||||||
|
checkQuoting(false, "v1.0")
|
||||||
|
checkQuoting(false, "1234567890")
|
||||||
|
checkQuoting(true, "/foobar")
|
||||||
|
checkQuoting(true, "x y")
|
||||||
|
checkQuoting(true, "x,y")
|
||||||
|
checkQuoting(false, errors.New("invalid"))
|
||||||
|
checkQuoting(true, errors.New("invalid argument"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimestampFormat(t *testing.T) {
|
||||||
|
checkTimeStr := func(format string) {
|
||||||
|
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
||||||
|
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
||||||
|
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
||||||
|
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
||||||
|
timeStr := customStr[timeStart+5 : timeEnd-1]
|
||||||
|
if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' {
|
||||||
|
timeStr = timeStr[1 : len(timeStr)-1]
|
||||||
|
}
|
||||||
|
if format == "" {
|
||||||
|
format = time.RFC3339
|
||||||
|
}
|
||||||
|
_, e := time.Parse(format, (string)(timeStr))
|
||||||
|
if e != nil {
|
||||||
|
t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
|
||||||
|
checkTimeStr("Mon Jan _2 15:04:05 2006")
|
||||||
|
checkTimeStr("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add tests for sorting etc., this requires a parser for the text
|
||||||
|
// formatter output.
|
383
vendor/github.com/fatih/structs/field_test.go
generated
vendored
Normal file
383
vendor/github.com/fatih/structs/field_test.go
generated
vendored
Normal file
|
@ -0,0 +1,383 @@
|
||||||
|
package structs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A test struct that defines all cases
|
||||||
|
type Foo struct {
|
||||||
|
A string
|
||||||
|
B int `structs:"y"`
|
||||||
|
C bool `json:"c"`
|
||||||
|
d string // not exported
|
||||||
|
E *Baz
|
||||||
|
x string `xml:"x"` // not exported, with tag
|
||||||
|
Y []string
|
||||||
|
Z map[string]interface{}
|
||||||
|
*Bar // embedded
|
||||||
|
}
|
||||||
|
|
||||||
|
type Baz struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Bar struct {
|
||||||
|
E string
|
||||||
|
F int
|
||||||
|
g []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStruct() *Struct {
|
||||||
|
b := &Bar{
|
||||||
|
E: "example",
|
||||||
|
F: 2,
|
||||||
|
g: []string{"zeynep", "fatih"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// B and x is not initialized for testing
|
||||||
|
f := &Foo{
|
||||||
|
A: "gopher",
|
||||||
|
C: true,
|
||||||
|
d: "small",
|
||||||
|
E: nil,
|
||||||
|
Y: []string{"example"},
|
||||||
|
Z: nil,
|
||||||
|
}
|
||||||
|
f.Bar = b
|
||||||
|
|
||||||
|
return New(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Set(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
f := s.Field("A")
|
||||||
|
err := f.Set("fatih")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.Value().(string) != "fatih" {
|
||||||
|
t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih")
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("Y")
|
||||||
|
err = f.Set([]string{"override", "with", "this"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sliceLen := len(f.Value().([]string))
|
||||||
|
if sliceLen != 3 {
|
||||||
|
t.Errorf("Setted values slice length is wrong: %d, want: %d", sliceLen, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("C")
|
||||||
|
err = f.Set(false)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.Value().(bool) {
|
||||||
|
t.Errorf("Setted value is wrong: %t want: %t", f.Value().(bool), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's pass a different type
|
||||||
|
f = s.Field("A")
|
||||||
|
err = f.Set(123) // Field A is of type string, but we are going to pass an integer
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Setting a field's value with a different type than the field's type should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// old value should be still there :)
|
||||||
|
if f.Value().(string) != "fatih" {
|
||||||
|
t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih")
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's access an unexported field, which should give an error
|
||||||
|
f = s.Field("d")
|
||||||
|
err = f.Set("large")
|
||||||
|
if err != errNotExported {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's set a pointer to struct
|
||||||
|
b := &Bar{
|
||||||
|
E: "gopher",
|
||||||
|
F: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("Bar")
|
||||||
|
err = f.Set(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
baz := &Baz{
|
||||||
|
A: "helloWorld",
|
||||||
|
B: 42,
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("E")
|
||||||
|
err = f.Set(baz)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ba := s.Field("E").Value().(*Baz)
|
||||||
|
|
||||||
|
if ba.A != "helloWorld" {
|
||||||
|
t.Errorf("could not set baz. Got: %s Want: helloWorld", ba.A)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Zero(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
f := s.Field("A")
|
||||||
|
err := f.Zero()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.Value().(string) != "" {
|
||||||
|
t.Errorf("Zeroed value is wrong: %s want: %s", f.Value().(string), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("Y")
|
||||||
|
err = f.Zero()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sliceLen := len(f.Value().([]string))
|
||||||
|
if sliceLen != 0 {
|
||||||
|
t.Errorf("Zeroed values slice length is wrong: %d, want: %d", sliceLen, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("C")
|
||||||
|
err = f.Zero()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.Value().(bool) {
|
||||||
|
t.Errorf("Zeroed value is wrong: %t want: %t", f.Value().(bool), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's access an unexported field, which should give an error
|
||||||
|
f = s.Field("d")
|
||||||
|
err = f.Zero()
|
||||||
|
if err != errNotExported {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("Bar")
|
||||||
|
err = f.Zero()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("E")
|
||||||
|
err = f.Zero()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
v := s.Field("E").value
|
||||||
|
if !v.IsNil() {
|
||||||
|
t.Errorf("could not set baz. Got: %s Want: <nil>", v.Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Retrieveing a non existing field from the struct should panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_ = s.Field("no-field")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Kind(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
f := s.Field("A")
|
||||||
|
if f.Kind() != reflect.String {
|
||||||
|
t.Errorf("Field A has wrong kind: %s want: %s", f.Kind(), reflect.String)
|
||||||
|
}
|
||||||
|
|
||||||
|
f = s.Field("B")
|
||||||
|
if f.Kind() != reflect.Int {
|
||||||
|
t.Errorf("Field B has wrong kind: %s want: %s", f.Kind(), reflect.Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unexported
|
||||||
|
f = s.Field("d")
|
||||||
|
if f.Kind() != reflect.String {
|
||||||
|
t.Errorf("Field d has wrong kind: %s want: %s", f.Kind(), reflect.String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Tag(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
v := s.Field("B").Tag("json")
|
||||||
|
if v != "" {
|
||||||
|
t.Errorf("Field's tag value of a non existing tag should return empty, got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("C").Tag("json")
|
||||||
|
if v != "c" {
|
||||||
|
t.Errorf("Field's tag value of the existing field C should return 'c', got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("d").Tag("json")
|
||||||
|
if v != "" {
|
||||||
|
t.Errorf("Field's tag value of a non exported field should return empty, got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("x").Tag("xml")
|
||||||
|
if v != "x" {
|
||||||
|
t.Errorf("Field's tag value of a non exported field with a tag should return 'x', got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("A").Tag("json")
|
||||||
|
if v != "" {
|
||||||
|
t.Errorf("Field's tag value of a existing field without a tag should return empty, got: %s", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Value(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
v := s.Field("A").Value()
|
||||||
|
val, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("Field's value of a A should be string")
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != "gopher" {
|
||||||
|
t.Errorf("Field's value of a existing tag should return 'gopher', got: %s", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Value of a non exported field from the field should panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// should panic
|
||||||
|
_ = s.Field("d").Value()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_IsEmbedded(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
if !s.Field("Bar").IsEmbedded() {
|
||||||
|
t.Errorf("Fields 'Bar' field is an embedded field")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Field("d").IsEmbedded() {
|
||||||
|
t.Errorf("Fields 'd' field is not an embedded field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_IsExported(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
if !s.Field("Bar").IsExported() {
|
||||||
|
t.Errorf("Fields 'Bar' field is an exported field")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !s.Field("A").IsExported() {
|
||||||
|
t.Errorf("Fields 'A' field is an exported field")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Field("d").IsExported() {
|
||||||
|
t.Errorf("Fields 'd' field is not an exported field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_IsZero(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
if s.Field("A").IsZero() {
|
||||||
|
t.Errorf("Fields 'A' field is an initialized field")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !s.Field("B").IsZero() {
|
||||||
|
t.Errorf("Fields 'B' field is not an initialized field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Name(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
if s.Field("A").Name() != "A" {
|
||||||
|
t.Errorf("Fields 'A' field should have the name 'A'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Field(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
e := s.Field("Bar").Field("E")
|
||||||
|
|
||||||
|
val, ok := e.Value().(string)
|
||||||
|
if !ok {
|
||||||
|
t.Error("The value of the field 'e' inside 'Bar' struct should be string")
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != "example" {
|
||||||
|
t.Errorf("The value of 'e' should be 'example, got: %s", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Field of a non existing nested struct should panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_ = s.Field("Bar").Field("e")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Fields(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
fields := s.Field("Bar").Fields()
|
||||||
|
|
||||||
|
if len(fields) != 3 {
|
||||||
|
t.Errorf("We expect 3 fields in embedded struct, was: %d", len(fields))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_FieldOk(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
b, ok := s.FieldOk("Bar")
|
||||||
|
if !ok {
|
||||||
|
t.Error("The field 'Bar' should exists.")
|
||||||
|
}
|
||||||
|
|
||||||
|
e, ok := b.FieldOk("E")
|
||||||
|
if !ok {
|
||||||
|
t.Error("The field 'E' should exists.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok := e.Value().(string)
|
||||||
|
if !ok {
|
||||||
|
t.Error("The value of the field 'e' inside 'Bar' struct should be string")
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != "example" {
|
||||||
|
t.Errorf("The value of 'e' should be 'example, got: %s", val)
|
||||||
|
}
|
||||||
|
}
|
351
vendor/github.com/fatih/structs/structs_example_test.go
generated
vendored
Normal file
351
vendor/github.com/fatih/structs/structs_example_test.go
generated
vendored
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
package structs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleNew() {
|
||||||
|
type Server struct {
|
||||||
|
Name string
|
||||||
|
ID int32
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Name: "Arslan",
|
||||||
|
ID: 123456,
|
||||||
|
Enabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
s := New(server)
|
||||||
|
|
||||||
|
fmt.Printf("Name : %v\n", s.Name())
|
||||||
|
fmt.Printf("Values : %v\n", s.Values())
|
||||||
|
fmt.Printf("Value of ID : %v\n", s.Field("ID").Value())
|
||||||
|
// Output:
|
||||||
|
// Name : Server
|
||||||
|
// Values : [Arslan 123456 true]
|
||||||
|
// Value of ID : 123456
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMap() {
|
||||||
|
type Server struct {
|
||||||
|
Name string
|
||||||
|
ID int32
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Server{
|
||||||
|
Name: "Arslan",
|
||||||
|
ID: 123456,
|
||||||
|
Enabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Map(s)
|
||||||
|
|
||||||
|
fmt.Printf("%#v\n", m["Name"])
|
||||||
|
fmt.Printf("%#v\n", m["ID"])
|
||||||
|
fmt.Printf("%#v\n", m["Enabled"])
|
||||||
|
// Output:
|
||||||
|
// "Arslan"
|
||||||
|
// 123456
|
||||||
|
// true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMap_tags() {
|
||||||
|
// Custom tags can change the map keys instead of using the fields name
|
||||||
|
type Server struct {
|
||||||
|
Name string `structs:"server_name"`
|
||||||
|
ID int32 `structs:"server_id"`
|
||||||
|
Enabled bool `structs:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Server{
|
||||||
|
Name: "Zeynep",
|
||||||
|
ID: 789012,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Map(s)
|
||||||
|
|
||||||
|
// access them by the custom tags defined above
|
||||||
|
fmt.Printf("%#v\n", m["server_name"])
|
||||||
|
fmt.Printf("%#v\n", m["server_id"])
|
||||||
|
fmt.Printf("%#v\n", m["enabled"])
|
||||||
|
// Output:
|
||||||
|
// "Zeynep"
|
||||||
|
// 789012
|
||||||
|
// false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMap_nested() {
|
||||||
|
// By default field with struct types are processed too. We can stop
|
||||||
|
// processing them via "omitnested" tag option.
|
||||||
|
type Server struct {
|
||||||
|
Name string `structs:"server_name"`
|
||||||
|
ID int32 `structs:"server_id"`
|
||||||
|
Time time.Time `structs:"time,omitnested"` // do not convert to map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shortForm = "2006-Jan-02"
|
||||||
|
t, _ := time.Parse("2006-Jan-02", "2013-Feb-03")
|
||||||
|
|
||||||
|
s := &Server{
|
||||||
|
Name: "Zeynep",
|
||||||
|
ID: 789012,
|
||||||
|
Time: t,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Map(s)
|
||||||
|
|
||||||
|
// access them by the custom tags defined above
|
||||||
|
fmt.Printf("%v\n", m["server_name"])
|
||||||
|
fmt.Printf("%v\n", m["server_id"])
|
||||||
|
fmt.Printf("%v\n", m["time"].(time.Time))
|
||||||
|
// Output:
|
||||||
|
// Zeynep
|
||||||
|
// 789012
|
||||||
|
// 2013-02-03 00:00:00 +0000 UTC
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMap_omitEmpty() {
|
||||||
|
// By default field with struct types of zero values are processed too. We
|
||||||
|
// can stop processing them via "omitempty" tag option.
|
||||||
|
type Server struct {
|
||||||
|
Name string `structs:",omitempty"`
|
||||||
|
ID int32 `structs:"server_id,omitempty"`
|
||||||
|
Location string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only add location
|
||||||
|
s := &Server{
|
||||||
|
Location: "Tokyo",
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Map(s)
|
||||||
|
|
||||||
|
// map contains only the Location field
|
||||||
|
fmt.Printf("%v\n", m)
|
||||||
|
// Output:
|
||||||
|
// map[Location:Tokyo]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleValues() {
|
||||||
|
type Server struct {
|
||||||
|
Name string
|
||||||
|
ID int32
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Server{
|
||||||
|
Name: "Fatih",
|
||||||
|
ID: 135790,
|
||||||
|
Enabled: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Values(s)
|
||||||
|
|
||||||
|
fmt.Printf("Values: %+v\n", m)
|
||||||
|
// Output:
|
||||||
|
// Values: [Fatih 135790 false]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleValues_omitEmpty() {
|
||||||
|
// By default field with struct types of zero values are processed too. We
|
||||||
|
// can stop processing them via "omitempty" tag option.
|
||||||
|
type Server struct {
|
||||||
|
Name string `structs:",omitempty"`
|
||||||
|
ID int32 `structs:"server_id,omitempty"`
|
||||||
|
Location string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only add location
|
||||||
|
s := &Server{
|
||||||
|
Location: "Ankara",
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Values(s)
|
||||||
|
|
||||||
|
// values contains only the Location field
|
||||||
|
fmt.Printf("Values: %+v\n", m)
|
||||||
|
// Output:
|
||||||
|
// Values: [Ankara]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleValues_tags() {
|
||||||
|
type Location struct {
|
||||||
|
City string
|
||||||
|
Country string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
Name string
|
||||||
|
ID int32
|
||||||
|
Enabled bool
|
||||||
|
Location Location `structs:"-"` // values from location are not included anymore
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Server{
|
||||||
|
Name: "Fatih",
|
||||||
|
ID: 135790,
|
||||||
|
Enabled: false,
|
||||||
|
Location: Location{City: "Ankara", Country: "Turkey"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let get all values from the struct s. Note that we don't include values
|
||||||
|
// from the Location field
|
||||||
|
m := Values(s)
|
||||||
|
|
||||||
|
fmt.Printf("Values: %+v\n", m)
|
||||||
|
// Output:
|
||||||
|
// Values: [Fatih 135790 false]
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleFields() {
|
||||||
|
type Access struct {
|
||||||
|
Name string
|
||||||
|
LastAccessed time.Time
|
||||||
|
Number int
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Access{
|
||||||
|
Name: "Fatih",
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
Number: 1234567,
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := Fields(s)
|
||||||
|
|
||||||
|
for i, field := range fields {
|
||||||
|
fmt.Printf("[%d] %+v\n", i, field.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [0] Name
|
||||||
|
// [1] LastAccessed
|
||||||
|
// [2] Number
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleFields_nested() {
|
||||||
|
type Person struct {
|
||||||
|
Name string
|
||||||
|
Number int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Access struct {
|
||||||
|
Person Person
|
||||||
|
HasPermission bool
|
||||||
|
LastAccessed time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Access{
|
||||||
|
Person: Person{Name: "fatih", Number: 1234567},
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
HasPermission: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's get all fields from the struct s.
|
||||||
|
fields := Fields(s)
|
||||||
|
|
||||||
|
for _, field := range fields {
|
||||||
|
if field.Name() == "Person" {
|
||||||
|
fmt.Printf("Access.Person.Name: %+v\n", field.Field("Name").Value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Access.Person.Name: fatih
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleField() {
|
||||||
|
type Person struct {
|
||||||
|
Name string
|
||||||
|
Number int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Access struct {
|
||||||
|
Person Person
|
||||||
|
HasPermission bool
|
||||||
|
LastAccessed time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
access := &Access{
|
||||||
|
Person: Person{Name: "fatih", Number: 1234567},
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
HasPermission: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Struct type
|
||||||
|
s := New(access)
|
||||||
|
|
||||||
|
// Get the Field type for "Person" field
|
||||||
|
p := s.Field("Person")
|
||||||
|
|
||||||
|
// Get the underlying "Name field" and print the value of it
|
||||||
|
name := p.Field("Name")
|
||||||
|
|
||||||
|
fmt.Printf("Value of Person.Access.Name: %+v\n", name.Value())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Value of Person.Access.Name: fatih
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleIsZero() {
|
||||||
|
type Server struct {
|
||||||
|
Name string
|
||||||
|
ID int32
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing is initalized
|
||||||
|
a := &Server{}
|
||||||
|
isZeroA := IsZero(a)
|
||||||
|
|
||||||
|
// Name and Enabled is initialized, but not ID
|
||||||
|
b := &Server{
|
||||||
|
Name: "Golang",
|
||||||
|
Enabled: true,
|
||||||
|
}
|
||||||
|
isZeroB := IsZero(b)
|
||||||
|
|
||||||
|
fmt.Printf("%#v\n", isZeroA)
|
||||||
|
fmt.Printf("%#v\n", isZeroB)
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleHasZero() {
|
||||||
|
// Let's define an Access struct. Note that the "Enabled" field is not
|
||||||
|
// going to be checked because we added the "structs" tag to the field.
|
||||||
|
type Access struct {
|
||||||
|
Name string
|
||||||
|
LastAccessed time.Time
|
||||||
|
Number int
|
||||||
|
Enabled bool `structs:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name and Number is not initialized.
|
||||||
|
a := &Access{
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
}
|
||||||
|
hasZeroA := HasZero(a)
|
||||||
|
|
||||||
|
// Name and Number is initialized.
|
||||||
|
b := &Access{
|
||||||
|
Name: "Fatih",
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
Number: 12345,
|
||||||
|
}
|
||||||
|
hasZeroB := HasZero(b)
|
||||||
|
|
||||||
|
fmt.Printf("%#v\n", hasZeroA)
|
||||||
|
fmt.Printf("%#v\n", hasZeroB)
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
1109
vendor/github.com/fatih/structs/structs_test.go
generated
vendored
Normal file
1109
vendor/github.com/fatih/structs/structs_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
46
vendor/github.com/fatih/structs/tags_test.go
generated
vendored
Normal file
46
vendor/github.com/fatih/structs/tags_test.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package structs
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestParseTag_Name(t *testing.T) {
|
||||||
|
tags := []struct {
|
||||||
|
tag string
|
||||||
|
has bool
|
||||||
|
}{
|
||||||
|
{"", false},
|
||||||
|
{"name", true},
|
||||||
|
{"name,opt", true},
|
||||||
|
{"name , opt, opt2", false}, // has a single whitespace
|
||||||
|
{", opt, opt2", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tag := range tags {
|
||||||
|
name, _ := parseTag(tag.tag)
|
||||||
|
|
||||||
|
if (name != "name") && tag.has {
|
||||||
|
t.Errorf("Parse tag should return name: %#v", tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseTag_Opts(t *testing.T) {
|
||||||
|
tags := []struct {
|
||||||
|
opts string
|
||||||
|
has bool
|
||||||
|
}{
|
||||||
|
{"name", false},
|
||||||
|
{"name,opt", true},
|
||||||
|
{"name , opt, opt2", false}, // has a single whitespace
|
||||||
|
{",opt, opt2", true},
|
||||||
|
{", opt3, opt4", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
// search for "opt"
|
||||||
|
for _, tag := range tags {
|
||||||
|
_, opts := parseTag(tag.opts)
|
||||||
|
|
||||||
|
if opts.Has("opt") != tag.has {
|
||||||
|
t.Errorf("Tag opts should have opt: %#v", tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
vendor/github.com/hashicorp/errwrap/errwrap_test.go
generated
vendored
Normal file
94
vendor/github.com/hashicorp/errwrap/errwrap_test.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
package errwrap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWrappedError_impl(t *testing.T) {
|
||||||
|
var _ error = new(wrappedError)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAll(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Err error
|
||||||
|
Msg string
|
||||||
|
Len int
|
||||||
|
}{
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
fmt.Errorf("foo"),
|
||||||
|
"foo",
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fmt.Errorf("bar"),
|
||||||
|
"foo",
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Wrapf("bar", fmt.Errorf("foo")),
|
||||||
|
"foo",
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Wrapf("{{err}}", fmt.Errorf("foo")),
|
||||||
|
"foo",
|
||||||
|
2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Wrapf("bar", Wrapf("baz", fmt.Errorf("foo"))),
|
||||||
|
"foo",
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
actual := GetAll(tc.Err, tc.Msg)
|
||||||
|
if len(actual) != tc.Len {
|
||||||
|
t.Fatalf("%d: bad: %#v", i, actual)
|
||||||
|
}
|
||||||
|
for _, v := range actual {
|
||||||
|
if v.Error() != tc.Msg {
|
||||||
|
t.Fatalf("%d: bad: %#v", i, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAllType(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Err error
|
||||||
|
Type interface{}
|
||||||
|
Len int
|
||||||
|
}{
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
fmt.Errorf("foo"),
|
||||||
|
"foo",
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fmt.Errorf("bar"),
|
||||||
|
fmt.Errorf("foo"),
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Wrapf("bar", fmt.Errorf("foo")),
|
||||||
|
fmt.Errorf("baz"),
|
||||||
|
2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Wrapf("bar", Wrapf("baz", fmt.Errorf("foo"))),
|
||||||
|
Wrapf("", nil),
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
actual := GetAllType(tc.Err, tc.Type)
|
||||||
|
if len(actual) != tc.Len {
|
||||||
|
t.Fatalf("%d: bad: %#v", i, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
vendor/github.com/hashicorp/go-multierror/append_test.go
generated
vendored
Normal file
64
vendor/github.com/hashicorp/go-multierror/append_test.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAppend_Error(t *testing.T) {
|
||||||
|
original := &Error{
|
||||||
|
Errors: []error{errors.New("foo")},
|
||||||
|
}
|
||||||
|
|
||||||
|
result := Append(original, errors.New("bar"))
|
||||||
|
if len(result.Errors) != 2 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
|
||||||
|
original = &Error{}
|
||||||
|
result = Append(original, errors.New("bar"))
|
||||||
|
if len(result.Errors) != 1 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test when a typed nil is passed
|
||||||
|
var e *Error
|
||||||
|
result = Append(e, errors.New("baz"))
|
||||||
|
if len(result.Errors) != 1 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test flattening
|
||||||
|
original = &Error{
|
||||||
|
Errors: []error{errors.New("foo")},
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Append(original, Append(nil, errors.New("foo"), errors.New("bar")))
|
||||||
|
if len(result.Errors) != 3 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppend_NilError(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
result := Append(err, errors.New("bar"))
|
||||||
|
if len(result.Errors) != 1 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppend_NonError(t *testing.T) {
|
||||||
|
original := errors.New("foo")
|
||||||
|
result := Append(original, errors.New("bar"))
|
||||||
|
if len(result.Errors) != 2 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppend_NonError_Error(t *testing.T) {
|
||||||
|
original := errors.New("foo")
|
||||||
|
result := Append(original, Append(nil, errors.New("bar")))
|
||||||
|
if len(result.Errors) != 2 {
|
||||||
|
t.Fatalf("wrong len: %d", len(result.Errors))
|
||||||
|
}
|
||||||
|
}
|
48
vendor/github.com/hashicorp/go-multierror/flatten_test.go
generated
vendored
Normal file
48
vendor/github.com/hashicorp/go-multierror/flatten_test.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFlatten(t *testing.T) {
|
||||||
|
original := &Error{
|
||||||
|
Errors: []error{
|
||||||
|
errors.New("one"),
|
||||||
|
&Error{
|
||||||
|
Errors: []error{
|
||||||
|
errors.New("two"),
|
||||||
|
&Error{
|
||||||
|
Errors: []error{
|
||||||
|
errors.New("three"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := strings.TrimSpace(`
|
||||||
|
3 error(s) occurred:
|
||||||
|
|
||||||
|
* one
|
||||||
|
* two
|
||||||
|
* three
|
||||||
|
`)
|
||||||
|
actual := fmt.Sprintf("%s", Flatten(original))
|
||||||
|
|
||||||
|
if expected != actual {
|
||||||
|
t.Fatalf("expected: %s, got: %s", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFlatten_nonError(t *testing.T) {
|
||||||
|
err := errors.New("foo")
|
||||||
|
actual := Flatten(err)
|
||||||
|
if !reflect.DeepEqual(actual, err) {
|
||||||
|
t.Fatalf("bad: %#v", actual)
|
||||||
|
}
|
||||||
|
}
|
23
vendor/github.com/hashicorp/go-multierror/format_test.go
generated
vendored
Normal file
23
vendor/github.com/hashicorp/go-multierror/format_test.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestListFormatFunc(t *testing.T) {
|
||||||
|
expected := `2 error(s) occurred:
|
||||||
|
|
||||||
|
* foo
|
||||||
|
* bar`
|
||||||
|
|
||||||
|
errors := []error{
|
||||||
|
errors.New("foo"),
|
||||||
|
errors.New("bar"),
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := ListFormatFunc(errors)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad: %#v", actual)
|
||||||
|
}
|
||||||
|
}
|
70
vendor/github.com/hashicorp/go-multierror/multierror_test.go
generated
vendored
Normal file
70
vendor/github.com/hashicorp/go-multierror/multierror_test.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestError_Impl(t *testing.T) {
|
||||||
|
var _ error = new(Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorError_custom(t *testing.T) {
|
||||||
|
errors := []error{
|
||||||
|
errors.New("foo"),
|
||||||
|
errors.New("bar"),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn := func(es []error) string {
|
||||||
|
return "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
multi := &Error{Errors: errors, ErrorFormat: fn}
|
||||||
|
if multi.Error() != "foo" {
|
||||||
|
t.Fatalf("bad: %s", multi.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorError_default(t *testing.T) {
|
||||||
|
expected := `2 error(s) occurred:
|
||||||
|
|
||||||
|
* foo
|
||||||
|
* bar`
|
||||||
|
|
||||||
|
errors := []error{
|
||||||
|
errors.New("foo"),
|
||||||
|
errors.New("bar"),
|
||||||
|
}
|
||||||
|
|
||||||
|
multi := &Error{Errors: errors}
|
||||||
|
if multi.Error() != expected {
|
||||||
|
t.Fatalf("bad: %s", multi.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorErrorOrNil(t *testing.T) {
|
||||||
|
err := new(Error)
|
||||||
|
if err.ErrorOrNil() != nil {
|
||||||
|
t.Fatalf("bad: %#v", err.ErrorOrNil())
|
||||||
|
}
|
||||||
|
|
||||||
|
err.Errors = []error{errors.New("foo")}
|
||||||
|
if v := err.ErrorOrNil(); v == nil {
|
||||||
|
t.Fatal("should not be nil")
|
||||||
|
} else if !reflect.DeepEqual(v, err) {
|
||||||
|
t.Fatalf("bad: %#v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorWrappedErrors(t *testing.T) {
|
||||||
|
errors := []error{
|
||||||
|
errors.New("foo"),
|
||||||
|
errors.New("bar"),
|
||||||
|
}
|
||||||
|
|
||||||
|
multi := &Error{Errors: errors}
|
||||||
|
if !reflect.DeepEqual(multi.Errors, multi.WrappedErrors()) {
|
||||||
|
t.Fatalf("bad: %s", multi.WrappedErrors())
|
||||||
|
}
|
||||||
|
}
|
33
vendor/github.com/hashicorp/go-multierror/prefix_test.go
generated
vendored
Normal file
33
vendor/github.com/hashicorp/go-multierror/prefix_test.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPrefix_Error(t *testing.T) {
|
||||||
|
original := &Error{
|
||||||
|
Errors: []error{errors.New("foo")},
|
||||||
|
}
|
||||||
|
|
||||||
|
result := Prefix(original, "bar")
|
||||||
|
if result.(*Error).Errors[0].Error() != "bar foo" {
|
||||||
|
t.Fatalf("bad: %s", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefix_NilError(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
result := Prefix(err, "bar")
|
||||||
|
if result != nil {
|
||||||
|
t.Fatalf("bad: %#v", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefix_NonError(t *testing.T) {
|
||||||
|
original := errors.New("foo")
|
||||||
|
result := Prefix(original, "bar")
|
||||||
|
if result.Error() != "bar foo" {
|
||||||
|
t.Fatalf("bad: %s", result)
|
||||||
|
}
|
||||||
|
}
|
17
vendor/github.com/hashicorp/go-rootcerts/rootcerts_darwin_test.go
generated
vendored
Normal file
17
vendor/github.com/hashicorp/go-rootcerts/rootcerts_darwin_test.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package rootcerts
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSystemCAsOnDarwin(t *testing.T) {
|
||||||
|
_, err := LoadSystemCAs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Got error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCertKeychains(t *testing.T) {
|
||||||
|
keychains := certKeychains()
|
||||||
|
if len(keychains) != 3 {
|
||||||
|
t.Fatalf("Expected 3 keychains, got %#v", keychains)
|
||||||
|
}
|
||||||
|
}
|
52
vendor/github.com/hashicorp/go-rootcerts/rootcerts_test.go
generated
vendored
Normal file
52
vendor/github.com/hashicorp/go-rootcerts/rootcerts_test.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package rootcerts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const fixturesDir = "./test-fixtures"
|
||||||
|
|
||||||
|
func TestConfigureTLSHandlesNil(t *testing.T) {
|
||||||
|
err := ConfigureTLS(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadCACertsHandlesNil(t *testing.T) {
|
||||||
|
_, err := LoadCACerts(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadCACertsFromFile(t *testing.T) {
|
||||||
|
path := testFixture("cafile", "cacert.pem")
|
||||||
|
_, err := LoadCACerts(&Config{CAFile: path})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadCACertsFromDir(t *testing.T) {
|
||||||
|
path := testFixture("capath")
|
||||||
|
_, err := LoadCACerts(&Config{CAPath: path})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadCACertsFromDirWithSymlinks(t *testing.T) {
|
||||||
|
path := testFixture("capath-with-symlinks")
|
||||||
|
_, err := LoadCACerts(&Config{CAPath: path})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFixture(n ...string) string {
|
||||||
|
parts := []string{fixturesDir}
|
||||||
|
parts = append(parts, n...)
|
||||||
|
return filepath.Join(parts...)
|
||||||
|
}
|
28
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/cafile/cacert.pem
generated
vendored
Normal file
28
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/cafile/cacert.pem
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIExDCCA6ygAwIBAgIJAJ7PV+3kJZqZMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||||
|
VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xEjAQ
|
||||||
|
BgNVBAoTCUhhc2hpQ29ycDEUMBIGA1UECxMLRW5naW5lZXJpbmcxGzAZBgNVBAMU
|
||||||
|
EiouYXRsYXMucGhpbnplLmNvbTEhMB8GCSqGSIb3DQEJARYScGF1bEBoYXNoaWNv
|
||||||
|
cnAuY29tMB4XDTE2MDQyNzE1MjYyMVoXDTE3MDQyNzE1MjYyMVowgZwxCzAJBgNV
|
||||||
|
BAYTAlVTMREwDwYDVQQIEwhJbGxpbm9pczEQMA4GA1UEBxMHQ2hpY2FnbzESMBAG
|
||||||
|
A1UEChMJSGFzaGlDb3JwMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEbMBkGA1UEAxQS
|
||||||
|
Ki5hdGxhcy5waGluemUuY29tMSEwHwYJKoZIhvcNAQkBFhJwYXVsQGhhc2hpY29y
|
||||||
|
cC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWRXdMnsTpxpwZ
|
||||||
|
D2olsun9WO7SnMQ/SIR3DV/fttPIDHSQm2ad4r2pKEuiV+TKEFUgj/Id9bCAfQYs
|
||||||
|
jsa1qX1GmieXz+83OnK3MDEcDczpjGhSplTYGOjlxKLMhMBAOtdV5hJAYz3nwV3c
|
||||||
|
R+IQu/4213+em40shZAQRNZ2apnyE3+QB+gPlEs9Nw0OcbSKLmAiuKPbJpO+94ou
|
||||||
|
n1h0/w/+DPz6yO/fFPoA3vlisGM6B4R9U2JVwWjXrU71fU1i82ulFQdApdfUs1FP
|
||||||
|
wRrZxgX5ldUrRvFr8lJiMehdX8khO7Ue4rT6yxbI6KVM04Q5mNt1ARRLI69rN9My
|
||||||
|
pGXiItcxAgMBAAGjggEFMIIBATAdBgNVHQ4EFgQUjwsj8l0Y9HFQLH0GaJAsOHof
|
||||||
|
PhwwgdEGA1UdIwSByTCBxoAUjwsj8l0Y9HFQLH0GaJAsOHofPhyhgaKkgZ8wgZwx
|
||||||
|
CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhJbGxpbm9pczEQMA4GA1UEBxMHQ2hpY2Fn
|
||||||
|
bzESMBAGA1UEChMJSGFzaGlDb3JwMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEbMBkG
|
||||||
|
A1UEAxQSKi5hdGxhcy5waGluemUuY29tMSEwHwYJKoZIhvcNAQkBFhJwYXVsQGhh
|
||||||
|
c2hpY29ycC5jb22CCQCez1ft5CWamTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
|
||||||
|
BQUAA4IBAQC4tFfxpB8xEk9ewb5CNhhac4oKwGths+oq45DjoNtlagDMmIs2bl18
|
||||||
|
q45PIB7fuFkAz/YHcOL0UEOAiw4jbuROp9jacHxBV21lRLLmNlK1Llc3eNVvLJ38
|
||||||
|
ud6/Skilv9XyC4JNk0P5KrghxR6SOGwRuYZNqF+tthf+Bp9wJvLyfqDuJfGBal7C
|
||||||
|
ezobMoh4tp8Dh1JeQlwvJcVt2k0UFJpa57MNr78c684Bq55ow+jd6wFG0XM0MMmy
|
||||||
|
u+QRgJEGfYuYDPFEO8C8IfRyrHuV7Ll9P6eyEEFCneznXY0yJc/Gn3ZcX7ANqJsc
|
||||||
|
ueMOWw/vUnonzxAFKW+I9U9ptyVSNMLY
|
||||||
|
-----END CERTIFICATE-----
|
1
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath-with-symlinks/securetrust.pem
generated
vendored
Symbolic link
1
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath-with-symlinks/securetrust.pem
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../capath/securetrust.pem
|
1
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath-with-symlinks/thawte.pem
generated
vendored
Symbolic link
1
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath-with-symlinks/thawte.pem
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../capath/thawte.pem
|
22
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath/securetrust.pem
generated
vendored
Normal file
22
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath/securetrust.pem
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
|
||||||
|
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
|
||||||
|
FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
|
||||||
|
MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
|
||||||
|
cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
|
||||||
|
Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
|
||||||
|
0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
|
||||||
|
wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
|
||||||
|
7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
|
||||||
|
8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
|
||||||
|
BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
|
||||||
|
/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
|
||||||
|
JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
|
||||||
|
NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
|
||||||
|
6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
|
||||||
|
3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
|
||||||
|
D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
|
||||||
|
CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
|
||||||
|
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
|
||||||
|
-----END CERTIFICATE-----
|
25
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath/thawte.pem
generated
vendored
Normal file
25
vendor/github.com/hashicorp/go-rootcerts/test-fixtures/capath/thawte.pem
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
|
||||||
|
qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
|
||||||
|
Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
|
||||||
|
MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
|
||||||
|
BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
|
||||||
|
NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
|
||||||
|
LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
|
||||||
|
A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
|
||||||
|
IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
|
||||||
|
W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
|
||||||
|
3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
|
||||||
|
6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
|
||||||
|
Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
|
||||||
|
NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
|
||||||
|
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
|
||||||
|
r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
|
||||||
|
DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
|
||||||
|
YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
|
||||||
|
xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
|
||||||
|
/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
|
||||||
|
LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
|
||||||
|
jVaMaA==
|
||||||
|
-----END CERTIFICATE-----
|
1089
vendor/github.com/hashicorp/hcl/decoder_test.go
generated
vendored
Normal file
1089
vendor/github.com/hashicorp/hcl/decoder_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
200
vendor/github.com/hashicorp/hcl/hcl/ast/ast_test.go
generated
vendored
Normal file
200
vendor/github.com/hashicorp/hcl/hcl/ast/ast_test.go
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/hcl/token"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestObjectListFilter(t *testing.T) {
|
||||||
|
var cases = []struct {
|
||||||
|
Filter []string
|
||||||
|
Input []*ObjectItem
|
||||||
|
Output []*ObjectItem
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]string{"foo"},
|
||||||
|
[]*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{
|
||||||
|
Token: token.Token{Type: token.STRING, Text: `"foo"`},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
[]string{"foo"},
|
||||||
|
[]*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"foo"`}},
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"bar"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"baz"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"bar"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
input := &ObjectList{Items: tc.Input}
|
||||||
|
expected := &ObjectList{Items: tc.Output}
|
||||||
|
if actual := input.Filter(tc.Filter...); !reflect.DeepEqual(actual, expected) {
|
||||||
|
t.Fatalf("in order: input, expected, actual\n\n%#v\n\n%#v\n\n%#v", input, expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWalk(t *testing.T) {
|
||||||
|
items := []*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"foo"`}},
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"bar"`}},
|
||||||
|
},
|
||||||
|
Val: &LiteralType{Token: token.Token{Type: token.STRING, Text: `"example"`}},
|
||||||
|
},
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"baz"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
node := &ObjectList{Items: items}
|
||||||
|
|
||||||
|
order := []string{
|
||||||
|
"*ast.ObjectList",
|
||||||
|
"*ast.ObjectItem",
|
||||||
|
"*ast.ObjectKey",
|
||||||
|
"*ast.ObjectKey",
|
||||||
|
"*ast.LiteralType",
|
||||||
|
"*ast.ObjectItem",
|
||||||
|
"*ast.ObjectKey",
|
||||||
|
}
|
||||||
|
count := 0
|
||||||
|
|
||||||
|
Walk(node, func(n Node) (Node, bool) {
|
||||||
|
if n == nil {
|
||||||
|
return n, false
|
||||||
|
}
|
||||||
|
|
||||||
|
typeName := reflect.TypeOf(n).String()
|
||||||
|
if order[count] != typeName {
|
||||||
|
t.Errorf("expected '%s' got: '%s'", order[count], typeName)
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
return n, true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWalkEquality(t *testing.T) {
|
||||||
|
items := []*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"foo"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"bar"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
node := &ObjectList{Items: items}
|
||||||
|
|
||||||
|
rewritten := Walk(node, func(n Node) (Node, bool) { return n, true })
|
||||||
|
|
||||||
|
newNode, ok := rewritten.(*ObjectList)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected Objectlist, got %T", rewritten)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(node, newNode) {
|
||||||
|
t.Fatal("rewritten node is not equal to the given node")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(newNode.Items) != 2 {
|
||||||
|
t.Error("expected newNode length 2, got: %d", len(newNode.Items))
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := []string{
|
||||||
|
`"foo"`,
|
||||||
|
`"bar"`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, item := range newNode.Items {
|
||||||
|
if len(item.Keys) != 1 {
|
||||||
|
t.Error("expected keys newNode length 1, got: %d", len(item.Keys))
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Keys[0].Token.Text != expected[i] {
|
||||||
|
t.Errorf("expected key %s, got %s", expected[i], item.Keys[0].Token.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Val != nil {
|
||||||
|
t.Errorf("expected item value should be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWalkRewrite(t *testing.T) {
|
||||||
|
items := []*ObjectItem{
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"foo"`}},
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"bar"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&ObjectItem{
|
||||||
|
Keys: []*ObjectKey{
|
||||||
|
&ObjectKey{Token: token.Token{Type: token.STRING, Text: `"baz"`}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
node := &ObjectList{Items: items}
|
||||||
|
|
||||||
|
suffix := "_example"
|
||||||
|
node = Walk(node, func(n Node) (Node, bool) {
|
||||||
|
switch i := n.(type) {
|
||||||
|
case *ObjectKey:
|
||||||
|
i.Token.Text = i.Token.Text + suffix
|
||||||
|
n = i
|
||||||
|
}
|
||||||
|
return n, true
|
||||||
|
}).(*ObjectList)
|
||||||
|
|
||||||
|
Walk(node, func(n Node) (Node, bool) {
|
||||||
|
switch i := n.(type) {
|
||||||
|
case *ObjectKey:
|
||||||
|
if !strings.HasSuffix(i.Token.Text, suffix) {
|
||||||
|
t.Errorf("Token '%s' should have suffix: %s", i.Token.Text, suffix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, true
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
162
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/fmtcmd.go
generated
vendored
Normal file
162
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/fmtcmd.go
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
// Derivative work from:
|
||||||
|
// - https://golang.org/src/cmd/gofmt/gofmt.go
|
||||||
|
// - https://github.com/fatih/hclfmt
|
||||||
|
|
||||||
|
package fmtcmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/hcl/printer"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrWriteStdin = errors.New("cannot use write option with standard input")
|
||||||
|
)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
List bool // list files whose formatting differs
|
||||||
|
Write bool // write result to (source) file instead of stdout
|
||||||
|
Diff bool // display diffs of formatting changes
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidFile(f os.FileInfo, extensions []string) bool {
|
||||||
|
if !f.IsDir() && !strings.HasPrefix(f.Name(), ".") {
|
||||||
|
for _, ext := range extensions {
|
||||||
|
if strings.HasSuffix(f.Name(), "."+ext) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If in == nil, the source is the contents of the file with the given filename.
|
||||||
|
func processFile(filename string, in io.Reader, out io.Writer, stdin bool, opts Options) error {
|
||||||
|
if in == nil {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
in = f
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := ioutil.ReadAll(in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := printer.Format(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(src, res) {
|
||||||
|
// formatting has changed
|
||||||
|
if opts.List {
|
||||||
|
fmt.Fprintln(out, filename)
|
||||||
|
}
|
||||||
|
if opts.Write {
|
||||||
|
err = ioutil.WriteFile(filename, res, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if opts.Diff {
|
||||||
|
data, err := diff(src, res)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("computing diff: %s", err)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "diff a/%s b/%s\n", filename, filename)
|
||||||
|
out.Write(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !opts.List && !opts.Write && !opts.Diff {
|
||||||
|
_, err = out.Write(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func walkDir(path string, extensions []string, stdout io.Writer, opts Options) error {
|
||||||
|
visitFile := func(path string, f os.FileInfo, err error) error {
|
||||||
|
if err == nil && isValidFile(f, extensions) {
|
||||||
|
err = processFile(path, nil, stdout, false, opts)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Walk(path, visitFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run(
|
||||||
|
paths, extensions []string,
|
||||||
|
stdin io.Reader,
|
||||||
|
stdout io.Writer,
|
||||||
|
opts Options,
|
||||||
|
) error {
|
||||||
|
if len(paths) == 0 {
|
||||||
|
if opts.Write {
|
||||||
|
return ErrWriteStdin
|
||||||
|
}
|
||||||
|
if err := processFile("<standard input>", stdin, stdout, true, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, path := range paths {
|
||||||
|
switch dir, err := os.Stat(path); {
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
case dir.IsDir():
|
||||||
|
if err := walkDir(path, extensions, stdout, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if err := processFile(path, nil, stdout, false, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func diff(b1, b2 []byte) (data []byte, err error) {
|
||||||
|
f1, err := ioutil.TempFile("", "")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer os.Remove(f1.Name())
|
||||||
|
defer f1.Close()
|
||||||
|
|
||||||
|
f2, err := ioutil.TempFile("", "")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer os.Remove(f2.Name())
|
||||||
|
defer f2.Close()
|
||||||
|
|
||||||
|
f1.Write(b1)
|
||||||
|
f2.Write(b2)
|
||||||
|
|
||||||
|
data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
|
||||||
|
if len(data) > 0 {
|
||||||
|
// diff exits with a non-zero status when the files don't match.
|
||||||
|
// Ignore that failure as long as we get output.
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
440
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/fmtcmd_test.go
generated
vendored
Normal file
440
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/fmtcmd_test.go
generated
vendored
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
// +build !windows
|
||||||
|
// TODO(jen20): These need fixing on Windows but fmt is not used right now
|
||||||
|
// and red CI is making it harder to process other bugs, so ignore until
|
||||||
|
// we get around to fixing them.
|
||||||
|
|
||||||
|
package fmtcmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/testhelper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fixtureExtensions = []string{"hcl"}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sort.Sort(ByFilename(fixtures))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsValidFile(t *testing.T) {
|
||||||
|
const fixtureDir = "./test-fixtures"
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
Path string
|
||||||
|
Expected bool
|
||||||
|
}{
|
||||||
|
{"good.hcl", true},
|
||||||
|
{".hidden.ignore", false},
|
||||||
|
{"file.ignore", false},
|
||||||
|
{"dir.ignore", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
file, err := os.Stat(filepath.Join(fixtureDir, tc.Path))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if res := isValidFile(file, fixtureExtensions); res != tc.Expected {
|
||||||
|
t.Errorf("want: %b, got: %b", tc.Expected, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunMultiplePaths(t *testing.T) {
|
||||||
|
path1, err := renderFixtures("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path1)
|
||||||
|
path2, err := renderFixtures("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path2)
|
||||||
|
|
||||||
|
var expectedOut bytes.Buffer
|
||||||
|
for _, path := range []string{path1, path2} {
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
if !bytes.Equal(fixture.golden, fixture.input) {
|
||||||
|
expectedOut.WriteString(filepath.Join(path, fixture.filename) + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{path1, path2},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{
|
||||||
|
List: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if stdout.String() != expectedOut.String() {
|
||||||
|
t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunSubDirectories(t *testing.T) {
|
||||||
|
pathParent, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(pathParent)
|
||||||
|
|
||||||
|
path1, err := renderFixtures(pathParent)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
path2, err := renderFixtures(pathParent)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
paths := []string{path1, path2}
|
||||||
|
sort.Strings(paths)
|
||||||
|
|
||||||
|
var expectedOut bytes.Buffer
|
||||||
|
for _, path := range paths {
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
if !bytes.Equal(fixture.golden, fixture.input) {
|
||||||
|
expectedOut.WriteString(filepath.Join(path, fixture.filename) + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{pathParent},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{
|
||||||
|
List: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if stdout.String() != expectedOut.String() {
|
||||||
|
t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunStdin(t *testing.T) {
|
||||||
|
var expectedOut bytes.Buffer
|
||||||
|
for i, fixture := range fixtures {
|
||||||
|
if i != 0 {
|
||||||
|
expectedOut.WriteString("\n")
|
||||||
|
}
|
||||||
|
expectedOut.Write(fixture.golden)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdin, stdout := mockIO()
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
stdin.Write(fixture.input)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := Run(
|
||||||
|
[]string{},
|
||||||
|
fixtureExtensions,
|
||||||
|
stdin, stdout,
|
||||||
|
Options{},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(stdout.Bytes(), expectedOut.Bytes()) {
|
||||||
|
t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunStdinAndWrite(t *testing.T) {
|
||||||
|
var expectedOut = []byte{}
|
||||||
|
|
||||||
|
stdin, stdout := mockIO()
|
||||||
|
stdin.WriteString("")
|
||||||
|
err := Run(
|
||||||
|
[]string{}, []string{},
|
||||||
|
stdin, stdout,
|
||||||
|
Options{
|
||||||
|
Write: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != ErrWriteStdin {
|
||||||
|
t.Errorf("error want:\n%s\ngot:\n%s", ErrWriteStdin, err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(stdout.Bytes(), expectedOut) {
|
||||||
|
t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunFileError(t *testing.T) {
|
||||||
|
path, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path)
|
||||||
|
filename := filepath.Join(path, "unreadable.hcl")
|
||||||
|
|
||||||
|
var expectedError = &os.PathError{
|
||||||
|
Op: "open",
|
||||||
|
Path: filename,
|
||||||
|
Err: syscall.EACCES,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(filename, []byte{}, 0000)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{path},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{},
|
||||||
|
)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(err, expectedError) {
|
||||||
|
t.Errorf("error want: %#v, got: %#v", expectedError, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunNoOptions(t *testing.T) {
|
||||||
|
path, err := renderFixtures("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path)
|
||||||
|
|
||||||
|
var expectedOut bytes.Buffer
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
expectedOut.Write(fixture.golden)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{path},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if stdout.String() != expectedOut.String() {
|
||||||
|
t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunList(t *testing.T) {
|
||||||
|
path, err := renderFixtures("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path)
|
||||||
|
|
||||||
|
var expectedOut bytes.Buffer
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
if !bytes.Equal(fixture.golden, fixture.input) {
|
||||||
|
expectedOut.WriteString(fmt.Sprintln(filepath.Join(path, fixture.filename)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{path},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{
|
||||||
|
List: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if stdout.String() != expectedOut.String() {
|
||||||
|
t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunWrite(t *testing.T) {
|
||||||
|
path, err := renderFixtures("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path)
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{path},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{
|
||||||
|
Write: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
res, err := ioutil.ReadFile(filepath.Join(path, fixture.filename))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(res, fixture.golden) {
|
||||||
|
t.Errorf("file %q contents want:\n%s\ngot:\n%s", fixture.filename, fixture.golden, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunDiff(t *testing.T) {
|
||||||
|
path, err := renderFixtures("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(path)
|
||||||
|
|
||||||
|
var expectedOut bytes.Buffer
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
if len(fixture.diff) > 0 {
|
||||||
|
expectedOut.WriteString(
|
||||||
|
regexp.QuoteMeta(
|
||||||
|
fmt.Sprintf("diff a/%s/%s b/%s/%s\n", path, fixture.filename, path, fixture.filename),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// Need to use regex to ignore datetimes in diff.
|
||||||
|
expectedOut.WriteString(`--- .+?\n`)
|
||||||
|
expectedOut.WriteString(`\+\+\+ .+?\n`)
|
||||||
|
expectedOut.WriteString(regexp.QuoteMeta(string(fixture.diff)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutString := testhelper.Unix2dos(expectedOut.String())
|
||||||
|
|
||||||
|
_, stdout := mockIO()
|
||||||
|
err = Run(
|
||||||
|
[]string{path},
|
||||||
|
fixtureExtensions,
|
||||||
|
nil, stdout,
|
||||||
|
Options{
|
||||||
|
Diff: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(expectedOutString).Match(stdout.Bytes()) {
|
||||||
|
t.Errorf("stdout want match:\n%s\ngot:\n%q", expectedOutString, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockIO() (stdin, stdout *bytes.Buffer) {
|
||||||
|
return new(bytes.Buffer), new(bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
type fixture struct {
|
||||||
|
filename string
|
||||||
|
input, golden, diff []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type ByFilename []fixture
|
||||||
|
|
||||||
|
func (s ByFilename) Len() int { return len(s) }
|
||||||
|
func (s ByFilename) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
func (s ByFilename) Less(i, j int) bool { return len(s[i].filename) > len(s[j].filename) }
|
||||||
|
|
||||||
|
var fixtures = []fixture{
|
||||||
|
{
|
||||||
|
"noop.hcl",
|
||||||
|
[]byte(`resource "aws_security_group" "firewall" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
[]byte(`resource "aws_security_group" "firewall" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
[]byte(``),
|
||||||
|
}, {
|
||||||
|
"align_equals.hcl",
|
||||||
|
[]byte(`variable "foo" {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
[]byte(`variable "foo" {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
[]byte(`@@ -1,4 +1,4 @@
|
||||||
|
variable "foo" {
|
||||||
|
- default = "bar"
|
||||||
|
+ default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
}, {
|
||||||
|
"indentation.hcl",
|
||||||
|
[]byte(`provider "aws" {
|
||||||
|
access_key = "foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
[]byte(`provider "aws" {
|
||||||
|
access_key = "foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
[]byte(`@@ -1,4 +1,4 @@
|
||||||
|
provider "aws" {
|
||||||
|
- access_key = "foo"
|
||||||
|
- secret_key = "bar"
|
||||||
|
+ access_key = "foo"
|
||||||
|
+ secret_key = "bar"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// parent can be an empty string, in which case the system's default
|
||||||
|
// temporary directory will be used.
|
||||||
|
func renderFixtures(parent string) (path string, err error) {
|
||||||
|
path, err = ioutil.TempDir(parent, "")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fixture := range fixtures {
|
||||||
|
err = ioutil.WriteFile(filepath.Join(path, fixture.filename), []byte(fixture.input), 0644)
|
||||||
|
if err != nil {
|
||||||
|
os.RemoveAll(path)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return path, nil
|
||||||
|
}
|
1
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/.hidden.ignore
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/.hidden.ignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
invalid
|
0
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/dir.ignore
generated
vendored
Normal file
0
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/dir.ignore
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/file.ignore
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/file.ignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
invalid
|
0
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/good.hcl
generated
vendored
Normal file
0
vendor/github.com/hashicorp/hcl/hcl/fmtcmd/test-fixtures/good.hcl
generated
vendored
Normal file
9
vendor/github.com/hashicorp/hcl/hcl/parser/error_test.go
generated
vendored
Normal file
9
vendor/github.com/hashicorp/hcl/hcl/parser/error_test.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPosError_impl(t *testing.T) {
|
||||||
|
var _ error = new(PosError)
|
||||||
|
}
|
420
vendor/github.com/hashicorp/hcl/hcl/parser/parser_test.go
generated
vendored
Normal file
420
vendor/github.com/hashicorp/hcl/hcl/parser/parser_test.go
generated
vendored
Normal file
|
@ -0,0 +1,420 @@
|
||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/hcl/ast"
|
||||||
|
"github.com/hashicorp/hcl/hcl/token"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestType(t *testing.T) {
|
||||||
|
var literals = []struct {
|
||||||
|
typ token.Type
|
||||||
|
src string
|
||||||
|
}{
|
||||||
|
{token.STRING, `foo = "foo"`},
|
||||||
|
{token.NUMBER, `foo = 123`},
|
||||||
|
{token.NUMBER, `foo = -29`},
|
||||||
|
{token.FLOAT, `foo = 123.12`},
|
||||||
|
{token.FLOAT, `foo = -123.12`},
|
||||||
|
{token.BOOL, `foo = true`},
|
||||||
|
{token.HEREDOC, "foo = <<EOF\nHello\nWorld\nEOF"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range literals {
|
||||||
|
p := newParser([]byte(l.src))
|
||||||
|
item, err := p.objectItem()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lit, ok := item.Val.(*ast.LiteralType)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("node should be of type LiteralType, got: %T", item.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if lit.Token.Type != l.typ {
|
||||||
|
t.Errorf("want: %s, got: %s", l.typ, lit.Token.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListType(t *testing.T) {
|
||||||
|
var literals = []struct {
|
||||||
|
src string
|
||||||
|
tokens []token.Type
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`foo = ["123", 123]`,
|
||||||
|
[]token.Type{token.STRING, token.NUMBER},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = [123, "123",]`,
|
||||||
|
[]token.Type{token.NUMBER, token.STRING},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = []`,
|
||||||
|
[]token.Type{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = ["123", 123]`,
|
||||||
|
[]token.Type{token.STRING, token.NUMBER},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = [1,
|
||||||
|
"string",
|
||||||
|
<<EOF
|
||||||
|
heredoc contents
|
||||||
|
EOF
|
||||||
|
]`,
|
||||||
|
[]token.Type{token.NUMBER, token.STRING, token.HEREDOC},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range literals {
|
||||||
|
p := newParser([]byte(l.src))
|
||||||
|
item, err := p.objectItem()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
list, ok := item.Val.(*ast.ListType)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("node should be of type LiteralType, got: %T", item.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens := []token.Type{}
|
||||||
|
for _, li := range list.List {
|
||||||
|
if tp, ok := li.(*ast.LiteralType); ok {
|
||||||
|
tokens = append(tokens, tp.Token.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
equals(t, l.tokens, tokens)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListOfMaps(t *testing.T) {
|
||||||
|
src := `foo = [
|
||||||
|
{key = "bar"},
|
||||||
|
{key = "baz", key2 = "qux"},
|
||||||
|
]`
|
||||||
|
p := newParser([]byte(src))
|
||||||
|
|
||||||
|
file, err := p.Parse()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we make all sorts of assumptions about the input structure w/ type
|
||||||
|
// assertions. The intent is only for this to be a "smoke test" ensuring
|
||||||
|
// parsing actually performed its duty - giving this test something a bit
|
||||||
|
// more robust than _just_ "no error occurred".
|
||||||
|
expected := []string{`"bar"`, `"baz"`, `"qux"`}
|
||||||
|
actual := make([]string, 0, 3)
|
||||||
|
ol := file.Node.(*ast.ObjectList)
|
||||||
|
objItem := ol.Items[0]
|
||||||
|
list := objItem.Val.(*ast.ListType)
|
||||||
|
for _, node := range list.List {
|
||||||
|
obj := node.(*ast.ObjectType)
|
||||||
|
for _, item := range obj.List.Items {
|
||||||
|
val := item.Val.(*ast.LiteralType)
|
||||||
|
actual = append(actual, val.Token.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(expected, actual) {
|
||||||
|
t.Fatalf("Expected: %#v, got %#v", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListOfMaps_requiresComma(t *testing.T) {
|
||||||
|
src := `foo = [
|
||||||
|
{key = "bar"}
|
||||||
|
{key = "baz"}
|
||||||
|
]`
|
||||||
|
p := newParser([]byte(src))
|
||||||
|
|
||||||
|
_, err := p.Parse()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error, got none!")
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := "error parsing list, expected comma or list end"
|
||||||
|
if !strings.Contains(err.Error(), expected) {
|
||||||
|
t.Fatalf("Expected err:\n %s\nTo contain:\n %s\n", err, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestObjectType(t *testing.T) {
|
||||||
|
var literals = []struct {
|
||||||
|
src string
|
||||||
|
nodeType []ast.Node
|
||||||
|
itemLen int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`foo = {}`,
|
||||||
|
nil,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = {
|
||||||
|
bar = "fatih"
|
||||||
|
}`,
|
||||||
|
[]ast.Node{&ast.LiteralType{}},
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = {
|
||||||
|
bar = "fatih"
|
||||||
|
baz = ["arslan"]
|
||||||
|
}`,
|
||||||
|
[]ast.Node{
|
||||||
|
&ast.LiteralType{},
|
||||||
|
&ast.ListType{},
|
||||||
|
},
|
||||||
|
2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo = {
|
||||||
|
bar {}
|
||||||
|
}`,
|
||||||
|
[]ast.Node{
|
||||||
|
&ast.ObjectType{},
|
||||||
|
},
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`foo {
|
||||||
|
bar {}
|
||||||
|
foo = true
|
||||||
|
}`,
|
||||||
|
[]ast.Node{
|
||||||
|
&ast.ObjectType{},
|
||||||
|
&ast.LiteralType{},
|
||||||
|
},
|
||||||
|
2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range literals {
|
||||||
|
p := newParser([]byte(l.src))
|
||||||
|
// p.enableTrace = true
|
||||||
|
item, err := p.objectItem()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// we know that the ObjectKey name is foo for all cases, what matters
|
||||||
|
// is the object
|
||||||
|
obj, ok := item.Val.(*ast.ObjectType)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("node should be of type LiteralType, got: %T", item.Val)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the total length of items are correct
|
||||||
|
equals(t, l.itemLen, len(obj.List.Items))
|
||||||
|
|
||||||
|
// check if the types are correct
|
||||||
|
for i, item := range obj.List.Items {
|
||||||
|
equals(t, reflect.TypeOf(l.nodeType[i]), reflect.TypeOf(item.Val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestObjectKey(t *testing.T) {
|
||||||
|
keys := []struct {
|
||||||
|
exp []token.Type
|
||||||
|
src string
|
||||||
|
}{
|
||||||
|
{[]token.Type{token.IDENT}, `foo {}`},
|
||||||
|
{[]token.Type{token.IDENT}, `foo = {}`},
|
||||||
|
{[]token.Type{token.IDENT}, `foo = bar`},
|
||||||
|
{[]token.Type{token.IDENT}, `foo = 123`},
|
||||||
|
{[]token.Type{token.IDENT}, `foo = "${var.bar}`},
|
||||||
|
{[]token.Type{token.STRING}, `"foo" {}`},
|
||||||
|
{[]token.Type{token.STRING}, `"foo" = {}`},
|
||||||
|
{[]token.Type{token.STRING}, `"foo" = "${var.bar}`},
|
||||||
|
{[]token.Type{token.IDENT, token.IDENT}, `foo bar {}`},
|
||||||
|
{[]token.Type{token.IDENT, token.STRING}, `foo "bar" {}`},
|
||||||
|
{[]token.Type{token.STRING, token.IDENT}, `"foo" bar {}`},
|
||||||
|
{[]token.Type{token.IDENT, token.IDENT, token.IDENT}, `foo bar baz {}`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
|
p := newParser([]byte(k.src))
|
||||||
|
keys, err := p.objectKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens := []token.Type{}
|
||||||
|
for _, o := range keys {
|
||||||
|
tokens = append(tokens, o.Token.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
equals(t, k.exp, tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
errKeys := []struct {
|
||||||
|
src string
|
||||||
|
}{
|
||||||
|
{`foo 12 {}`},
|
||||||
|
{`foo bar = {}`},
|
||||||
|
{`foo []`},
|
||||||
|
{`12 {}`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range errKeys {
|
||||||
|
p := newParser([]byte(k.src))
|
||||||
|
_, err := p.objectKey()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("case '%s' should give an error", k.src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Official HCL tests
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Name string
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"assign_colon.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment_lastline.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment_single.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"empty.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"list_comma.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object_list_comma.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"structure.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"structure_basic.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"structure_empty.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"complex.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"types.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"array_comment.hcl",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"array_comment_2.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"missing_braces.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"unterminated_object.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"unterminated_object_2.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key_without_value.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object_key_without_value.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const fixtureDir = "./test-fixtures"
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Name))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = Parse(d)
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("Input: %s\n\nError: %s", tc.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParse_inline(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{"t t e{{}}", true},
|
||||||
|
{"o{{}}", true},
|
||||||
|
{"t t e d N{{}}", true},
|
||||||
|
{"t t e d{{}}", true},
|
||||||
|
{"N{}N{{}}", true},
|
||||||
|
{"v\nN{{}}", true},
|
||||||
|
{"v=/\n[,", true},
|
||||||
|
{"v=10kb", true},
|
||||||
|
{"v=/foo", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Logf("Testing: %q", tc.Value)
|
||||||
|
ast, err := Parse([]byte(tc.Value))
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("Input: %q\n\nError: %s\n\nAST: %#v", tc.Value, err, ast)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// equals fails the test if exp is not equal to act.
|
||||||
|
func equals(tb testing.TB, exp, act interface{}) {
|
||||||
|
if !reflect.DeepEqual(exp, act) {
|
||||||
|
_, file, line, _ := runtime.Caller(1)
|
||||||
|
fmt.Printf("\033[31m%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act)
|
||||||
|
tb.FailNow()
|
||||||
|
}
|
||||||
|
}
|
4
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/array_comment.hcl
generated
vendored
Normal file
4
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/array_comment.hcl
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
foo = [
|
||||||
|
"1",
|
||||||
|
"2", # comment
|
||||||
|
]
|
6
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/array_comment_2.hcl
generated
vendored
Normal file
6
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/array_comment_2.hcl
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
scripts = [
|
||||||
|
"${path.module}/scripts/install-consul.sh" // missing comma
|
||||||
|
"${path.module}/scripts/install-haproxy.sh"
|
||||||
|
]
|
||||||
|
}
|
6
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/assign_colon.hcl
generated
vendored
Normal file
6
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/assign_colon.hcl
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
resource = [{
|
||||||
|
"foo": {
|
||||||
|
"bar": {},
|
||||||
|
"baz": [1, 2, "foo"],
|
||||||
|
}
|
||||||
|
}]
|
5
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/assign_deep.hcl
generated
vendored
Normal file
5
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/assign_deep.hcl
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
resource = [{
|
||||||
|
foo = [{
|
||||||
|
bar = {}
|
||||||
|
}]
|
||||||
|
}]
|
15
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/comment.hcl
generated
vendored
Normal file
15
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/comment.hcl
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Foo
|
||||||
|
|
||||||
|
/* Bar */
|
||||||
|
|
||||||
|
/*
|
||||||
|
/*
|
||||||
|
Baz
|
||||||
|
*/
|
||||||
|
|
||||||
|
# Another
|
||||||
|
|
||||||
|
# Multiple
|
||||||
|
# Lines
|
||||||
|
|
||||||
|
foo = "bar"
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/comment_lastline.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/comment_lastline.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#foo
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/comment_single.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/comment_single.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Hello
|
42
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/complex.hcl
generated
vendored
Normal file
42
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/complex.hcl
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
variable "foo" {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "groups" { }
|
||||||
|
|
||||||
|
provider "aws" {
|
||||||
|
access_key = "foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "do" {
|
||||||
|
api_key = "${var.foo}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "firewall" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
resource aws_instance "web" {
|
||||||
|
ami = "${var.foo}"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"${aws_security_group.firewall.foo}",
|
||||||
|
"${element(split(\",\", var.groups)}",
|
||||||
|
]
|
||||||
|
network_interface = {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "db" {
|
||||||
|
security_groups = "${aws_security_group.firewall.*.id}"
|
||||||
|
VPC = "foo"
|
||||||
|
depends_on = ["aws_instance.web"]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "web_ip" {
|
||||||
|
value = "${aws_instance.web.private_ip}"
|
||||||
|
}
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/complex_key.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/complex_key.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo.bar = "baz"
|
0
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/empty.hcl
generated
vendored
Normal file
0
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/empty.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/key_without_value.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/key_without_value.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/list.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/list.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo = [1, 2, "foo"]
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/list_comma.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/list_comma.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo = [1, 2, "foo",]
|
4
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/missing_braces.hcl
generated
vendored
Normal file
4
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/missing_braces.hcl
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# should error, but not crash
|
||||||
|
resource "template_file" "cloud_config" {
|
||||||
|
template = "$file("${path.module}/some/path")"
|
||||||
|
}
|
2
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/multiple.hcl
generated
vendored
Normal file
2
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/multiple.hcl
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
foo = "bar"
|
||||||
|
key = 7
|
3
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/object_key_without_value.hcl
generated
vendored
Normal file
3
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/object_key_without_value.hcl
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
foo {
|
||||||
|
bar
|
||||||
|
}
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/object_list_comma.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/object_list_comma.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo = {one = 1, two = 2}
|
3
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/old.hcl
generated
vendored
Normal file
3
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/old.hcl
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
default = {
|
||||||
|
"eu-west-1": "ami-b1cf19c6",
|
||||||
|
}
|
5
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/structure.hcl
generated
vendored
Normal file
5
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/structure.hcl
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// This is a test structure for the lexer
|
||||||
|
foo bar "baz" {
|
||||||
|
key = 7
|
||||||
|
foo = "bar"
|
||||||
|
}
|
5
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/structure_basic.hcl
generated
vendored
Normal file
5
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/structure_basic.hcl
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
foo {
|
||||||
|
value = 7
|
||||||
|
"value" = 8
|
||||||
|
"complex::value" = 9
|
||||||
|
}
|
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/structure_empty.hcl
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/structure_empty.hcl
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
resource "foo" "bar" {}
|
7
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/types.hcl
generated
vendored
Normal file
7
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/types.hcl
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
foo = "bar"
|
||||||
|
bar = 7
|
||||||
|
baz = [1,2,3]
|
||||||
|
foo = -12
|
||||||
|
bar = 3.14159
|
||||||
|
foo = true
|
||||||
|
bar = false
|
2
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/unterminated_object.hcl
generated
vendored
Normal file
2
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/unterminated_object.hcl
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
foo "baz" {
|
||||||
|
bar = "baz"
|
6
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/unterminated_object_2.hcl
generated
vendored
Normal file
6
vendor/github.com/hashicorp/hcl/hcl/parser/test-fixtures/unterminated_object_2.hcl
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
resource "aws_eip" "EIP1" { a { a { a { a { a {
|
||||||
|
count = "1"
|
||||||
|
|
||||||
|
resource "aws_eip" "EIP2" {
|
||||||
|
count = "1"
|
||||||
|
}
|
590
vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
generated
vendored
Normal file
590
vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
generated
vendored
Normal file
|
@ -0,0 +1,590 @@
|
||||||
|
package printer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/hcl/ast"
|
||||||
|
"github.com/hashicorp/hcl/hcl/token"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
blank = byte(' ')
|
||||||
|
newline = byte('\n')
|
||||||
|
tab = byte('\t')
|
||||||
|
infinity = 1 << 30 // offset or line
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
unindent = []byte("\uE123") // in the private use space
|
||||||
|
)
|
||||||
|
|
||||||
|
type printer struct {
|
||||||
|
cfg Config
|
||||||
|
prev token.Pos
|
||||||
|
|
||||||
|
comments []*ast.CommentGroup // may be nil, contains all comments
|
||||||
|
standaloneComments []*ast.CommentGroup // contains all standalone comments (not assigned to any node)
|
||||||
|
|
||||||
|
enableTrace bool
|
||||||
|
indentTrace int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ByPosition []*ast.CommentGroup
|
||||||
|
|
||||||
|
func (b ByPosition) Len() int { return len(b) }
|
||||||
|
func (b ByPosition) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
||||||
|
func (b ByPosition) Less(i, j int) bool { return b[i].Pos().Before(b[j].Pos()) }
|
||||||
|
|
||||||
|
// collectComments comments all standalone comments which are not lead or line
|
||||||
|
// comment
|
||||||
|
func (p *printer) collectComments(node ast.Node) {
|
||||||
|
// first collect all comments. This is already stored in
|
||||||
|
// ast.File.(comments)
|
||||||
|
ast.Walk(node, func(nn ast.Node) (ast.Node, bool) {
|
||||||
|
switch t := nn.(type) {
|
||||||
|
case *ast.File:
|
||||||
|
p.comments = t.Comments
|
||||||
|
return nn, false
|
||||||
|
}
|
||||||
|
return nn, true
|
||||||
|
})
|
||||||
|
|
||||||
|
standaloneComments := make(map[token.Pos]*ast.CommentGroup, 0)
|
||||||
|
for _, c := range p.comments {
|
||||||
|
standaloneComments[c.Pos()] = c
|
||||||
|
}
|
||||||
|
|
||||||
|
// next remove all lead and line comments from the overall comment map.
|
||||||
|
// This will give us comments which are standalone, comments which are not
|
||||||
|
// assigned to any kind of node.
|
||||||
|
ast.Walk(node, func(nn ast.Node) (ast.Node, bool) {
|
||||||
|
switch t := nn.(type) {
|
||||||
|
case *ast.LiteralType:
|
||||||
|
if t.LineComment != nil {
|
||||||
|
for _, comment := range t.LineComment.List {
|
||||||
|
if _, ok := standaloneComments[comment.Pos()]; ok {
|
||||||
|
delete(standaloneComments, comment.Pos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *ast.ObjectItem:
|
||||||
|
if t.LeadComment != nil {
|
||||||
|
for _, comment := range t.LeadComment.List {
|
||||||
|
if _, ok := standaloneComments[comment.Pos()]; ok {
|
||||||
|
delete(standaloneComments, comment.Pos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.LineComment != nil {
|
||||||
|
for _, comment := range t.LineComment.List {
|
||||||
|
if _, ok := standaloneComments[comment.Pos()]; ok {
|
||||||
|
delete(standaloneComments, comment.Pos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nn, true
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, c := range standaloneComments {
|
||||||
|
p.standaloneComments = append(p.standaloneComments, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(ByPosition(p.standaloneComments))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// output prints creates b printable HCL output and returns it.
|
||||||
|
func (p *printer) output(n interface{}) []byte {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
switch t := n.(type) {
|
||||||
|
case *ast.File:
|
||||||
|
return p.output(t.Node)
|
||||||
|
case *ast.ObjectList:
|
||||||
|
var index int
|
||||||
|
var nextItem token.Pos
|
||||||
|
var commented bool
|
||||||
|
for {
|
||||||
|
// TODO(arslan): refactor below comment printing, we have the same in objectType
|
||||||
|
for _, c := range p.standaloneComments {
|
||||||
|
for _, comment := range c.List {
|
||||||
|
if index != len(t.Items) {
|
||||||
|
nextItem = t.Items[index].Pos()
|
||||||
|
} else {
|
||||||
|
nextItem = token.Pos{Offset: infinity, Line: infinity}
|
||||||
|
}
|
||||||
|
|
||||||
|
if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) {
|
||||||
|
// if we hit the end add newlines so we can print the comment
|
||||||
|
if index == len(t.Items) {
|
||||||
|
buf.Write([]byte{newline, newline})
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
if index != len(t.Items) {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == len(t.Items) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(p.output(t.Items[index]))
|
||||||
|
if !commented && index != len(t.Items)-1 {
|
||||||
|
buf.Write([]byte{newline, newline})
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
case *ast.ObjectKey:
|
||||||
|
buf.WriteString(t.Token.Text)
|
||||||
|
case *ast.ObjectItem:
|
||||||
|
p.prev = t.Pos()
|
||||||
|
buf.Write(p.objectItem(t))
|
||||||
|
case *ast.LiteralType:
|
||||||
|
buf.Write(p.literalType(t))
|
||||||
|
case *ast.ListType:
|
||||||
|
buf.Write(p.list(t))
|
||||||
|
case *ast.ObjectType:
|
||||||
|
buf.Write(p.objectType(t))
|
||||||
|
default:
|
||||||
|
fmt.Printf(" unknown type: %T\n", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *printer) literalType(lit *ast.LiteralType) []byte {
|
||||||
|
result := []byte(lit.Token.Text)
|
||||||
|
if lit.Token.Type == token.HEREDOC {
|
||||||
|
// Clear the trailing newline from heredocs
|
||||||
|
if result[len(result)-1] == '\n' {
|
||||||
|
result = result[:len(result)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poison lines 2+ so that we don't indent them
|
||||||
|
result = p.heredocIndent(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// objectItem returns the printable HCL form of an object item. An object type
|
||||||
|
// starts with one/multiple keys and has a value. The value might be of any
|
||||||
|
// type.
|
||||||
|
func (p *printer) objectItem(o *ast.ObjectItem) []byte {
|
||||||
|
defer un(trace(p, fmt.Sprintf("ObjectItem: %s", o.Keys[0].Token.Text)))
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
if o.LeadComment != nil {
|
||||||
|
for _, comment := range o.LeadComment.List {
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, k := range o.Keys {
|
||||||
|
buf.WriteString(k.Token.Text)
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
|
||||||
|
// reach end of key
|
||||||
|
if o.Assign.IsValid() && i == len(o.Keys)-1 && len(o.Keys) == 1 {
|
||||||
|
buf.WriteString("=")
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(p.output(o.Val))
|
||||||
|
|
||||||
|
if o.Val.Pos().Line == o.Keys[0].Pos().Line && o.LineComment != nil {
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
for _, comment := range o.LineComment.List {
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// objectType returns the printable HCL form of an object type. An object type
|
||||||
|
// begins with a brace and ends with a brace.
|
||||||
|
func (p *printer) objectType(o *ast.ObjectType) []byte {
|
||||||
|
defer un(trace(p, "ObjectType"))
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.WriteString("{")
|
||||||
|
|
||||||
|
var index int
|
||||||
|
var nextItem token.Pos
|
||||||
|
var commented, newlinePrinted bool
|
||||||
|
for {
|
||||||
|
|
||||||
|
// Print stand alone comments
|
||||||
|
for _, c := range p.standaloneComments {
|
||||||
|
for _, comment := range c.List {
|
||||||
|
// if we hit the end, last item should be the brace
|
||||||
|
if index != len(o.List.Items) {
|
||||||
|
nextItem = o.List.Items[index].Pos()
|
||||||
|
} else {
|
||||||
|
nextItem = o.Rbrace
|
||||||
|
}
|
||||||
|
|
||||||
|
if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) {
|
||||||
|
// If there are standalone comments and the initial newline has not
|
||||||
|
// been printed yet, do it now.
|
||||||
|
if !newlinePrinted {
|
||||||
|
newlinePrinted = true
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add newline if it's between other printed nodes
|
||||||
|
if index > 0 {
|
||||||
|
commented = true
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(p.indent([]byte(comment.Text)))
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
if index != len(o.List.Items) {
|
||||||
|
buf.WriteByte(newline) // do not print on the end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == len(o.List.Items) {
|
||||||
|
p.prev = o.Rbrace
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we are sure that it's not a totally empty block: print
|
||||||
|
// the initial newline if it hasn't been printed yet by the previous
|
||||||
|
// block about standalone comments.
|
||||||
|
if !newlinePrinted {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
newlinePrinted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we have adjacent one liner items. If yes we'll going to align
|
||||||
|
// the comments.
|
||||||
|
var aligned []*ast.ObjectItem
|
||||||
|
for _, item := range o.List.Items[index:] {
|
||||||
|
// we don't group one line lists
|
||||||
|
if len(o.List.Items) == 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// one means a oneliner with out any lead comment
|
||||||
|
// two means a oneliner with lead comment
|
||||||
|
// anything else might be something else
|
||||||
|
cur := lines(string(p.objectItem(item)))
|
||||||
|
if cur > 2 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
curPos := item.Pos()
|
||||||
|
|
||||||
|
nextPos := token.Pos{}
|
||||||
|
if index != len(o.List.Items)-1 {
|
||||||
|
nextPos = o.List.Items[index+1].Pos()
|
||||||
|
}
|
||||||
|
|
||||||
|
prevPos := token.Pos{}
|
||||||
|
if index != 0 {
|
||||||
|
prevPos = o.List.Items[index-1].Pos()
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Println("DEBUG ----------------")
|
||||||
|
// fmt.Printf("prev = %+v prevPos: %s\n", prev, prevPos)
|
||||||
|
// fmt.Printf("cur = %+v curPos: %s\n", cur, curPos)
|
||||||
|
// fmt.Printf("next = %+v nextPos: %s\n", next, nextPos)
|
||||||
|
|
||||||
|
if curPos.Line+1 == nextPos.Line {
|
||||||
|
aligned = append(aligned, item)
|
||||||
|
index++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if curPos.Line-1 == prevPos.Line {
|
||||||
|
aligned = append(aligned, item)
|
||||||
|
index++
|
||||||
|
|
||||||
|
// finish if we have a new line or comment next. This happens
|
||||||
|
// if the next item is not adjacent
|
||||||
|
if curPos.Line+1 != nextPos.Line {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// put newlines if the items are between other non aligned items.
|
||||||
|
// newlines are also added if there is a standalone comment already, so
|
||||||
|
// check it too
|
||||||
|
if !commented && index != len(aligned) {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(aligned) >= 1 {
|
||||||
|
p.prev = aligned[len(aligned)-1].Pos()
|
||||||
|
|
||||||
|
items := p.alignedItems(aligned)
|
||||||
|
buf.Write(p.indent(items))
|
||||||
|
} else {
|
||||||
|
p.prev = o.List.Items[index].Pos()
|
||||||
|
|
||||||
|
buf.Write(p.indent(p.objectItem(o.List.Items[index])))
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteString("}")
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *printer) alignedItems(items []*ast.ObjectItem) []byte {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
// find the longest key and value length, needed for alignment
|
||||||
|
var longestKeyLen int // longest key length
|
||||||
|
var longestValLen int // longest value length
|
||||||
|
for _, item := range items {
|
||||||
|
key := len(item.Keys[0].Token.Text)
|
||||||
|
val := len(p.output(item.Val))
|
||||||
|
|
||||||
|
if key > longestKeyLen {
|
||||||
|
longestKeyLen = key
|
||||||
|
}
|
||||||
|
|
||||||
|
if val > longestValLen {
|
||||||
|
longestValLen = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, item := range items {
|
||||||
|
if item.LeadComment != nil {
|
||||||
|
for _, comment := range item.LeadComment.List {
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, k := range item.Keys {
|
||||||
|
keyLen := len(k.Token.Text)
|
||||||
|
buf.WriteString(k.Token.Text)
|
||||||
|
for i := 0; i < longestKeyLen-keyLen+1; i++ {
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reach end of key
|
||||||
|
if i == len(item.Keys)-1 && len(item.Keys) == 1 {
|
||||||
|
buf.WriteString("=")
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val := p.output(item.Val)
|
||||||
|
valLen := len(val)
|
||||||
|
buf.Write(val)
|
||||||
|
|
||||||
|
if item.Val.Pos().Line == item.Keys[0].Pos().Line && item.LineComment != nil {
|
||||||
|
for i := 0; i < longestValLen-valLen+1; i++ {
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, comment := range item.LineComment.List {
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not print for the last item
|
||||||
|
if i != len(items)-1 {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// list returns the printable HCL form of an list type.
|
||||||
|
func (p *printer) list(l *ast.ListType) []byte {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.WriteString("[")
|
||||||
|
|
||||||
|
var longestLine int
|
||||||
|
for _, item := range l.List {
|
||||||
|
// for now we assume that the list only contains literal types
|
||||||
|
if lit, ok := item.(*ast.LiteralType); ok {
|
||||||
|
lineLen := len(lit.Token.Text)
|
||||||
|
if lineLen > longestLine {
|
||||||
|
longestLine = lineLen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insertSpaceBeforeItem := false
|
||||||
|
for i, item := range l.List {
|
||||||
|
if item.Pos().Line != l.Lbrack.Line {
|
||||||
|
// multiline list, add newline before we add each item
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
insertSpaceBeforeItem = false
|
||||||
|
// also indent each line
|
||||||
|
val := p.output(item)
|
||||||
|
curLen := len(val)
|
||||||
|
buf.Write(p.indent(val))
|
||||||
|
buf.WriteString(",")
|
||||||
|
|
||||||
|
if lit, ok := item.(*ast.LiteralType); ok && lit.LineComment != nil {
|
||||||
|
// if the next item doesn't have any comments, do not align
|
||||||
|
buf.WriteByte(blank) // align one space
|
||||||
|
for i := 0; i < longestLine-curLen; i++ {
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, comment := range lit.LineComment.List {
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == len(l.List)-1 {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if insertSpaceBeforeItem {
|
||||||
|
buf.WriteByte(blank)
|
||||||
|
insertSpaceBeforeItem = false
|
||||||
|
}
|
||||||
|
buf.Write(p.output(item))
|
||||||
|
if i != len(l.List)-1 {
|
||||||
|
buf.WriteString(",")
|
||||||
|
insertSpaceBeforeItem = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteString("]")
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// indent indents the lines of the given buffer for each non-empty line
|
||||||
|
func (p *printer) indent(buf []byte) []byte {
|
||||||
|
var prefix []byte
|
||||||
|
if p.cfg.SpacesWidth != 0 {
|
||||||
|
for i := 0; i < p.cfg.SpacesWidth; i++ {
|
||||||
|
prefix = append(prefix, blank)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prefix = []byte{tab}
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []byte
|
||||||
|
bol := true
|
||||||
|
for _, c := range buf {
|
||||||
|
if bol && c != '\n' {
|
||||||
|
res = append(res, prefix...)
|
||||||
|
}
|
||||||
|
|
||||||
|
res = append(res, c)
|
||||||
|
bol = c == '\n'
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// unindent removes all the indentation from the tombstoned lines
|
||||||
|
func (p *printer) unindent(buf []byte) []byte {
|
||||||
|
var res []byte
|
||||||
|
for i := 0; i < len(buf); i++ {
|
||||||
|
skip := len(buf)-i <= len(unindent)
|
||||||
|
if !skip {
|
||||||
|
skip = !bytes.Equal(unindent, buf[i:i+len(unindent)])
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
res = append(res, buf[i])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have a marker. we have to backtrace here and clean out
|
||||||
|
// any whitespace ahead of our tombstone up to a \n
|
||||||
|
for j := len(res) - 1; j >= 0; j-- {
|
||||||
|
if res[j] == '\n' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
res = res[:j]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the entire unindent marker
|
||||||
|
i += len(unindent) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// heredocIndent marks all the 2nd and further lines as unindentable
|
||||||
|
func (p *printer) heredocIndent(buf []byte) []byte {
|
||||||
|
var res []byte
|
||||||
|
bol := false
|
||||||
|
for _, c := range buf {
|
||||||
|
if bol && c != '\n' {
|
||||||
|
res = append(res, unindent...)
|
||||||
|
}
|
||||||
|
res = append(res, c)
|
||||||
|
bol = c == '\n'
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func lines(txt string) int {
|
||||||
|
endline := 1
|
||||||
|
for i := 0; i < len(txt); i++ {
|
||||||
|
if txt[i] == '\n' {
|
||||||
|
endline++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return endline
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Tracing support
|
||||||
|
|
||||||
|
func (p *printer) printTrace(a ...interface{}) {
|
||||||
|
if !p.enableTrace {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
|
||||||
|
const n = len(dots)
|
||||||
|
i := 2 * p.indentTrace
|
||||||
|
for i > n {
|
||||||
|
fmt.Print(dots)
|
||||||
|
i -= n
|
||||||
|
}
|
||||||
|
// i <= n
|
||||||
|
fmt.Print(dots[0:i])
|
||||||
|
fmt.Println(a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func trace(p *printer, msg string) *printer {
|
||||||
|
p.printTrace(msg, "(")
|
||||||
|
p.indentTrace++
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage pattern: defer un(trace(p, "..."))
|
||||||
|
func un(p *printer) {
|
||||||
|
p.indentTrace--
|
||||||
|
p.printTrace(")")
|
||||||
|
}
|
67
vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
generated
vendored
Normal file
67
vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// Package printer implements printing of AST nodes to HCL format.
|
||||||
|
package printer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/hcl/ast"
|
||||||
|
"github.com/hashicorp/hcl/hcl/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DefaultConfig = Config{
|
||||||
|
SpacesWidth: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Config node controls the output of Fprint.
|
||||||
|
type Config struct {
|
||||||
|
SpacesWidth int // if set, it will use spaces instead of tabs for alignment
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Fprint(output io.Writer, node ast.Node) error {
|
||||||
|
p := &printer{
|
||||||
|
cfg: *c,
|
||||||
|
comments: make([]*ast.CommentGroup, 0),
|
||||||
|
standaloneComments: make([]*ast.CommentGroup, 0),
|
||||||
|
// enableTrace: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
p.collectComments(node)
|
||||||
|
|
||||||
|
if _, err := output.Write(p.unindent(p.output(node))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// flush tabwriter, if any
|
||||||
|
var err error
|
||||||
|
if tw, _ := output.(*tabwriter.Writer); tw != nil {
|
||||||
|
err = tw.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprint "pretty-prints" an HCL node to output
|
||||||
|
// It calls Config.Fprint with default settings.
|
||||||
|
func Fprint(output io.Writer, node ast.Node) error {
|
||||||
|
return DefaultConfig.Fprint(output, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format formats src HCL and returns the result.
|
||||||
|
func Format(src []byte) ([]byte, error) {
|
||||||
|
node, err := parser.Parse(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := DefaultConfig.Fprint(&buf, node); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add trailing newline to result
|
||||||
|
buf.WriteString("\n")
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
140
vendor/github.com/hashicorp/hcl/hcl/printer/printer_test.go
generated
vendored
Normal file
140
vendor/github.com/hashicorp/hcl/hcl/printer/printer_test.go
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
// +build !windows
|
||||||
|
// TODO(jen20): These need fixing on Windows but printer is not used right now
|
||||||
|
// and red CI is making it harder to process other bugs, so ignore until
|
||||||
|
// we get around to fixing them.package printer
|
||||||
|
|
||||||
|
package printer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/hcl/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
var update = flag.Bool("update", false, "update golden files")
|
||||||
|
|
||||||
|
const (
|
||||||
|
dataDir = "testdata"
|
||||||
|
)
|
||||||
|
|
||||||
|
type entry struct {
|
||||||
|
source, golden string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use go test -update to create/update the respective golden files.
|
||||||
|
var data = []entry{
|
||||||
|
{"complexhcl.input", "complexhcl.golden"},
|
||||||
|
{"list.input", "list.golden"},
|
||||||
|
{"comment.input", "comment.golden"},
|
||||||
|
{"comment_aligned.input", "comment_aligned.golden"},
|
||||||
|
{"comment_standalone.input", "comment_standalone.golden"},
|
||||||
|
{"empty_block.input", "empty_block.golden"},
|
||||||
|
{"list_of_objects.input", "list_of_objects.golden"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFiles(t *testing.T) {
|
||||||
|
for _, e := range data {
|
||||||
|
source := filepath.Join(dataDir, e.source)
|
||||||
|
golden := filepath.Join(dataDir, e.golden)
|
||||||
|
check(t, source, golden)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(t *testing.T, source, golden string) {
|
||||||
|
src, err := ioutil.ReadFile(source)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := format(src)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// update golden files if necessary
|
||||||
|
if *update {
|
||||||
|
if err := ioutil.WriteFile(golden, res, 0644); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get golden
|
||||||
|
gld, err := ioutil.ReadFile(golden)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatted source and golden must be the same
|
||||||
|
if err := diff(source, golden, res, gld); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// diff compares a and b.
|
||||||
|
func diff(aname, bname string, a, b []byte) error {
|
||||||
|
var buf bytes.Buffer // holding long error message
|
||||||
|
|
||||||
|
// compare lengths
|
||||||
|
if len(a) != len(b) {
|
||||||
|
fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare contents
|
||||||
|
line := 1
|
||||||
|
offs := 1
|
||||||
|
for i := 0; i < len(a) && i < len(b); i++ {
|
||||||
|
ch := a[i]
|
||||||
|
if ch != b[i] {
|
||||||
|
fmt.Fprintf(&buf, "\n%s:%d:%d: %s", aname, line, i-offs+1, lineAt(a, offs))
|
||||||
|
fmt.Fprintf(&buf, "\n%s:%d:%d: %s", bname, line, i-offs+1, lineAt(b, offs))
|
||||||
|
fmt.Fprintf(&buf, "\n\n")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ch == '\n' {
|
||||||
|
line++
|
||||||
|
offs = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if buf.Len() > 0 {
|
||||||
|
return errors.New(buf.String())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// format parses src, prints the corresponding AST, verifies the resulting
|
||||||
|
// src is syntactically correct, and returns the resulting src or an error
|
||||||
|
// if any.
|
||||||
|
func format(src []byte) ([]byte, error) {
|
||||||
|
formatted, err := Format(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure formatted output is syntactically correct
|
||||||
|
if _, err := parser.Parse(formatted); err != nil {
|
||||||
|
return nil, fmt.Errorf("parse: %s\n%s", err, src)
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatted, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// lineAt returns the line in text starting at offset offs.
|
||||||
|
func lineAt(text []byte, offs int) []byte {
|
||||||
|
i := offs
|
||||||
|
for i < len(text) && text[i] != '\n' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return text[offs:i]
|
||||||
|
}
|
36
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.golden
generated
vendored
Normal file
36
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.golden
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// A standalone comment is a comment which is not attached to any kind of node
|
||||||
|
|
||||||
|
// This comes from Terraform, as a test
|
||||||
|
variable "foo" {
|
||||||
|
# Standalone comment should be still here
|
||||||
|
|
||||||
|
default = "bar"
|
||||||
|
description = "bar" # yooo
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a multi line standalone
|
||||||
|
comment*/
|
||||||
|
|
||||||
|
// fatih arslan
|
||||||
|
/* This is a developer test
|
||||||
|
account and a multine comment */
|
||||||
|
developer = ["fatih", "arslan"] // fatih arslan
|
||||||
|
|
||||||
|
# One line here
|
||||||
|
numbers = [1, 2] // another line here
|
||||||
|
|
||||||
|
# Another comment
|
||||||
|
variable = {
|
||||||
|
description = "bar" # another yooo
|
||||||
|
|
||||||
|
foo {
|
||||||
|
# Nested standalone
|
||||||
|
|
||||||
|
bar = "fatih"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lead comment
|
||||||
|
foo {
|
||||||
|
bar = "fatih" // line comment 2
|
||||||
|
} // line comment 3
|
37
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.input
generated
vendored
Normal file
37
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.input
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// A standalone comment is a comment which is not attached to any kind of node
|
||||||
|
|
||||||
|
// This comes from Terraform, as a test
|
||||||
|
variable "foo" {
|
||||||
|
# Standalone comment should be still here
|
||||||
|
|
||||||
|
default = "bar"
|
||||||
|
description = "bar" # yooo
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a multi line standalone
|
||||||
|
comment*/
|
||||||
|
|
||||||
|
|
||||||
|
// fatih arslan
|
||||||
|
/* This is a developer test
|
||||||
|
account and a multine comment */
|
||||||
|
developer = [ "fatih", "arslan"] // fatih arslan
|
||||||
|
|
||||||
|
# One line here
|
||||||
|
numbers = [1,2] // another line here
|
||||||
|
|
||||||
|
# Another comment
|
||||||
|
variable = {
|
||||||
|
description = "bar" # another yooo
|
||||||
|
foo {
|
||||||
|
# Nested standalone
|
||||||
|
|
||||||
|
bar = "fatih"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lead comment
|
||||||
|
foo {
|
||||||
|
bar = "fatih" // line comment 2
|
||||||
|
} // line comment 3
|
||||||
|
|
32
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.golden
generated
vendored
Normal file
32
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.golden
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
aligned {
|
||||||
|
# We have some aligned items below
|
||||||
|
foo = "fatih" # yoo1
|
||||||
|
default = "bar" # yoo2
|
||||||
|
bar = "bar and foo" # yoo3
|
||||||
|
|
||||||
|
default = {
|
||||||
|
bar = "example"
|
||||||
|
}
|
||||||
|
|
||||||
|
#deneme arslan
|
||||||
|
fatih = ["fatih"] # yoo4
|
||||||
|
|
||||||
|
#fatih arslan
|
||||||
|
fatiharslan = ["arslan"] // yoo5
|
||||||
|
|
||||||
|
default = {
|
||||||
|
bar = "example"
|
||||||
|
}
|
||||||
|
|
||||||
|
security_groups = [
|
||||||
|
"foo", # kenya 1
|
||||||
|
"${aws_security_group.firewall.foo}", # kenya 2
|
||||||
|
]
|
||||||
|
|
||||||
|
security_groups2 = [
|
||||||
|
"foo", # kenya 1
|
||||||
|
"bar", # kenya 1.5
|
||||||
|
"${aws_security_group.firewall.foo}", # kenya 2
|
||||||
|
"foobar", # kenya 3
|
||||||
|
]
|
||||||
|
}
|
28
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.input
generated
vendored
Normal file
28
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.input
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
aligned {
|
||||||
|
# We have some aligned items below
|
||||||
|
foo = "fatih" # yoo1
|
||||||
|
default = "bar" # yoo2
|
||||||
|
bar = "bar and foo" # yoo3
|
||||||
|
default = {
|
||||||
|
bar = "example"
|
||||||
|
}
|
||||||
|
#deneme arslan
|
||||||
|
fatih = ["fatih"] # yoo4
|
||||||
|
#fatih arslan
|
||||||
|
fatiharslan = ["arslan"] // yoo5
|
||||||
|
default = {
|
||||||
|
bar = "example"
|
||||||
|
}
|
||||||
|
|
||||||
|
security_groups = [
|
||||||
|
"foo", # kenya 1
|
||||||
|
"${aws_security_group.firewall.foo}", # kenya 2
|
||||||
|
]
|
||||||
|
|
||||||
|
security_groups2 = [
|
||||||
|
"foo", # kenya 1
|
||||||
|
"bar", # kenya 1.5
|
||||||
|
"${aws_security_group.firewall.foo}", # kenya 2
|
||||||
|
"foobar", # kenya 3
|
||||||
|
]
|
||||||
|
}
|
17
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.golden
generated
vendored
Normal file
17
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.golden
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// A standalone comment
|
||||||
|
|
||||||
|
aligned {
|
||||||
|
# Standalone 1
|
||||||
|
|
||||||
|
a = "bar" # yoo1
|
||||||
|
default = "bar" # yoo2
|
||||||
|
|
||||||
|
# Standalone 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standalone 3
|
||||||
|
|
||||||
|
numbers = [1, 2] // another line here
|
||||||
|
|
||||||
|
# Standalone 4
|
||||||
|
|
16
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.input
generated
vendored
Normal file
16
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.input
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// A standalone comment
|
||||||
|
|
||||||
|
aligned {
|
||||||
|
# Standalone 1
|
||||||
|
|
||||||
|
a = "bar" # yoo1
|
||||||
|
default = "bar" # yoo2
|
||||||
|
|
||||||
|
# Standalone 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standalone 3
|
||||||
|
|
||||||
|
numbers = [1,2] // another line here
|
||||||
|
|
||||||
|
# Standalone 4
|
54
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.golden
generated
vendored
Normal file
54
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.golden
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
variable "foo" {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
developer = ["fatih", "arslan"]
|
||||||
|
|
||||||
|
provider "aws" {
|
||||||
|
access_key = "foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "do" {
|
||||||
|
api_key = "${var.foo}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "firewall" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
resource aws_instance "web" {
|
||||||
|
ami = "${var.foo}"
|
||||||
|
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"${aws_security_group.firewall.foo}",
|
||||||
|
]
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_interface = {
|
||||||
|
device_index = 1
|
||||||
|
|
||||||
|
description = <<EOF
|
||||||
|
ANOTHER NETWORK INTERFACE
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "db" {
|
||||||
|
security_groups = "${aws_security_group.firewall.*.id}"
|
||||||
|
VPC = "foo"
|
||||||
|
|
||||||
|
depends_on = ["aws_instance.web"]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "web_ip" {
|
||||||
|
value = <<EOF
|
||||||
|
TUBES
|
||||||
|
EOF
|
||||||
|
}
|
53
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.input
generated
vendored
Normal file
53
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.input
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
variable "foo" {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
developer = [ "fatih", "arslan"]
|
||||||
|
|
||||||
|
provider "aws" {
|
||||||
|
access_key ="foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "do" {
|
||||||
|
api_key = "${var.foo}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "firewall" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
resource aws_instance "web" {
|
||||||
|
ami = "${var.foo}"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"${aws_security_group.firewall.foo}"
|
||||||
|
]
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_interface = {
|
||||||
|
device_index = 1
|
||||||
|
description = <<EOF
|
||||||
|
ANOTHER NETWORK INTERFACE
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "db" {
|
||||||
|
security_groups = "${aws_security_group.firewall.*.id}"
|
||||||
|
VPC = "foo"
|
||||||
|
|
||||||
|
depends_on = ["aws_instance.web"]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "web_ip" {
|
||||||
|
|
||||||
|
value=<<EOF
|
||||||
|
TUBES
|
||||||
|
EOF
|
||||||
|
}
|
13
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.golden
generated
vendored
Normal file
13
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.golden
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
variable "foo" {}
|
||||||
|
|
||||||
|
variable "foo" {}
|
||||||
|
|
||||||
|
variable "foo" {
|
||||||
|
# Standalone comment should be still here
|
||||||
|
}
|
||||||
|
|
||||||
|
foo {}
|
||||||
|
|
||||||
|
foo {
|
||||||
|
bar = "mssola"
|
||||||
|
}
|
14
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.input
generated
vendored
Normal file
14
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.input
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
variable "foo" {}
|
||||||
|
variable "foo" {
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "foo" {
|
||||||
|
# Standalone comment should be still here
|
||||||
|
}
|
||||||
|
|
||||||
|
foo {
|
||||||
|
}
|
||||||
|
|
||||||
|
foo {
|
||||||
|
bar = "mssola"
|
||||||
|
}
|
27
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.golden
generated
vendored
Normal file
27
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.golden
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
foo = ["fatih", "arslan"]
|
||||||
|
|
||||||
|
foo = ["bar", "qaz"]
|
||||||
|
|
||||||
|
foo = ["zeynep",
|
||||||
|
"arslan",
|
||||||
|
]
|
||||||
|
|
||||||
|
foo = ["fatih", "zeynep",
|
||||||
|
"arslan",
|
||||||
|
]
|
||||||
|
|
||||||
|
foo = [
|
||||||
|
"vim-go",
|
||||||
|
"golang",
|
||||||
|
"hcl",
|
||||||
|
]
|
||||||
|
|
||||||
|
foo = []
|
||||||
|
|
||||||
|
foo = [1, 2, 3, 4]
|
||||||
|
|
||||||
|
foo = [
|
||||||
|
"kenya",
|
||||||
|
"ethiopia",
|
||||||
|
"columbia",
|
||||||
|
]
|
21
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.input
generated
vendored
Normal file
21
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.input
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
foo = ["fatih", "arslan" ]
|
||||||
|
|
||||||
|
foo = [ "bar", "qaz", ]
|
||||||
|
|
||||||
|
foo = [ "zeynep",
|
||||||
|
"arslan", ]
|
||||||
|
|
||||||
|
foo = ["fatih", "zeynep",
|
||||||
|
"arslan", ]
|
||||||
|
|
||||||
|
foo = [
|
||||||
|
"vim-go",
|
||||||
|
"golang", "hcl"]
|
||||||
|
|
||||||
|
foo = []
|
||||||
|
|
||||||
|
foo = [1, 2,3, 4]
|
||||||
|
|
||||||
|
foo = [
|
||||||
|
"kenya", "ethiopia",
|
||||||
|
"columbia"]
|
10
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.golden
generated
vendored
Normal file
10
vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.golden
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
list_of_objects = [
|
||||||
|
{
|
||||||
|
key1 = "value1"
|
||||||
|
key2 = "value2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key3 = "value3"
|
||||||
|
key4 = "value4"
|
||||||
|
},
|
||||||
|
]
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue