mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:02:26 -05:00 
			
		
		
		
	[chore]: Bump github.com/spf13/viper from 1.19.0 to 1.20.0
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.19.0 to 1.20.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.19.0...v1.20.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
		
					parent
					
						
							
								d3c3d34aae
							
						
					
				
			
			
				commit
				
					
						4183b5f5ce
					
				
			
		
					 146 changed files with 4637 additions and 18493 deletions
				
			
		
							
								
								
									
										15
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -2,7 +2,7 @@ module github.com/superseriousbusiness/gotosocial | |||
| 
 | ||||
| go 1.23.0 | ||||
| 
 | ||||
| toolchain go1.23.3 | ||||
| toolchain go1.24.1 | ||||
| 
 | ||||
| // Replace go-swagger with our version that fixes (ours particularly) use of Go1.23 | ||||
| replace github.com/go-swagger/go-swagger => codeberg.org/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix | ||||
|  | @ -58,7 +58,7 @@ require ( | |||
| 	github.com/prometheus/client_golang v1.21.1 | ||||
| 	github.com/rivo/uniseg v0.4.7 | ||||
| 	github.com/spf13/cobra v1.9.1 | ||||
| 	github.com/spf13/viper v1.19.0 | ||||
| 	github.com/spf13/viper v1.20.0 | ||||
| 	github.com/stretchr/testify v1.10.0 | ||||
| 	github.com/tdewolff/minify/v2 v2.21.3 | ||||
| 	github.com/technologize/otel-go-contrib v1.1.1 | ||||
|  | @ -141,6 +141,7 @@ require ( | |||
| 	github.com/go-playground/locales v0.14.1 // indirect | ||||
| 	github.com/go-playground/universal-translator v0.18.1 // indirect | ||||
| 	github.com/go-playground/validator/v10 v10.24.0 // indirect | ||||
| 	github.com/go-viper/mapstructure/v2 v2.2.1 // indirect | ||||
| 	github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect | ||||
| 	github.com/goccy/go-json v0.10.5 // indirect | ||||
| 	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | ||||
|  | @ -152,7 +153,6 @@ require ( | |||
| 	github.com/gorilla/securecookie v1.1.2 // indirect | ||||
| 	github.com/gorilla/sessions v1.2.2 // indirect | ||||
| 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect | ||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||
| 	github.com/huandu/xstrings v1.4.0 // indirect | ||||
| 	github.com/imdario/mergo v0.3.16 // indirect | ||||
| 	github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||
|  | @ -168,7 +168,6 @@ require ( | |||
| 	github.com/kr/pretty v0.3.1 // indirect | ||||
| 	github.com/kr/text v0.2.0 // indirect | ||||
| 	github.com/leodido/go-urn v1.4.0 // indirect | ||||
| 	github.com/magiconair/properties v1.8.7 // indirect | ||||
| 	github.com/mailru/easyjson v0.7.7 // indirect | ||||
| 	github.com/mattn/go-isatty v0.0.20 // indirect | ||||
| 	github.com/minio/md5-simd v1.1.2 // indirect | ||||
|  | @ -191,12 +190,11 @@ require ( | |||
| 	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | ||||
| 	github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a // indirect | ||||
| 	github.com/rs/xid v1.6.0 // indirect | ||||
| 	github.com/sagikazarmark/locafero v0.4.0 // indirect | ||||
| 	github.com/sagikazarmark/slog-shim v0.1.0 // indirect | ||||
| 	github.com/sagikazarmark/locafero v0.7.0 // indirect | ||||
| 	github.com/shopspring/decimal v1.3.1 // indirect | ||||
| 	github.com/sourcegraph/conc v0.3.0 // indirect | ||||
| 	github.com/spf13/afero v1.11.0 // indirect | ||||
| 	github.com/spf13/cast v1.6.0 // indirect | ||||
| 	github.com/spf13/afero v1.12.0 // indirect | ||||
| 	github.com/spf13/cast v1.7.1 // indirect | ||||
| 	github.com/spf13/pflag v1.0.6 // indirect | ||||
| 	github.com/subosito/gotenv v1.6.0 // indirect | ||||
| 	github.com/tdewolff/parse/v2 v2.7.19 // indirect | ||||
|  | @ -221,7 +219,6 @@ require ( | |||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect | ||||
| 	google.golang.org/grpc v1.71.0 // indirect | ||||
| 	google.golang.org/protobuf v1.36.5 // indirect | ||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	modernc.org/libc v1.61.13 // indirect | ||||
| 	modernc.org/mathutil v1.7.1 // indirect | ||||
|  |  | |||
							
								
								
									
										26
									
								
								go.sum
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										26
									
								
								go.sum
									
										
									
										generated
									
									
									
								
							|  | @ -193,6 +193,8 @@ github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE | |||
| github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= | ||||
| github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= | ||||
| github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= | ||||
| github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= | ||||
| github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= | ||||
| github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= | ||||
| github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= | ||||
| github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= | ||||
|  | @ -242,8 +244,6 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN | |||
| github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||||
| github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= | ||||
| github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= | ||||
| github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | ||||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | ||||
| github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | ||||
| github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= | ||||
| github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | ||||
|  | @ -290,8 +290,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 | |||
| github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= | ||||
| github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= | ||||
| github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | ||||
| github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= | ||||
| github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= | ||||
| github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= | ||||
| github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= | ||||
| github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= | ||||
|  | @ -365,10 +363,8 @@ github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1: | |||
| github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= | ||||
| github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= | ||||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||
| github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= | ||||
| github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= | ||||
| github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= | ||||
| github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= | ||||
| github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= | ||||
| github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= | ||||
| github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= | ||||
| github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= | ||||
| github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||
|  | @ -382,17 +378,17 @@ github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sS | |||
| github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= | ||||
| github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= | ||||
| github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= | ||||
| github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= | ||||
| github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= | ||||
| github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= | ||||
| github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= | ||||
| github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||
| github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= | ||||
| github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= | ||||
| github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= | ||||
| github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= | ||||
| github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= | ||||
| github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= | ||||
| github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= | ||||
| github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||
| github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= | ||||
| github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= | ||||
| github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY= | ||||
| github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||||
| github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||||
|  | @ -634,8 +630,6 @@ google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt | |||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||||
| gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= | ||||
| gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/mcuadros/go-syslog.v2 v2.3.0 h1:kcsiS+WsTKyIEPABJBJtoG0KkOS6yzvJ+/eZlhD79kk= | ||||
| gopkg.in/mcuadros/go-syslog.v2 v2.3.0/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
|  |  | |||
|  | @ -8,11 +8,11 @@ indent_style = space | |||
| insert_final_newline = true | ||||
| trim_trailing_whitespace = true | ||||
| 
 | ||||
| [*.nix] | ||||
| indent_size = 2 | ||||
| [*.go] | ||||
| indent_style = tab | ||||
| 
 | ||||
| [{Makefile,*.mk}] | ||||
| indent_style = tab | ||||
| 
 | ||||
| [Taskfile.yaml] | ||||
| [*.nix] | ||||
| indent_size = 2 | ||||
							
								
								
									
										6
									
								
								vendor/github.com/go-viper/mapstructure/v2/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/go-viper/mapstructure/v2/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| /.devenv/ | ||||
| /.direnv/ | ||||
| /.pre-commit-config.yaml | ||||
| /bin/ | ||||
| /build/ | ||||
| /var/ | ||||
							
								
								
									
										23
									
								
								vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| run: | ||||
|   timeout: 5m | ||||
| 
 | ||||
| linters-settings: | ||||
|   gci: | ||||
|     sections: | ||||
|       - standard | ||||
|       - default | ||||
|       - prefix(github.com/go-viper/mapstructure) | ||||
|   golint: | ||||
|     min-confidence: 0 | ||||
|   goimports: | ||||
|     local-prefixes: github.com/go-viper/maptstructure | ||||
| 
 | ||||
| linters: | ||||
|   disable-all: true | ||||
|   enable: | ||||
|     - gci | ||||
|     - gofmt | ||||
|     - gofumpt | ||||
|     - goimports | ||||
|     - staticcheck | ||||
|     # - stylecheck | ||||
							
								
								
									
										104
									
								
								vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,104 @@ | |||
| > [!WARNING] | ||||
| > As of v2 of this library, change log can be found in GitHub releases. | ||||
| 
 | ||||
| ## 1.5.1 | ||||
| 
 | ||||
| * Wrap errors so they're compatible with `errors.Is` and `errors.As` [GH-282] | ||||
| * Fix map of slices not decoding properly in certain cases. [GH-266] | ||||
| 
 | ||||
| ## 1.5.0 | ||||
| 
 | ||||
| * New option `IgnoreUntaggedFields` to ignore decoding to any fields | ||||
|   without `mapstructure` (or the configured tag name) set [GH-277] | ||||
| * New option `ErrorUnset` which makes it an error if any fields | ||||
|   in a target struct are not set by the decoding process. [GH-225] | ||||
| * New function `OrComposeDecodeHookFunc` to help compose decode hooks. [GH-240] | ||||
| * Decoding to slice from array no longer crashes [GH-265] | ||||
| * Decode nested struct pointers to map [GH-271] | ||||
| * Fix issue where `,squash` was ignored if `Squash` option was set. [GH-280] | ||||
| * Fix issue where fields with `,omitempty` would sometimes decode | ||||
|   into a map with an empty string key [GH-281] | ||||
| 
 | ||||
| ## 1.4.3 | ||||
| 
 | ||||
| * Fix cases where `json.Number` didn't decode properly [GH-261] | ||||
| 
 | ||||
| ## 1.4.2 | ||||
| 
 | ||||
| * Custom name matchers to support any sort of casing, formatting, etc. for | ||||
|   field names. [GH-250] | ||||
| * Fix possible panic in ComposeDecodeHookFunc [GH-251] | ||||
| 
 | ||||
| ## 1.4.1 | ||||
| 
 | ||||
| * Fix regression where `*time.Time` value would be set to empty and not be sent | ||||
|   to decode hooks properly [GH-232] | ||||
| 
 | ||||
| ## 1.4.0 | ||||
| 
 | ||||
| * A new decode hook type `DecodeHookFuncValue` has been added that has | ||||
|   access to the full values. [GH-183] | ||||
| * Squash is now supported with embedded fields that are struct pointers [GH-205] | ||||
| * Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206] | ||||
| 
 | ||||
| ## 1.3.3 | ||||
| 
 | ||||
| * Decoding maps from maps creates a settable value for decode hooks [GH-203] | ||||
| 
 | ||||
| ## 1.3.2 | ||||
| 
 | ||||
| * Decode into interface type with a struct value is supported [GH-187] | ||||
| 
 | ||||
| ## 1.3.1 | ||||
| 
 | ||||
| * Squash should only squash embedded structs. [GH-194] | ||||
| 
 | ||||
| ## 1.3.0 | ||||
| 
 | ||||
| * Added `",omitempty"` support. This will ignore zero values in the source | ||||
|   structure when encoding. [GH-145] | ||||
| 
 | ||||
| ## 1.2.3 | ||||
| 
 | ||||
| * Fix duplicate entries in Keys list with pointer values. [GH-185] | ||||
| 
 | ||||
| ## 1.2.2 | ||||
| 
 | ||||
| * Do not add unsettable (unexported) values to the unused metadata key | ||||
|   or "remain" value. [GH-150] | ||||
| 
 | ||||
| ## 1.2.1 | ||||
| 
 | ||||
| * Go modules checksum mismatch fix | ||||
| 
 | ||||
| ## 1.2.0 | ||||
| 
 | ||||
| * Added support to capture unused values in a field using the `",remain"` value | ||||
|   in the mapstructure tag. There is an example to showcase usage. | ||||
| * Added `DecoderConfig` option to always squash embedded structs | ||||
| * `json.Number` can decode into `uint` types | ||||
| * Empty slices are preserved and not replaced with nil slices | ||||
| * Fix panic that can occur in when decoding a map into a nil slice of structs | ||||
| * Improved package documentation for godoc | ||||
| 
 | ||||
| ## 1.1.2 | ||||
| 
 | ||||
| * Fix error when decode hook decodes interface implementation into interface | ||||
|   type. [GH-140] | ||||
| 
 | ||||
| ## 1.1.1 | ||||
| 
 | ||||
| * Fix panic that can happen in `decodePtr` | ||||
| 
 | ||||
| ## 1.1.0 | ||||
| 
 | ||||
| * Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133] | ||||
| * Support struct to struct decoding [GH-137] | ||||
| * If source map value is nil, then destination map value is nil (instead of empty) | ||||
| * If source slice value is nil, then destination slice value is nil (instead of empty) | ||||
| * If source pointer is nil, then destination pointer is set to nil (instead of | ||||
|   allocated zero value of type) | ||||
| 
 | ||||
| ## 1.0.0 | ||||
| 
 | ||||
| * Initial tagged stable release. | ||||
							
								
								
									
										21
									
								
								vendor/github.com/go-viper/mapstructure/v2/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/go-viper/mapstructure/v2/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| The MIT License (MIT) | ||||
| 
 | ||||
| Copyright (c) 2013 Mitchell Hashimoto | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										80
									
								
								vendor/github.com/go-viper/mapstructure/v2/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/go-viper/mapstructure/v2/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,80 @@ | |||
| # mapstructure | ||||
| 
 | ||||
| [](https://github.com/go-viper/mapstructure/actions?query=workflow%3ACI) | ||||
| [](https://pkg.go.dev/mod/github.com/go-viper/mapstructure/v2) | ||||
|  | ||||
| 
 | ||||
| mapstructure is a Go library for decoding generic map values to structures | ||||
| and vice versa, while providing helpful error handling. | ||||
| 
 | ||||
| This library is most useful when decoding values from some data stream (JSON, | ||||
| Gob, etc.) where you don't _quite_ know the structure of the underlying data | ||||
| until you read a part of it. You can therefore read a `map[string]interface{}` | ||||
| and use this library to decode it into the proper underlying native Go | ||||
| structure. | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| ```shell | ||||
| go get github.com/go-viper/mapstructure/v2 | ||||
| ``` | ||||
| 
 | ||||
| ## Migrating from `github.com/mitchellh/mapstructure` | ||||
| 
 | ||||
| [@mitchehllh](https://github.com/mitchellh) announced his intent to archive some of his unmaintained projects (see [here](https://gist.github.com/mitchellh/90029601268e59a29e64e55bab1c5bdc) and [here](https://github.com/mitchellh/mapstructure/issues/349)). This is a repository achieved the "blessed fork" status. | ||||
| 
 | ||||
| You can migrate to this package by changing your import paths in your Go files to `github.com/go-viper/mapstructure/v2`. | ||||
| The API is the same, so you don't need to change anything else. | ||||
| 
 | ||||
| Here is a script that can help you with the migration: | ||||
| 
 | ||||
| ```shell | ||||
| sed -i 's/github.com\/mitchellh\/mapstructure/github.com\/go-viper\/mapstructure\/v2/g' $(find . -type f -name '*.go') | ||||
| ``` | ||||
| 
 | ||||
| If you need more time to migrate your code, that is absolutely fine. | ||||
| 
 | ||||
| Some of the latest fixes are backported to the v1 release branch of this package, so you can use the Go modules `replace` feature until you are ready to migrate: | ||||
| 
 | ||||
| ```shell | ||||
| replace github.com/mitchellh/mapstructure => github.com/go-viper/mapstructure v1.6.0 | ||||
| ``` | ||||
| 
 | ||||
| ## Usage & Example | ||||
| 
 | ||||
| For usage and examples see the [documentation](https://pkg.go.dev/mod/github.com/go-viper/mapstructure/v2). | ||||
| 
 | ||||
| The `Decode` function has examples associated with it there. | ||||
| 
 | ||||
| ## But Why?! | ||||
| 
 | ||||
| Go offers fantastic standard libraries for decoding formats such as JSON. | ||||
| The standard method is to have a struct pre-created, and populate that struct | ||||
| from the bytes of the encoded format. This is great, but the problem is if | ||||
| you have configuration or an encoding that changes slightly depending on | ||||
| specific fields. For example, consider this JSON: | ||||
| 
 | ||||
| ```json | ||||
| { | ||||
|   "type": "person", | ||||
|   "name": "Mitchell" | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Perhaps we can't populate a specific structure without first reading | ||||
| the "type" field from the JSON. We could always do two passes over the | ||||
| decoding of the JSON (reading the "type" first, and the rest later). | ||||
| However, it is much simpler to just decode this into a `map[string]interface{}` | ||||
| structure, read the "type" key, then use something like this library | ||||
| to decode it into the proper structure. | ||||
| 
 | ||||
| ## Credits | ||||
| 
 | ||||
| Mapstructure was originally created by [@mitchellh](https://github.com/mitchellh). | ||||
| This is a maintained fork of the original library. | ||||
| 
 | ||||
| Read more about the reasons for the fork [here](https://github.com/mitchellh/mapstructure/issues/349). | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| The project is licensed under the [MIT License](LICENSE). | ||||
							
								
								
									
										630
									
								
								vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										630
									
								
								vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,630 @@ | |||
| package mapstructure | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"net/netip" | ||||
| 	"net/url" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns | ||||
| // it into the proper DecodeHookFunc type, such as DecodeHookFuncType. | ||||
| func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { | ||||
| 	// Create variables here so we can reference them with the reflect pkg | ||||
| 	var f1 DecodeHookFuncType | ||||
| 	var f2 DecodeHookFuncKind | ||||
| 	var f3 DecodeHookFuncValue | ||||
| 
 | ||||
| 	// Fill in the variables into this interface and the rest is done | ||||
| 	// automatically using the reflect package. | ||||
| 	potential := []interface{}{f1, f2, f3} | ||||
| 
 | ||||
| 	v := reflect.ValueOf(h) | ||||
| 	vt := v.Type() | ||||
| 	for _, raw := range potential { | ||||
| 		pt := reflect.ValueOf(raw).Type() | ||||
| 		if vt.ConvertibleTo(pt) { | ||||
| 			return v.Convert(pt).Interface() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // cachedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns | ||||
| // it into a closure to be used directly | ||||
| // if the type fails to convert we return a closure always erroring to keep the previous behaviour | ||||
| func cachedDecodeHook(raw DecodeHookFunc) func(from reflect.Value, to reflect.Value) (interface{}, error) { | ||||
| 	switch f := typedDecodeHook(raw).(type) { | ||||
| 	case DecodeHookFuncType: | ||||
| 		return func(from reflect.Value, to reflect.Value) (interface{}, error) { | ||||
| 			return f(from.Type(), to.Type(), from.Interface()) | ||||
| 		} | ||||
| 	case DecodeHookFuncKind: | ||||
| 		return func(from reflect.Value, to reflect.Value) (interface{}, error) { | ||||
| 			return f(from.Kind(), to.Kind(), from.Interface()) | ||||
| 		} | ||||
| 	case DecodeHookFuncValue: | ||||
| 		return func(from reflect.Value, to reflect.Value) (interface{}, error) { | ||||
| 			return f(from, to) | ||||
| 		} | ||||
| 	default: | ||||
| 		return func(from reflect.Value, to reflect.Value) (interface{}, error) { | ||||
| 			return nil, errors.New("invalid decode hook signature") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // DecodeHookExec executes the given decode hook. This should be used | ||||
| // since it'll naturally degrade to the older backwards compatible DecodeHookFunc | ||||
| // that took reflect.Kind instead of reflect.Type. | ||||
| func DecodeHookExec( | ||||
| 	raw DecodeHookFunc, | ||||
| 	from reflect.Value, to reflect.Value, | ||||
| ) (interface{}, error) { | ||||
| 	switch f := typedDecodeHook(raw).(type) { | ||||
| 	case DecodeHookFuncType: | ||||
| 		return f(from.Type(), to.Type(), from.Interface()) | ||||
| 	case DecodeHookFuncKind: | ||||
| 		return f(from.Kind(), to.Kind(), from.Interface()) | ||||
| 	case DecodeHookFuncValue: | ||||
| 		return f(from, to) | ||||
| 	default: | ||||
| 		return nil, errors.New("invalid decode hook signature") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ComposeDecodeHookFunc creates a single DecodeHookFunc that | ||||
| // automatically composes multiple DecodeHookFuncs. | ||||
| // | ||||
| // The composed funcs are called in order, with the result of the | ||||
| // previous transformation. | ||||
| func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { | ||||
| 	cached := make([]func(from reflect.Value, to reflect.Value) (interface{}, error), 0, len(fs)) | ||||
| 	for _, f := range fs { | ||||
| 		cached = append(cached, cachedDecodeHook(f)) | ||||
| 	} | ||||
| 	return func(f reflect.Value, t reflect.Value) (interface{}, error) { | ||||
| 		var err error | ||||
| 		data := f.Interface() | ||||
| 
 | ||||
| 		newFrom := f | ||||
| 		for _, c := range cached { | ||||
| 			data, err = c(newFrom, t) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			newFrom = reflect.ValueOf(data) | ||||
| 		} | ||||
| 
 | ||||
| 		return data, nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // OrComposeDecodeHookFunc executes all input hook functions until one of them returns no error. In that case its value is returned. | ||||
| // If all hooks return an error, OrComposeDecodeHookFunc returns an error concatenating all error messages. | ||||
| func OrComposeDecodeHookFunc(ff ...DecodeHookFunc) DecodeHookFunc { | ||||
| 	cached := make([]func(from reflect.Value, to reflect.Value) (interface{}, error), 0, len(ff)) | ||||
| 	for _, f := range ff { | ||||
| 		cached = append(cached, cachedDecodeHook(f)) | ||||
| 	} | ||||
| 	return func(a, b reflect.Value) (interface{}, error) { | ||||
| 		var allErrs string | ||||
| 		var out interface{} | ||||
| 		var err error | ||||
| 
 | ||||
| 		for _, c := range cached { | ||||
| 			out, err = c(a, b) | ||||
| 			if err != nil { | ||||
| 				allErrs += err.Error() + "\n" | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			return out, nil | ||||
| 		} | ||||
| 
 | ||||
| 		return nil, errors.New(allErrs) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToSliceHookFunc returns a DecodeHookFunc that converts | ||||
| // string to []string by splitting on the given sep. | ||||
| func StringToSliceHookFunc(sep string) DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.SliceOf(f) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		raw := data.(string) | ||||
| 		if raw == "" { | ||||
| 			return []string{}, nil | ||||
| 		} | ||||
| 
 | ||||
| 		return strings.Split(raw, sep), nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToTimeDurationHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to time.Duration. | ||||
| func StringToTimeDurationHookFunc() DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(time.Duration(5)) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return time.ParseDuration(data.(string)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToURLHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to *url.URL. | ||||
| func StringToURLHookFunc() DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(&url.URL{}) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return url.Parse(data.(string)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToIPHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to net.IP | ||||
| func StringToIPHookFunc() DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(net.IP{}) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		ip := net.ParseIP(data.(string)) | ||||
| 		if ip == nil { | ||||
| 			return net.IP{}, fmt.Errorf("failed parsing ip %v", data) | ||||
| 		} | ||||
| 
 | ||||
| 		return ip, nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToIPNetHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to net.IPNet | ||||
| func StringToIPNetHookFunc() DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(net.IPNet{}) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		_, net, err := net.ParseCIDR(data.(string)) | ||||
| 		return net, err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToTimeHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to time.Time. | ||||
| func StringToTimeHookFunc(layout string) DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(time.Time{}) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return time.Parse(layout, data.(string)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to | ||||
| // the decoder. | ||||
| // | ||||
| // Note that this is significantly different from the WeaklyTypedInput option | ||||
| // of the DecoderConfig. | ||||
| func WeaklyTypedHook( | ||||
| 	f reflect.Kind, | ||||
| 	t reflect.Kind, | ||||
| 	data interface{}, | ||||
| ) (interface{}, error) { | ||||
| 	dataVal := reflect.ValueOf(data) | ||||
| 	switch t { | ||||
| 	case reflect.String: | ||||
| 		switch f { | ||||
| 		case reflect.Bool: | ||||
| 			if dataVal.Bool() { | ||||
| 				return "1", nil | ||||
| 			} | ||||
| 			return "0", nil | ||||
| 		case reflect.Float32: | ||||
| 			return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil | ||||
| 		case reflect.Int: | ||||
| 			return strconv.FormatInt(dataVal.Int(), 10), nil | ||||
| 		case reflect.Slice: | ||||
| 			dataType := dataVal.Type() | ||||
| 			elemKind := dataType.Elem().Kind() | ||||
| 			if elemKind == reflect.Uint8 { | ||||
| 				return string(dataVal.Interface().([]uint8)), nil | ||||
| 			} | ||||
| 		case reflect.Uint: | ||||
| 			return strconv.FormatUint(dataVal.Uint(), 10), nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return data, nil | ||||
| } | ||||
| 
 | ||||
| func RecursiveStructToMapHookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Value, t reflect.Value) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.Struct { | ||||
| 			return f.Interface(), nil | ||||
| 		} | ||||
| 
 | ||||
| 		var i interface{} = struct{}{} | ||||
| 		if t.Type() != reflect.TypeOf(&i).Elem() { | ||||
| 			return f.Interface(), nil | ||||
| 		} | ||||
| 
 | ||||
| 		m := make(map[string]interface{}) | ||||
| 		t.Set(reflect.ValueOf(m)) | ||||
| 
 | ||||
| 		return f.Interface(), nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TextUnmarshallerHookFunc returns a DecodeHookFunc that applies | ||||
| // strings to the UnmarshalText function, when the target type | ||||
| // implements the encoding.TextUnmarshaler interface | ||||
| func TextUnmarshallerHookFunc() DecodeHookFuncType { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		result := reflect.New(t).Interface() | ||||
| 		unmarshaller, ok := result.(encoding.TextUnmarshaler) | ||||
| 		if !ok { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		str, ok := data.(string) | ||||
| 		if !ok { | ||||
| 			str = reflect.Indirect(reflect.ValueOf(&data)).Elem().String() | ||||
| 		} | ||||
| 		if err := unmarshaller.UnmarshalText([]byte(str)); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return result, nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToNetIPAddrHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to netip.Addr. | ||||
| func StringToNetIPAddrHookFunc() DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(netip.Addr{}) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return netip.ParseAddr(data.(string)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToNetIPAddrPortHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to netip.AddrPort. | ||||
| func StringToNetIPAddrPortHookFunc() DecodeHookFunc { | ||||
| 	return func( | ||||
| 		f reflect.Type, | ||||
| 		t reflect.Type, | ||||
| 		data interface{}, | ||||
| 	) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 		if t != reflect.TypeOf(netip.AddrPort{}) { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return netip.ParseAddrPort(data.(string)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToBasicTypeHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to basic types. | ||||
| // int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, float32, float64, bool, byte, rune, complex64, complex128 | ||||
| func StringToBasicTypeHookFunc() DecodeHookFunc { | ||||
| 	return ComposeDecodeHookFunc( | ||||
| 		StringToInt8HookFunc(), | ||||
| 		StringToUint8HookFunc(), | ||||
| 		StringToInt16HookFunc(), | ||||
| 		StringToUint16HookFunc(), | ||||
| 		StringToInt32HookFunc(), | ||||
| 		StringToUint32HookFunc(), | ||||
| 		StringToInt64HookFunc(), | ||||
| 		StringToUint64HookFunc(), | ||||
| 		StringToIntHookFunc(), | ||||
| 		StringToUintHookFunc(), | ||||
| 		StringToFloat32HookFunc(), | ||||
| 		StringToFloat64HookFunc(), | ||||
| 		StringToBoolHookFunc(), | ||||
| 		// byte and rune are aliases for uint8 and int32 respectively | ||||
| 		// StringToByteHookFunc(), | ||||
| 		// StringToRuneHookFunc(), | ||||
| 		StringToComplex64HookFunc(), | ||||
| 		StringToComplex128HookFunc(), | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| // StringToInt8HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to int8. | ||||
| func StringToInt8HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Int8 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		i64, err := strconv.ParseInt(data.(string), 0, 8) | ||||
| 		return int8(i64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToUint8HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to uint8. | ||||
| func StringToUint8HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Uint8 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		u64, err := strconv.ParseUint(data.(string), 0, 8) | ||||
| 		return uint8(u64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToInt16HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to int16. | ||||
| func StringToInt16HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Int16 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		i64, err := strconv.ParseInt(data.(string), 0, 16) | ||||
| 		return int16(i64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToUint16HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to uint16. | ||||
| func StringToUint16HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Uint16 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		u64, err := strconv.ParseUint(data.(string), 0, 16) | ||||
| 		return uint16(u64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToInt32HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to int32. | ||||
| func StringToInt32HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Int32 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		i64, err := strconv.ParseInt(data.(string), 0, 32) | ||||
| 		return int32(i64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToUint32HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to uint32. | ||||
| func StringToUint32HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Uint32 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		u64, err := strconv.ParseUint(data.(string), 0, 32) | ||||
| 		return uint32(u64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToInt64HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to int64. | ||||
| func StringToInt64HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Int64 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return strconv.ParseInt(data.(string), 0, 64) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToUint64HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to uint64. | ||||
| func StringToUint64HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Uint64 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return strconv.ParseUint(data.(string), 0, 64) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToIntHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to int. | ||||
| func StringToIntHookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Int { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		i64, err := strconv.ParseInt(data.(string), 0, 0) | ||||
| 		return int(i64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToUintHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to uint. | ||||
| func StringToUintHookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Uint { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		u64, err := strconv.ParseUint(data.(string), 0, 0) | ||||
| 		return uint(u64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToFloat32HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to float32. | ||||
| func StringToFloat32HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Float32 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		f64, err := strconv.ParseFloat(data.(string), 32) | ||||
| 		return float32(f64), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToFloat64HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to float64. | ||||
| func StringToFloat64HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Float64 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return strconv.ParseFloat(data.(string), 64) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToBoolHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to bool. | ||||
| func StringToBoolHookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Bool { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return strconv.ParseBool(data.(string)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToByteHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to byte. | ||||
| func StringToByteHookFunc() DecodeHookFunc { | ||||
| 	return StringToUint8HookFunc() | ||||
| } | ||||
| 
 | ||||
| // StringToRuneHookFunc returns a DecodeHookFunc that converts | ||||
| // strings to rune. | ||||
| func StringToRuneHookFunc() DecodeHookFunc { | ||||
| 	return StringToInt32HookFunc() | ||||
| } | ||||
| 
 | ||||
| // StringToComplex64HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to complex64. | ||||
| func StringToComplex64HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Complex64 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		c128, err := strconv.ParseComplex(data.(string), 64) | ||||
| 		return complex64(c128), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringToComplex128HookFunc returns a DecodeHookFunc that converts | ||||
| // strings to complex128. | ||||
| func StringToComplex128HookFunc() DecodeHookFunc { | ||||
| 	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { | ||||
| 		if f.Kind() != reflect.String || t.Kind() != reflect.Complex128 { | ||||
| 			return data, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert it by parsing | ||||
| 		return strconv.ParseComplex(data.(string), 128) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										472
									
								
								vendor/github.com/go-viper/mapstructure/v2/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										472
									
								
								vendor/github.com/go-viper/mapstructure/v2/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,472 @@ | |||
| { | ||||
|   "nodes": { | ||||
|     "cachix": { | ||||
|       "inputs": { | ||||
|         "devenv": "devenv_2", | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "pre-commit-hooks": [ | ||||
|           "devenv", | ||||
|           "pre-commit-hooks" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1712055811, | ||||
|         "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "cachix", | ||||
|         "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "cachix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "devenv": { | ||||
|       "inputs": { | ||||
|         "cachix": "cachix", | ||||
|         "flake-compat": "flake-compat_2", | ||||
|         "nix": "nix_2", | ||||
|         "nixpkgs": "nixpkgs_2", | ||||
|         "pre-commit-hooks": "pre-commit-hooks" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1717245169, | ||||
|         "narHash": "sha256-+mW3rTBjGU8p1THJN0lX/Dd/8FbnF+3dB+mJuSaxewE=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "c3f9f053c077c6f88a3de5276d9178c62baa3fc3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "devenv_2": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nix": "nix", | ||||
|         "nixpkgs": "nixpkgs", | ||||
|         "poetry2nix": "poetry2nix", | ||||
|         "pre-commit-hooks": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "pre-commit-hooks" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1708704632, | ||||
|         "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "ref": "python-rewrite", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-compat": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1673956053, | ||||
|         "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-compat_2": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1696426674, | ||||
|         "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-parts": { | ||||
|       "inputs": { | ||||
|         "nixpkgs-lib": "nixpkgs-lib" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1717285511, | ||||
|         "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "flake-parts", | ||||
|         "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "flake-parts", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-utils": { | ||||
|       "inputs": { | ||||
|         "systems": "systems" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1689068808, | ||||
|         "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-utils_2": { | ||||
|       "inputs": { | ||||
|         "systems": "systems_2" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1710146030, | ||||
|         "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "gitignore": { | ||||
|       "inputs": { | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "pre-commit-hooks", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1709087332, | ||||
|         "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "gitignore.nix", | ||||
|         "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "gitignore.nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix": { | ||||
|       "inputs": { | ||||
|         "flake-compat": "flake-compat", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1712911606, | ||||
|         "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "devenv-2.21", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix-github-actions": { | ||||
|       "inputs": { | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "poetry2nix", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1688870561, | ||||
|         "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "nix-github-actions", | ||||
|         "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-community", | ||||
|         "repo": "nix-github-actions", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix_2": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression_2" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1712911606, | ||||
|         "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "devenv-2.21", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs": { | ||||
|       "locked": { | ||||
|         "lastModified": 1692808169, | ||||
|         "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixpkgs-unstable", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-lib": { | ||||
|       "locked": { | ||||
|         "lastModified": 1717284937, | ||||
|         "narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=", | ||||
|         "type": "tarball", | ||||
|         "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" | ||||
|       }, | ||||
|       "original": { | ||||
|         "type": "tarball", | ||||
|         "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-regression": { | ||||
|       "locked": { | ||||
|         "lastModified": 1643052045, | ||||
|         "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-regression_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1643052045, | ||||
|         "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-stable": { | ||||
|       "locked": { | ||||
|         "lastModified": 1710695816, | ||||
|         "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "614b4613980a522ba49f0d194531beddbb7220d3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-23.11", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1713361204, | ||||
|         "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv-nixpkgs", | ||||
|         "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "ref": "rolling", | ||||
|         "repo": "devenv-nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_3": { | ||||
|       "locked": { | ||||
|         "lastModified": 1717112898, | ||||
|         "narHash": "sha256-7R2ZvOnvd9h8fDd65p0JnB7wXfUvreox3xFdYWd1BnY=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "6132b0f6e344ce2fe34fc051b72fb46e34f668e0", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixpkgs-unstable", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "poetry2nix": { | ||||
|       "inputs": { | ||||
|         "flake-utils": "flake-utils", | ||||
|         "nix-github-actions": "nix-github-actions", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1692876271, | ||||
|         "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "poetry2nix", | ||||
|         "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-community", | ||||
|         "repo": "poetry2nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "pre-commit-hooks": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "flake-utils": "flake-utils_2", | ||||
|         "gitignore": "gitignore", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-stable": "nixpkgs-stable" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1713775815, | ||||
|         "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "pre-commit-hooks.nix", | ||||
|         "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "pre-commit-hooks.nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "root": { | ||||
|       "inputs": { | ||||
|         "devenv": "devenv", | ||||
|         "flake-parts": "flake-parts", | ||||
|         "nixpkgs": "nixpkgs_3" | ||||
|       } | ||||
|     }, | ||||
|     "systems": { | ||||
|       "locked": { | ||||
|         "lastModified": 1681028828, | ||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "systems_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1681028828, | ||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "root": "root", | ||||
|   "version": 7 | ||||
| } | ||||
|  | @ -1,7 +1,6 @@ | |||
| { | ||||
|   inputs = { | ||||
|     # nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; | ||||
|     nixpkgs.url = "github:NixOS/nixpkgs/master"; | ||||
|     nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; | ||||
|     flake-parts.url = "github:hercules-ci/flake-parts"; | ||||
|     devenv.url = "github:cachix/devenv"; | ||||
|   }; | ||||
|  | @ -19,38 +18,21 @@ | |||
|           default = { | ||||
|             languages = { | ||||
|               go.enable = true; | ||||
|               go.package = pkgs.lib.mkDefault pkgs.go_1_21; | ||||
|             }; | ||||
| 
 | ||||
|             pre-commit.hooks = { | ||||
|               nixpkgs-fmt.enable = true; | ||||
|             }; | ||||
| 
 | ||||
|             packages = with pkgs; [ | ||||
|               golangci-lint | ||||
|             ]; | ||||
| 
 | ||||
|             # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767 | ||||
|             containers = pkgs.lib.mkForce { }; | ||||
|           }; | ||||
| 
 | ||||
|           ci = devenv.shells.default; | ||||
| 
 | ||||
|           ci_1_19 = { | ||||
|             imports = [ devenv.shells.ci ]; | ||||
| 
 | ||||
|             languages = { | ||||
|               go.package = pkgs.go_1_19; | ||||
|             }; | ||||
|           }; | ||||
| 
 | ||||
|           ci_1_20 = { | ||||
|             imports = [ devenv.shells.ci ]; | ||||
| 
 | ||||
|             languages = { | ||||
|               go.package = pkgs.go_1_20; | ||||
|             }; | ||||
|           }; | ||||
| 
 | ||||
|           ci_1_21 = { | ||||
|             imports = [ devenv.shells.ci ]; | ||||
| 
 | ||||
|             languages = { | ||||
|               go.package = pkgs.go_1_21; | ||||
|             }; | ||||
|           }; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
							
								
								
									
										11
									
								
								vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| package errors | ||||
| 
 | ||||
| import "errors" | ||||
| 
 | ||||
| func New(text string) error { | ||||
| 	return errors.New(text) | ||||
| } | ||||
| 
 | ||||
| func As(err error, target interface{}) bool { | ||||
| 	return errors.As(err, target) | ||||
| } | ||||
							
								
								
									
										9
									
								
								vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| //go:build go1.20 | ||||
| 
 | ||||
| package errors | ||||
| 
 | ||||
| import "errors" | ||||
| 
 | ||||
| func Join(errs ...error) error { | ||||
| 	return errors.Join(errs...) | ||||
| } | ||||
							
								
								
									
										61
									
								
								vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,61 @@ | |||
| //go:build !go1.20 | ||||
| 
 | ||||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package errors | ||||
| 
 | ||||
| // Join returns an error that wraps the given errors. | ||||
| // Any nil error values are discarded. | ||||
| // Join returns nil if every value in errs is nil. | ||||
| // The error formats as the concatenation of the strings obtained | ||||
| // by calling the Error method of each element of errs, with a newline | ||||
| // between each string. | ||||
| // | ||||
| // A non-nil error returned by Join implements the Unwrap() []error method. | ||||
| func Join(errs ...error) error { | ||||
| 	n := 0 | ||||
| 	for _, err := range errs { | ||||
| 		if err != nil { | ||||
| 			n++ | ||||
| 		} | ||||
| 	} | ||||
| 	if n == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	e := &joinError{ | ||||
| 		errs: make([]error, 0, n), | ||||
| 	} | ||||
| 	for _, err := range errs { | ||||
| 		if err != nil { | ||||
| 			e.errs = append(e.errs, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return e | ||||
| } | ||||
| 
 | ||||
| type joinError struct { | ||||
| 	errs []error | ||||
| } | ||||
| 
 | ||||
| func (e *joinError) Error() string { | ||||
| 	// Since Join returns nil if every value in errs is nil, | ||||
| 	// e.errs cannot be empty. | ||||
| 	if len(e.errs) == 1 { | ||||
| 		return e.errs[0].Error() | ||||
| 	} | ||||
| 
 | ||||
| 	b := []byte(e.errs[0].Error()) | ||||
| 	for _, err := range e.errs[1:] { | ||||
| 		b = append(b, '\n') | ||||
| 		b = append(b, err.Error()...) | ||||
| 	} | ||||
| 	// At this point, b has at least one byte '\n'. | ||||
| 	// return unsafe.String(&b[0], len(b)) | ||||
| 	return string(b) | ||||
| } | ||||
| 
 | ||||
| func (e *joinError) Unwrap() []error { | ||||
| 	return e.errs | ||||
| } | ||||
							
								
								
									
										1620
									
								
								vendor/github.com/go-viper/mapstructure/v2/mapstructure.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1620
									
								
								vendor/github.com/go-viper/mapstructure/v2/mapstructure.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										44
									
								
								vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| //go:build !go1.20 | ||||
| 
 | ||||
| package mapstructure | ||||
| 
 | ||||
| import "reflect" | ||||
| 
 | ||||
| func isComparable(v reflect.Value) bool { | ||||
| 	k := v.Kind() | ||||
| 	switch k { | ||||
| 	case reflect.Invalid: | ||||
| 		return false | ||||
| 
 | ||||
| 	case reflect.Array: | ||||
| 		switch v.Type().Elem().Kind() { | ||||
| 		case reflect.Interface, reflect.Array, reflect.Struct: | ||||
| 			for i := 0; i < v.Type().Len(); i++ { | ||||
| 				// if !v.Index(i).Comparable() { | ||||
| 				if !isComparable(v.Index(i)) { | ||||
| 					return false | ||||
| 				} | ||||
| 			} | ||||
| 			return true | ||||
| 		} | ||||
| 		return v.Type().Comparable() | ||||
| 
 | ||||
| 	case reflect.Interface: | ||||
| 		// return v.Elem().Comparable() | ||||
| 		return isComparable(v.Elem()) | ||||
| 
 | ||||
| 	case reflect.Struct: | ||||
| 		for i := 0; i < v.NumField(); i++ { | ||||
| 			return false | ||||
| 
 | ||||
| 			// if !v.Field(i).Comparable() { | ||||
| 			if !isComparable(v.Field(i)) { | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 		return true | ||||
| 
 | ||||
| 	default: | ||||
| 		return v.Type().Comparable() | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										10
									
								
								vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| //go:build go1.20 | ||||
| 
 | ||||
| package mapstructure | ||||
| 
 | ||||
| import "reflect" | ||||
| 
 | ||||
| // TODO: remove once we drop support for Go <1.20 | ||||
| func isComparable(v reflect.Value) bool { | ||||
| 	return v.Comparable() | ||||
| } | ||||
							
								
								
									
										9
									
								
								vendor/github.com/hashicorp/hcl/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/hashicorp/hcl/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +0,0 @@ | |||
| y.output | ||||
| 
 | ||||
| # ignore intellij files | ||||
| .idea | ||||
| *.iml | ||||
| *.ipr | ||||
| *.iws | ||||
| 
 | ||||
| *.test | ||||
							
								
								
									
										13
									
								
								vendor/github.com/hashicorp/hcl/.travis.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/hashicorp/hcl/.travis.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,13 +0,0 @@ | |||
| sudo: false | ||||
| 
 | ||||
| language: go | ||||
| 
 | ||||
| go: | ||||
|   - 1.x | ||||
|   - tip | ||||
| 
 | ||||
| branches: | ||||
|   only: | ||||
|     - master | ||||
| 
 | ||||
| script: make test | ||||
							
								
								
									
										354
									
								
								vendor/github.com/hashicorp/hcl/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										354
									
								
								vendor/github.com/hashicorp/hcl/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,354 +0,0 @@ | |||
| Mozilla Public License, version 2.0 | ||||
| 
 | ||||
| 1. Definitions | ||||
| 
 | ||||
| 1.1. “Contributor” | ||||
| 
 | ||||
|      means each individual or legal entity that creates, contributes to the | ||||
|      creation of, or owns Covered Software. | ||||
| 
 | ||||
| 1.2. “Contributor Version” | ||||
| 
 | ||||
|      means the combination of the Contributions of others (if any) used by a | ||||
|      Contributor and that particular Contributor’s Contribution. | ||||
| 
 | ||||
| 1.3. “Contribution” | ||||
| 
 | ||||
|      means Covered Software of a particular Contributor. | ||||
| 
 | ||||
| 1.4. “Covered Software” | ||||
| 
 | ||||
|      means Source Code Form to which the initial Contributor has attached the | ||||
|      notice in Exhibit A, the Executable Form of such Source Code Form, and | ||||
|      Modifications of such Source Code Form, in each case including portions | ||||
|      thereof. | ||||
| 
 | ||||
| 1.5. “Incompatible With Secondary Licenses” | ||||
|      means | ||||
| 
 | ||||
|      a. that the initial Contributor has attached the notice described in | ||||
|         Exhibit B to the Covered Software; or | ||||
| 
 | ||||
|      b. that the Covered Software was made available under the terms of version | ||||
|         1.1 or earlier of the License, but not also under the terms of a | ||||
|         Secondary License. | ||||
| 
 | ||||
| 1.6. “Executable Form” | ||||
| 
 | ||||
|      means any form of the work other than Source Code Form. | ||||
| 
 | ||||
| 1.7. “Larger Work” | ||||
| 
 | ||||
|      means a work that combines Covered Software with other material, in a separate | ||||
|      file or files, that is not Covered Software. | ||||
| 
 | ||||
| 1.8. “License” | ||||
| 
 | ||||
|      means this document. | ||||
| 
 | ||||
| 1.9. “Licensable” | ||||
| 
 | ||||
|      means having the right to grant, to the maximum extent possible, whether at the | ||||
|      time of the initial grant or subsequently, any and all of the rights conveyed by | ||||
|      this License. | ||||
| 
 | ||||
| 1.10. “Modifications” | ||||
| 
 | ||||
|      means any of the following: | ||||
| 
 | ||||
|      a. any file in Source Code Form that results from an addition to, deletion | ||||
|         from, or modification of the contents of Covered Software; or | ||||
| 
 | ||||
|      b. any new file in Source Code Form that contains any Covered Software. | ||||
| 
 | ||||
| 1.11. “Patent Claims” of a Contributor | ||||
| 
 | ||||
|       means any patent claim(s), including without limitation, method, process, | ||||
|       and apparatus claims, in any patent Licensable by such Contributor that | ||||
|       would be infringed, but for the grant of the License, by the making, | ||||
|       using, selling, offering for sale, having made, import, or transfer of | ||||
|       either its Contributions or its Contributor Version. | ||||
| 
 | ||||
| 1.12. “Secondary License” | ||||
| 
 | ||||
|       means either the GNU General Public License, Version 2.0, the GNU Lesser | ||||
|       General Public License, Version 2.1, the GNU Affero General Public | ||||
|       License, Version 3.0, or any later versions of those licenses. | ||||
| 
 | ||||
| 1.13. “Source Code Form” | ||||
| 
 | ||||
|       means the form of the work preferred for making modifications. | ||||
| 
 | ||||
| 1.14. “You” (or “Your”) | ||||
| 
 | ||||
|       means an individual or a legal entity exercising rights under this | ||||
|       License. For legal entities, “You” includes any entity that controls, is | ||||
|       controlled by, or is under common control with You. For purposes of this | ||||
|       definition, “control” means (a) the power, direct or indirect, to cause | ||||
|       the direction or management of such entity, whether by contract or | ||||
|       otherwise, or (b) ownership of more than fifty percent (50%) of the | ||||
|       outstanding shares or beneficial ownership of such entity. | ||||
| 
 | ||||
| 
 | ||||
| 2. License Grants and Conditions | ||||
| 
 | ||||
| 2.1. Grants | ||||
| 
 | ||||
|      Each Contributor hereby grants You a world-wide, royalty-free, | ||||
|      non-exclusive license: | ||||
| 
 | ||||
|      a. under intellectual property rights (other than patent or trademark) | ||||
|         Licensable by such Contributor to use, reproduce, make available, | ||||
|         modify, display, perform, distribute, and otherwise exploit its | ||||
|         Contributions, either on an unmodified basis, with Modifications, or as | ||||
|         part of a Larger Work; and | ||||
| 
 | ||||
|      b. under Patent Claims of such Contributor to make, use, sell, offer for | ||||
|         sale, have made, import, and otherwise transfer either its Contributions | ||||
|         or its Contributor Version. | ||||
| 
 | ||||
| 2.2. Effective Date | ||||
| 
 | ||||
|      The licenses granted in Section 2.1 with respect to any Contribution become | ||||
|      effective for each Contribution on the date the Contributor first distributes | ||||
|      such Contribution. | ||||
| 
 | ||||
| 2.3. Limitations on Grant Scope | ||||
| 
 | ||||
|      The licenses granted in this Section 2 are the only rights granted under this | ||||
|      License. No additional rights or licenses will be implied from the distribution | ||||
|      or licensing of Covered Software under this License. Notwithstanding Section | ||||
|      2.1(b) above, no patent license is granted by a Contributor: | ||||
| 
 | ||||
|      a. for any code that a Contributor has removed from Covered Software; or | ||||
| 
 | ||||
|      b. for infringements caused by: (i) Your and any other third party’s | ||||
|         modifications of Covered Software, or (ii) the combination of its | ||||
|         Contributions with other software (except as part of its Contributor | ||||
|         Version); or | ||||
| 
 | ||||
|      c. under Patent Claims infringed by Covered Software in the absence of its | ||||
|         Contributions. | ||||
| 
 | ||||
|      This License does not grant any rights in the trademarks, service marks, or | ||||
|      logos of any Contributor (except as may be necessary to comply with the | ||||
|      notice requirements in Section 3.4). | ||||
| 
 | ||||
| 2.4. Subsequent Licenses | ||||
| 
 | ||||
|      No Contributor makes additional grants as a result of Your choice to | ||||
|      distribute the Covered Software under a subsequent version of this License | ||||
|      (see Section 10.2) or under the terms of a Secondary License (if permitted | ||||
|      under the terms of Section 3.3). | ||||
| 
 | ||||
| 2.5. Representation | ||||
| 
 | ||||
|      Each Contributor represents that the Contributor believes its Contributions | ||||
|      are its original creation(s) or it has sufficient rights to grant the | ||||
|      rights to its Contributions conveyed by this License. | ||||
| 
 | ||||
| 2.6. Fair Use | ||||
| 
 | ||||
|      This License is not intended to limit any rights You have under applicable | ||||
|      copyright doctrines of fair use, fair dealing, or other equivalents. | ||||
| 
 | ||||
| 2.7. Conditions | ||||
| 
 | ||||
|      Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in | ||||
|      Section 2.1. | ||||
| 
 | ||||
| 
 | ||||
| 3. Responsibilities | ||||
| 
 | ||||
| 3.1. Distribution of Source Form | ||||
| 
 | ||||
|      All distribution of Covered Software in Source Code Form, including any | ||||
|      Modifications that You create or to which You contribute, must be under the | ||||
|      terms of this License. You must inform recipients that the Source Code Form | ||||
|      of the Covered Software is governed by the terms of this License, and how | ||||
|      they can obtain a copy of this License. You may not attempt to alter or | ||||
|      restrict the recipients’ rights in the Source Code Form. | ||||
| 
 | ||||
| 3.2. Distribution of Executable Form | ||||
| 
 | ||||
|      If You distribute Covered Software in Executable Form then: | ||||
| 
 | ||||
|      a. such Covered Software must also be made available in Source Code Form, | ||||
|         as described in Section 3.1, and You must inform recipients of the | ||||
|         Executable Form how they can obtain a copy of such Source Code Form by | ||||
|         reasonable means in a timely manner, at a charge no more than the cost | ||||
|         of distribution to the recipient; and | ||||
| 
 | ||||
|      b. You may distribute such Executable Form under the terms of this License, | ||||
|         or sublicense it under different terms, provided that the license for | ||||
|         the Executable Form does not attempt to limit or alter the recipients’ | ||||
|         rights in the Source Code Form under this License. | ||||
| 
 | ||||
| 3.3. Distribution of a Larger Work | ||||
| 
 | ||||
|      You may create and distribute a Larger Work under terms of Your choice, | ||||
|      provided that You also comply with the requirements of this License for the | ||||
|      Covered Software. If the Larger Work is a combination of Covered Software | ||||
|      with a work governed by one or more Secondary Licenses, and the Covered | ||||
|      Software is not Incompatible With Secondary Licenses, this License permits | ||||
|      You to additionally distribute such Covered Software under the terms of | ||||
|      such Secondary License(s), so that the recipient of the Larger Work may, at | ||||
|      their option, further distribute the Covered Software under the terms of | ||||
|      either this License or such Secondary License(s). | ||||
| 
 | ||||
| 3.4. Notices | ||||
| 
 | ||||
|      You may not remove or alter the substance of any license notices (including | ||||
|      copyright notices, patent notices, disclaimers of warranty, or limitations | ||||
|      of liability) contained within the Source Code Form of the Covered | ||||
|      Software, except that You may alter any license notices to the extent | ||||
|      required to remedy known factual inaccuracies. | ||||
| 
 | ||||
| 3.5. Application of Additional Terms | ||||
| 
 | ||||
|      You may choose to offer, and to charge a fee for, warranty, support, | ||||
|      indemnity or liability obligations to one or more recipients of Covered | ||||
|      Software. However, You may do so only on Your own behalf, and not on behalf | ||||
|      of any Contributor. You must make it absolutely clear that any such | ||||
|      warranty, support, indemnity, or liability obligation is offered by You | ||||
|      alone, and You hereby agree to indemnify every Contributor for any | ||||
|      liability incurred by such Contributor as a result of warranty, support, | ||||
|      indemnity or liability terms You offer. You may include additional | ||||
|      disclaimers of warranty and limitations of liability specific to any | ||||
|      jurisdiction. | ||||
| 
 | ||||
| 4. Inability to Comply Due to Statute or Regulation | ||||
| 
 | ||||
|    If it is impossible for You to comply with any of the terms of this License | ||||
|    with respect to some or all of the Covered Software due to statute, judicial | ||||
|    order, or regulation then You must: (a) comply with the terms of this License | ||||
|    to the maximum extent possible; and (b) describe the limitations and the code | ||||
|    they affect. Such description must be placed in a text file included with all | ||||
|    distributions of the Covered Software under this License. Except to the | ||||
|    extent prohibited by statute or regulation, such description must be | ||||
|    sufficiently detailed for a recipient of ordinary skill to be able to | ||||
|    understand it. | ||||
| 
 | ||||
| 5. Termination | ||||
| 
 | ||||
| 5.1. The rights granted under this License will terminate automatically if You | ||||
|      fail to comply with any of its terms. However, if You become compliant, | ||||
|      then the rights granted under this License from a particular Contributor | ||||
|      are reinstated (a) provisionally, unless and until such Contributor | ||||
|      explicitly and finally terminates Your grants, and (b) on an ongoing basis, | ||||
|      if such Contributor fails to notify You of the non-compliance by some | ||||
|      reasonable means prior to 60 days after You have come back into compliance. | ||||
|      Moreover, Your grants from a particular Contributor are reinstated on an | ||||
|      ongoing basis if such Contributor notifies You of the non-compliance by | ||||
|      some reasonable means, this is the first time You have received notice of | ||||
|      non-compliance with this License from such Contributor, and You become | ||||
|      compliant prior to 30 days after Your receipt of the notice. | ||||
| 
 | ||||
| 5.2. If You initiate litigation against any entity by asserting a patent | ||||
|      infringement claim (excluding declaratory judgment actions, counter-claims, | ||||
|      and cross-claims) alleging that a Contributor Version directly or | ||||
|      indirectly infringes any patent, then the rights granted to You by any and | ||||
|      all Contributors for the Covered Software under Section 2.1 of this License | ||||
|      shall terminate. | ||||
| 
 | ||||
| 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user | ||||
|      license agreements (excluding distributors and resellers) which have been | ||||
|      validly granted by You or Your distributors under this License prior to | ||||
|      termination shall survive termination. | ||||
| 
 | ||||
| 6. Disclaimer of Warranty | ||||
| 
 | ||||
|    Covered Software is provided under this License on an “as is” basis, without | ||||
|    warranty of any kind, either expressed, implied, or statutory, including, | ||||
|    without limitation, warranties that the Covered Software is free of defects, | ||||
|    merchantable, fit for a particular purpose or non-infringing. The entire | ||||
|    risk as to the quality and performance of the Covered Software is with You. | ||||
|    Should any Covered Software prove defective in any respect, You (not any | ||||
|    Contributor) assume the cost of any necessary servicing, repair, or | ||||
|    correction. This disclaimer of warranty constitutes an essential part of this | ||||
|    License. No use of  any Covered Software is authorized under this License | ||||
|    except under this disclaimer. | ||||
| 
 | ||||
| 7. Limitation of Liability | ||||
| 
 | ||||
|    Under no circumstances and under no legal theory, whether tort (including | ||||
|    negligence), contract, or otherwise, shall any Contributor, or anyone who | ||||
|    distributes Covered Software as permitted above, be liable to You for any | ||||
|    direct, indirect, special, incidental, or consequential damages of any | ||||
|    character including, without limitation, damages for lost profits, loss of | ||||
|    goodwill, work stoppage, computer failure or malfunction, or any and all | ||||
|    other commercial damages or losses, even if such party shall have been | ||||
|    informed of the possibility of such damages. This limitation of liability | ||||
|    shall not apply to liability for death or personal injury resulting from such | ||||
|    party’s negligence to the extent applicable law prohibits such limitation. | ||||
|    Some jurisdictions do not allow the exclusion or limitation of incidental or | ||||
|    consequential damages, so this exclusion and limitation may not apply to You. | ||||
| 
 | ||||
| 8. Litigation | ||||
| 
 | ||||
|    Any litigation relating to this License may be brought only in the courts of | ||||
|    a jurisdiction where the defendant maintains its principal place of business | ||||
|    and such litigation shall be governed by laws of that jurisdiction, without | ||||
|    reference to its conflict-of-law provisions. Nothing in this Section shall | ||||
|    prevent a party’s ability to bring cross-claims or counter-claims. | ||||
| 
 | ||||
| 9. Miscellaneous | ||||
| 
 | ||||
|    This License represents the complete agreement concerning the subject matter | ||||
|    hereof. If any provision of this License is held to be unenforceable, such | ||||
|    provision shall be reformed only to the extent necessary to make it | ||||
|    enforceable. Any law or regulation which provides that the language of a | ||||
|    contract shall be construed against the drafter shall not be used to construe | ||||
|    this License against a Contributor. | ||||
| 
 | ||||
| 
 | ||||
| 10. Versions of the License | ||||
| 
 | ||||
| 10.1. New Versions | ||||
| 
 | ||||
|       Mozilla Foundation is the license steward. Except as provided in Section | ||||
|       10.3, no one other than the license steward has the right to modify or | ||||
|       publish new versions of this License. Each version will be given a | ||||
|       distinguishing version number. | ||||
| 
 | ||||
| 10.2. Effect of New Versions | ||||
| 
 | ||||
|       You may distribute the Covered Software under the terms of the version of | ||||
|       the License under which You originally received the Covered Software, or | ||||
|       under the terms of any subsequent version published by the license | ||||
|       steward. | ||||
| 
 | ||||
| 10.3. Modified Versions | ||||
| 
 | ||||
|       If you create software not governed by this License, and you want to | ||||
|       create a new license for such software, you may create and use a modified | ||||
|       version of this License if you rename the license and remove any | ||||
|       references to the name of the license steward (except to note that such | ||||
|       modified license differs from this License). | ||||
| 
 | ||||
| 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses | ||||
|       If You choose to distribute Source Code Form that is Incompatible With | ||||
|       Secondary Licenses under the terms of this version of the License, the | ||||
|       notice described in Exhibit B of this License must be attached. | ||||
| 
 | ||||
| Exhibit A - Source Code Form License Notice | ||||
| 
 | ||||
|       This Source Code Form is subject to the | ||||
|       terms of the Mozilla Public License, v. | ||||
|       2.0. If a copy of the MPL was not | ||||
|       distributed with this file, You can | ||||
|       obtain one at | ||||
|       http://mozilla.org/MPL/2.0/. | ||||
| 
 | ||||
| If it is not possible or desirable to put the notice in a particular file, then | ||||
| You may include the notice in a location (such as a LICENSE file in a relevant | ||||
| directory) where a recipient would be likely to look for such a notice. | ||||
| 
 | ||||
| You may add additional accurate notices of copyright ownership. | ||||
| 
 | ||||
| Exhibit B - “Incompatible With Secondary Licenses” Notice | ||||
| 
 | ||||
|       This Source Code Form is “Incompatible | ||||
|       With Secondary Licenses”, as defined by | ||||
|       the Mozilla Public License, v. 2.0. | ||||
| 
 | ||||
							
								
								
									
										18
									
								
								vendor/github.com/hashicorp/hcl/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/hashicorp/hcl/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,18 +0,0 @@ | |||
| TEST?=./... | ||||
| 
 | ||||
| default: test | ||||
| 
 | ||||
| fmt: generate | ||||
| 	go fmt ./... | ||||
| 
 | ||||
| test: generate | ||||
| 	go get -t ./... | ||||
| 	go test $(TEST) $(TESTARGS) | ||||
| 
 | ||||
| generate: | ||||
| 	go generate ./... | ||||
| 
 | ||||
| updatedeps: | ||||
| 	go get -u golang.org/x/tools/cmd/stringer | ||||
| 
 | ||||
| .PHONY: default generate test updatedeps | ||||
							
								
								
									
										125
									
								
								vendor/github.com/hashicorp/hcl/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										125
									
								
								vendor/github.com/hashicorp/hcl/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,125 +0,0 @@ | |||
| # HCL | ||||
| 
 | ||||
| [](https://godoc.org/github.com/hashicorp/hcl) [](https://travis-ci.org/hashicorp/hcl) | ||||
| 
 | ||||
| HCL (HashiCorp Configuration Language) is a configuration language built | ||||
| by HashiCorp. The goal of HCL is to build a structured configuration language | ||||
| that is both human and machine friendly for use with command-line tools, but | ||||
| specifically targeted towards DevOps tools, servers, etc. | ||||
| 
 | ||||
| HCL is also fully JSON compatible. That is, JSON can be used as completely | ||||
| valid input to a system expecting HCL. This helps makes systems | ||||
| interoperable with other systems. | ||||
| 
 | ||||
| HCL is heavily inspired by | ||||
| [libucl](https://github.com/vstakhov/libucl), | ||||
| nginx configuration, and others similar. | ||||
| 
 | ||||
| ## Why? | ||||
| 
 | ||||
| A common question when viewing HCL is to ask the question: why not | ||||
| JSON, YAML, etc.? | ||||
| 
 | ||||
| Prior to HCL, the tools we built at [HashiCorp](http://www.hashicorp.com) | ||||
| used a variety of configuration languages from full programming languages | ||||
| such as Ruby to complete data structure languages such as JSON. What we | ||||
| learned is that some people wanted human-friendly configuration languages | ||||
| and some people wanted machine-friendly languages. | ||||
| 
 | ||||
| JSON fits a nice balance in this, but is fairly verbose and most | ||||
| importantly doesn't support comments. With YAML, we found that beginners | ||||
| had a really hard time determining what the actual structure was, and | ||||
| ended up guessing more often than not whether to use a hyphen, colon, etc. | ||||
| in order to represent some configuration key. | ||||
| 
 | ||||
| Full programming languages such as Ruby enable complex behavior | ||||
| a configuration language shouldn't usually allow, and also forces | ||||
| people to learn some set of Ruby. | ||||
| 
 | ||||
| Because of this, we decided to create our own configuration language | ||||
| that is JSON-compatible. Our configuration language (HCL) is designed | ||||
| to be written and modified by humans. The API for HCL allows JSON | ||||
| as an input so that it is also machine-friendly (machines can generate | ||||
| JSON instead of trying to generate HCL). | ||||
| 
 | ||||
| Our goal with HCL is not to alienate other configuration languages. | ||||
| It is instead to provide HCL as a specialized language for our tools, | ||||
| and JSON as the interoperability layer. | ||||
| 
 | ||||
| ## Syntax | ||||
| 
 | ||||
| For a complete grammar, please see the parser itself. A high-level overview | ||||
| of the syntax and grammar is listed here. | ||||
| 
 | ||||
|   * Single line comments start with `#` or `//` | ||||
| 
 | ||||
|   * Multi-line comments are wrapped in `/*` and `*/`. Nested block comments | ||||
|     are not allowed. A multi-line comment (also known as a block comment) | ||||
|     terminates at the first `*/` found. | ||||
| 
 | ||||
|   * Values are assigned with the syntax `key = value` (whitespace doesn't | ||||
|     matter). The value can be any primitive: a string, number, boolean, | ||||
|     object, or list. | ||||
| 
 | ||||
|   * Strings are double-quoted and can contain any UTF-8 characters. | ||||
|     Example: `"Hello, World"` | ||||
| 
 | ||||
|   * Multi-line strings start with `<<EOF` at the end of a line, and end | ||||
|     with `EOF` on its own line ([here documents](https://en.wikipedia.org/wiki/Here_document)). | ||||
|     Any text may be used in place of `EOF`. Example: | ||||
| ``` | ||||
| <<FOO | ||||
| hello | ||||
| world | ||||
| FOO | ||||
| ``` | ||||
| 
 | ||||
|   * Numbers are assumed to be base 10. If you prefix a number with 0x, | ||||
|     it is treated as a hexadecimal. If it is prefixed with 0, it is | ||||
|     treated as an octal. Numbers can be in scientific notation: "1e10". | ||||
| 
 | ||||
|   * Boolean values: `true`, `false` | ||||
| 
 | ||||
|   * Arrays can be made by wrapping it in `[]`. Example: | ||||
|     `["foo", "bar", 42]`. Arrays can contain primitives, | ||||
|     other arrays, and objects. As an alternative, lists | ||||
|     of objects can be created with repeated blocks, using | ||||
|     this structure: | ||||
| 
 | ||||
|     ```hcl | ||||
|     service { | ||||
|         key = "value" | ||||
|     } | ||||
| 
 | ||||
|     service { | ||||
|         key = "value" | ||||
|     } | ||||
|     ``` | ||||
| 
 | ||||
| Objects and nested objects are created using the structure shown below: | ||||
| 
 | ||||
| ``` | ||||
| variable "ami" { | ||||
|     description = "the AMI to use" | ||||
| } | ||||
| ``` | ||||
| This would be equivalent to the following json: | ||||
| ``` json | ||||
| { | ||||
|   "variable": { | ||||
|       "ami": { | ||||
|           "description": "the AMI to use" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Thanks | ||||
| 
 | ||||
| Thanks to: | ||||
| 
 | ||||
|   * [@vstakhov](https://github.com/vstakhov) - The original libucl parser | ||||
|     and syntax that HCL was based off of. | ||||
| 
 | ||||
|   * [@fatih](https://github.com/fatih) - The rewritten HCL parser | ||||
|     in pure Go (no goyacc) and support for a printer. | ||||
							
								
								
									
										19
									
								
								vendor/github.com/hashicorp/hcl/appveyor.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/hashicorp/hcl/appveyor.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,19 +0,0 @@ | |||
| version: "build-{branch}-{build}" | ||||
| image: Visual Studio 2015 | ||||
| clone_folder: c:\gopath\src\github.com\hashicorp\hcl | ||||
| environment: | ||||
|   GOPATH: c:\gopath | ||||
| init: | ||||
|   - git config --global core.autocrlf false | ||||
| install: | ||||
| - cmd: >- | ||||
|     echo %Path% | ||||
| 
 | ||||
|     go version | ||||
| 
 | ||||
|     go env | ||||
| 
 | ||||
|     go get -t ./... | ||||
| 
 | ||||
| build_script: | ||||
| - cmd: go test -v ./... | ||||
							
								
								
									
										729
									
								
								vendor/github.com/hashicorp/hcl/decoder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										729
									
								
								vendor/github.com/hashicorp/hcl/decoder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,729 +0,0 @@ | |||
| package hcl | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| 	"github.com/hashicorp/hcl/hcl/parser" | ||||
| 	"github.com/hashicorp/hcl/hcl/token" | ||||
| ) | ||||
| 
 | ||||
| // This is the tag to use with structures to have settings for HCL | ||||
| const tagName = "hcl" | ||||
| 
 | ||||
| var ( | ||||
| 	// nodeType holds a reference to the type of ast.Node | ||||
| 	nodeType reflect.Type = findNodeType() | ||||
| ) | ||||
| 
 | ||||
| // Unmarshal accepts a byte slice as input and writes the | ||||
| // data to the value pointed to by v. | ||||
| func Unmarshal(bs []byte, v interface{}) error { | ||||
| 	root, err := parse(bs) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return DecodeObject(v, root) | ||||
| } | ||||
| 
 | ||||
| // Decode reads the given input and decodes it into the structure | ||||
| // given by `out`. | ||||
| func Decode(out interface{}, in string) error { | ||||
| 	obj, err := Parse(in) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return DecodeObject(out, obj) | ||||
| } | ||||
| 
 | ||||
| // DecodeObject is a lower-level version of Decode. It decodes a | ||||
| // raw Object into the given output. | ||||
| func DecodeObject(out interface{}, n ast.Node) error { | ||||
| 	val := reflect.ValueOf(out) | ||||
| 	if val.Kind() != reflect.Ptr { | ||||
| 		return errors.New("result must be a pointer") | ||||
| 	} | ||||
| 
 | ||||
| 	// If we have the file, we really decode the root node | ||||
| 	if f, ok := n.(*ast.File); ok { | ||||
| 		n = f.Node | ||||
| 	} | ||||
| 
 | ||||
| 	var d decoder | ||||
| 	return d.decode("root", n, val.Elem()) | ||||
| } | ||||
| 
 | ||||
| type decoder struct { | ||||
| 	stack []reflect.Kind | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decode(name string, node ast.Node, result reflect.Value) error { | ||||
| 	k := result | ||||
| 
 | ||||
| 	// If we have an interface with a valid value, we use that | ||||
| 	// for the check. | ||||
| 	if result.Kind() == reflect.Interface { | ||||
| 		elem := result.Elem() | ||||
| 		if elem.IsValid() { | ||||
| 			k = elem | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Push current onto stack unless it is an interface. | ||||
| 	if k.Kind() != reflect.Interface { | ||||
| 		d.stack = append(d.stack, k.Kind()) | ||||
| 
 | ||||
| 		// Schedule a pop | ||||
| 		defer func() { | ||||
| 			d.stack = d.stack[:len(d.stack)-1] | ||||
| 		}() | ||||
| 	} | ||||
| 
 | ||||
| 	switch k.Kind() { | ||||
| 	case reflect.Bool: | ||||
| 		return d.decodeBool(name, node, result) | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		return d.decodeFloat(name, node, result) | ||||
| 	case reflect.Int, reflect.Int32, reflect.Int64: | ||||
| 		return d.decodeInt(name, node, result) | ||||
| 	case reflect.Interface: | ||||
| 		// When we see an interface, we make our own thing | ||||
| 		return d.decodeInterface(name, node, result) | ||||
| 	case reflect.Map: | ||||
| 		return d.decodeMap(name, node, result) | ||||
| 	case reflect.Ptr: | ||||
| 		return d.decodePtr(name, node, result) | ||||
| 	case reflect.Slice: | ||||
| 		return d.decodeSlice(name, node, result) | ||||
| 	case reflect.String: | ||||
| 		return d.decodeString(name, node, result) | ||||
| 	case reflect.Struct: | ||||
| 		return d.decodeStruct(name, node, result) | ||||
| 	default: | ||||
| 		return &parser.PosError{ | ||||
| 			Pos: node.Pos(), | ||||
| 			Err: fmt.Errorf("%s: unknown kind to decode into: %s", name, k.Kind()), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) error { | ||||
| 	switch n := node.(type) { | ||||
| 	case *ast.LiteralType: | ||||
| 		if n.Token.Type == token.BOOL { | ||||
| 			v, err := strconv.ParseBool(n.Token.Text) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			result.Set(reflect.ValueOf(v)) | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &parser.PosError{ | ||||
| 		Pos: node.Pos(), | ||||
| 		Err: fmt.Errorf("%s: unknown type %T", name, node), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error { | ||||
| 	switch n := node.(type) { | ||||
| 	case *ast.LiteralType: | ||||
| 		if n.Token.Type == token.FLOAT || n.Token.Type == token.NUMBER { | ||||
| 			v, err := strconv.ParseFloat(n.Token.Text, 64) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			result.Set(reflect.ValueOf(v).Convert(result.Type())) | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &parser.PosError{ | ||||
| 		Pos: node.Pos(), | ||||
| 		Err: fmt.Errorf("%s: unknown type %T", name, node), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) error { | ||||
| 	switch n := node.(type) { | ||||
| 	case *ast.LiteralType: | ||||
| 		switch n.Token.Type { | ||||
| 		case token.NUMBER: | ||||
| 			v, err := strconv.ParseInt(n.Token.Text, 0, 0) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			if result.Kind() == reflect.Interface { | ||||
| 				result.Set(reflect.ValueOf(int(v))) | ||||
| 			} else { | ||||
| 				result.SetInt(v) | ||||
| 			} | ||||
| 			return nil | ||||
| 		case token.STRING: | ||||
| 			v, err := strconv.ParseInt(n.Token.Value().(string), 0, 0) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			if result.Kind() == reflect.Interface { | ||||
| 				result.Set(reflect.ValueOf(int(v))) | ||||
| 			} else { | ||||
| 				result.SetInt(v) | ||||
| 			} | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &parser.PosError{ | ||||
| 		Pos: node.Pos(), | ||||
| 		Err: fmt.Errorf("%s: unknown type %T", name, node), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Value) error { | ||||
| 	// When we see an ast.Node, we retain the value to enable deferred decoding. | ||||
| 	// Very useful in situations where we want to preserve ast.Node information | ||||
| 	// like Pos | ||||
| 	if result.Type() == nodeType && result.CanSet() { | ||||
| 		result.Set(reflect.ValueOf(node)) | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var set reflect.Value | ||||
| 	redecode := true | ||||
| 
 | ||||
| 	// For testing types, ObjectType should just be treated as a list. We | ||||
| 	// set this to a temporary var because we want to pass in the real node. | ||||
| 	testNode := node | ||||
| 	if ot, ok := node.(*ast.ObjectType); ok { | ||||
| 		testNode = ot.List | ||||
| 	} | ||||
| 
 | ||||
| 	switch n := testNode.(type) { | ||||
| 	case *ast.ObjectList: | ||||
| 		// If we're at the root or we're directly within a slice, then we | ||||
| 		// decode objects into map[string]interface{}, otherwise we decode | ||||
| 		// them into lists. | ||||
| 		if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice { | ||||
| 			var temp map[string]interface{} | ||||
| 			tempVal := reflect.ValueOf(temp) | ||||
| 			result := reflect.MakeMap( | ||||
| 				reflect.MapOf( | ||||
| 					reflect.TypeOf(""), | ||||
| 					tempVal.Type().Elem())) | ||||
| 
 | ||||
| 			set = result | ||||
| 		} else { | ||||
| 			var temp []map[string]interface{} | ||||
| 			tempVal := reflect.ValueOf(temp) | ||||
| 			result := reflect.MakeSlice( | ||||
| 				reflect.SliceOf(tempVal.Type().Elem()), 0, len(n.Items)) | ||||
| 			set = result | ||||
| 		} | ||||
| 	case *ast.ObjectType: | ||||
| 		// If we're at the root or we're directly within a slice, then we | ||||
| 		// decode objects into map[string]interface{}, otherwise we decode | ||||
| 		// them into lists. | ||||
| 		if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice { | ||||
| 			var temp map[string]interface{} | ||||
| 			tempVal := reflect.ValueOf(temp) | ||||
| 			result := reflect.MakeMap( | ||||
| 				reflect.MapOf( | ||||
| 					reflect.TypeOf(""), | ||||
| 					tempVal.Type().Elem())) | ||||
| 
 | ||||
| 			set = result | ||||
| 		} else { | ||||
| 			var temp []map[string]interface{} | ||||
| 			tempVal := reflect.ValueOf(temp) | ||||
| 			result := reflect.MakeSlice( | ||||
| 				reflect.SliceOf(tempVal.Type().Elem()), 0, 1) | ||||
| 			set = result | ||||
| 		} | ||||
| 	case *ast.ListType: | ||||
| 		var temp []interface{} | ||||
| 		tempVal := reflect.ValueOf(temp) | ||||
| 		result := reflect.MakeSlice( | ||||
| 			reflect.SliceOf(tempVal.Type().Elem()), 0, 0) | ||||
| 		set = result | ||||
| 	case *ast.LiteralType: | ||||
| 		switch n.Token.Type { | ||||
| 		case token.BOOL: | ||||
| 			var result bool | ||||
| 			set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) | ||||
| 		case token.FLOAT: | ||||
| 			var result float64 | ||||
| 			set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) | ||||
| 		case token.NUMBER: | ||||
| 			var result int | ||||
| 			set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) | ||||
| 		case token.STRING, token.HEREDOC: | ||||
| 			set = reflect.Indirect(reflect.New(reflect.TypeOf(""))) | ||||
| 		default: | ||||
| 			return &parser.PosError{ | ||||
| 				Pos: node.Pos(), | ||||
| 				Err: fmt.Errorf("%s: cannot decode into interface: %T", name, node), | ||||
| 			} | ||||
| 		} | ||||
| 	default: | ||||
| 		return fmt.Errorf( | ||||
| 			"%s: cannot decode into interface: %T", | ||||
| 			name, node) | ||||
| 	} | ||||
| 
 | ||||
| 	// Set the result to what its supposed to be, then reset | ||||
| 	// result so we don't reflect into this method anymore. | ||||
| 	result.Set(set) | ||||
| 
 | ||||
| 	if redecode { | ||||
| 		// Revisit the node so that we can use the newly instantiated | ||||
| 		// thing and populate it. | ||||
| 		if err := d.decode(name, node, result); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) error { | ||||
| 	if item, ok := node.(*ast.ObjectItem); ok { | ||||
| 		node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} | ||||
| 	} | ||||
| 
 | ||||
| 	if ot, ok := node.(*ast.ObjectType); ok { | ||||
| 		node = ot.List | ||||
| 	} | ||||
| 
 | ||||
| 	n, ok := node.(*ast.ObjectList) | ||||
| 	if !ok { | ||||
| 		return &parser.PosError{ | ||||
| 			Pos: node.Pos(), | ||||
| 			Err: fmt.Errorf("%s: not an object type for map (%T)", name, node), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// If we have an interface, then we can address the interface, | ||||
| 	// but not the slice itself, so get the element but set the interface | ||||
| 	set := result | ||||
| 	if result.Kind() == reflect.Interface { | ||||
| 		result = result.Elem() | ||||
| 	} | ||||
| 
 | ||||
| 	resultType := result.Type() | ||||
| 	resultElemType := resultType.Elem() | ||||
| 	resultKeyType := resultType.Key() | ||||
| 	if resultKeyType.Kind() != reflect.String { | ||||
| 		return &parser.PosError{ | ||||
| 			Pos: node.Pos(), | ||||
| 			Err: fmt.Errorf("%s: map must have string keys", name), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Make a map if it is nil | ||||
| 	resultMap := result | ||||
| 	if result.IsNil() { | ||||
| 		resultMap = reflect.MakeMap( | ||||
| 			reflect.MapOf(resultKeyType, resultElemType)) | ||||
| 	} | ||||
| 
 | ||||
| 	// Go through each element and decode it. | ||||
| 	done := make(map[string]struct{}) | ||||
| 	for _, item := range n.Items { | ||||
| 		if item.Val == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		// github.com/hashicorp/terraform/issue/5740 | ||||
| 		if len(item.Keys) == 0 { | ||||
| 			return &parser.PosError{ | ||||
| 				Pos: node.Pos(), | ||||
| 				Err: fmt.Errorf("%s: map must have string keys", name), | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// Get the key we're dealing with, which is the first item | ||||
| 		keyStr := item.Keys[0].Token.Value().(string) | ||||
| 
 | ||||
| 		// If we've already processed this key, then ignore it | ||||
| 		if _, ok := done[keyStr]; ok { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		// Determine the value. If we have more than one key, then we | ||||
| 		// get the objectlist of only these keys. | ||||
| 		itemVal := item.Val | ||||
| 		if len(item.Keys) > 1 { | ||||
| 			itemVal = n.Filter(keyStr) | ||||
| 			done[keyStr] = struct{}{} | ||||
| 		} | ||||
| 
 | ||||
| 		// Make the field name | ||||
| 		fieldName := fmt.Sprintf("%s.%s", name, keyStr) | ||||
| 
 | ||||
| 		// Get the key/value as reflection values | ||||
| 		key := reflect.ValueOf(keyStr) | ||||
| 		val := reflect.Indirect(reflect.New(resultElemType)) | ||||
| 
 | ||||
| 		// If we have a pre-existing value in the map, use that | ||||
| 		oldVal := resultMap.MapIndex(key) | ||||
| 		if oldVal.IsValid() { | ||||
| 			val.Set(oldVal) | ||||
| 		} | ||||
| 
 | ||||
| 		// Decode! | ||||
| 		if err := d.decode(fieldName, itemVal, val); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		// Set the value on the map | ||||
| 		resultMap.SetMapIndex(key, val) | ||||
| 	} | ||||
| 
 | ||||
| 	// Set the final map if we can | ||||
| 	set.Set(resultMap) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodePtr(name string, node ast.Node, result reflect.Value) error { | ||||
| 	// Create an element of the concrete (non pointer) type and decode | ||||
| 	// into that. Then set the value of the pointer to this type. | ||||
| 	resultType := result.Type() | ||||
| 	resultElemType := resultType.Elem() | ||||
| 	val := reflect.New(resultElemType) | ||||
| 	if err := d.decode(name, node, reflect.Indirect(val)); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	result.Set(val) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) error { | ||||
| 	// If we have an interface, then we can address the interface, | ||||
| 	// but not the slice itself, so get the element but set the interface | ||||
| 	set := result | ||||
| 	if result.Kind() == reflect.Interface { | ||||
| 		result = result.Elem() | ||||
| 	} | ||||
| 	// Create the slice if it isn't nil | ||||
| 	resultType := result.Type() | ||||
| 	resultElemType := resultType.Elem() | ||||
| 	if result.IsNil() { | ||||
| 		resultSliceType := reflect.SliceOf(resultElemType) | ||||
| 		result = reflect.MakeSlice( | ||||
| 			resultSliceType, 0, 0) | ||||
| 	} | ||||
| 
 | ||||
| 	// Figure out the items we'll be copying into the slice | ||||
| 	var items []ast.Node | ||||
| 	switch n := node.(type) { | ||||
| 	case *ast.ObjectList: | ||||
| 		items = make([]ast.Node, len(n.Items)) | ||||
| 		for i, item := range n.Items { | ||||
| 			items[i] = item | ||||
| 		} | ||||
| 	case *ast.ObjectType: | ||||
| 		items = []ast.Node{n} | ||||
| 	case *ast.ListType: | ||||
| 		items = n.List | ||||
| 	default: | ||||
| 		return &parser.PosError{ | ||||
| 			Pos: node.Pos(), | ||||
| 			Err: fmt.Errorf("unknown slice type: %T", node), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for i, item := range items { | ||||
| 		fieldName := fmt.Sprintf("%s[%d]", name, i) | ||||
| 
 | ||||
| 		// Decode | ||||
| 		val := reflect.Indirect(reflect.New(resultElemType)) | ||||
| 
 | ||||
| 		// if item is an object that was decoded from ambiguous JSON and | ||||
| 		// flattened, make sure it's expanded if it needs to decode into a | ||||
| 		// defined structure. | ||||
| 		item := expandObject(item, val) | ||||
| 
 | ||||
| 		if err := d.decode(fieldName, item, val); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		// Append it onto the slice | ||||
| 		result = reflect.Append(result, val) | ||||
| 	} | ||||
| 
 | ||||
| 	set.Set(result) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // expandObject detects if an ambiguous JSON object was flattened to a List which | ||||
| // should be decoded into a struct, and expands the ast to properly deocode. | ||||
| func expandObject(node ast.Node, result reflect.Value) ast.Node { | ||||
| 	item, ok := node.(*ast.ObjectItem) | ||||
| 	if !ok { | ||||
| 		return node | ||||
| 	} | ||||
| 
 | ||||
| 	elemType := result.Type() | ||||
| 
 | ||||
| 	// our target type must be a struct | ||||
| 	switch elemType.Kind() { | ||||
| 	case reflect.Ptr: | ||||
| 		switch elemType.Elem().Kind() { | ||||
| 		case reflect.Struct: | ||||
| 			//OK | ||||
| 		default: | ||||
| 			return node | ||||
| 		} | ||||
| 	case reflect.Struct: | ||||
| 		//OK | ||||
| 	default: | ||||
| 		return node | ||||
| 	} | ||||
| 
 | ||||
| 	// A list value will have a key and field name. If it had more fields, | ||||
| 	// it wouldn't have been flattened. | ||||
| 	if len(item.Keys) != 2 { | ||||
| 		return node | ||||
| 	} | ||||
| 
 | ||||
| 	keyToken := item.Keys[0].Token | ||||
| 	item.Keys = item.Keys[1:] | ||||
| 
 | ||||
| 	// we need to un-flatten the ast enough to decode | ||||
| 	newNode := &ast.ObjectItem{ | ||||
| 		Keys: []*ast.ObjectKey{ | ||||
| 			&ast.ObjectKey{ | ||||
| 				Token: keyToken, | ||||
| 			}, | ||||
| 		}, | ||||
| 		Val: &ast.ObjectType{ | ||||
| 			List: &ast.ObjectList{ | ||||
| 				Items: []*ast.ObjectItem{item}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	return newNode | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value) error { | ||||
| 	switch n := node.(type) { | ||||
| 	case *ast.LiteralType: | ||||
| 		switch n.Token.Type { | ||||
| 		case token.NUMBER: | ||||
| 			result.Set(reflect.ValueOf(n.Token.Text).Convert(result.Type())) | ||||
| 			return nil | ||||
| 		case token.STRING, token.HEREDOC: | ||||
| 			result.Set(reflect.ValueOf(n.Token.Value()).Convert(result.Type())) | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &parser.PosError{ | ||||
| 		Pos: node.Pos(), | ||||
| 		Err: fmt.Errorf("%s: unknown type for string %T", name, node), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) error { | ||||
| 	var item *ast.ObjectItem | ||||
| 	if it, ok := node.(*ast.ObjectItem); ok { | ||||
| 		item = it | ||||
| 		node = it.Val | ||||
| 	} | ||||
| 
 | ||||
| 	if ot, ok := node.(*ast.ObjectType); ok { | ||||
| 		node = ot.List | ||||
| 	} | ||||
| 
 | ||||
| 	// Handle the special case where the object itself is a literal. Previously | ||||
| 	// the yacc parser would always ensure top-level elements were arrays. The new | ||||
| 	// parser does not make the same guarantees, thus we need to convert any | ||||
| 	// top-level literal elements into a list. | ||||
| 	if _, ok := node.(*ast.LiteralType); ok && item != nil { | ||||
| 		node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} | ||||
| 	} | ||||
| 
 | ||||
| 	list, ok := node.(*ast.ObjectList) | ||||
| 	if !ok { | ||||
| 		return &parser.PosError{ | ||||
| 			Pos: node.Pos(), | ||||
| 			Err: fmt.Errorf("%s: not an object type for struct (%T)", name, node), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// This slice will keep track of all the structs we'll be decoding. | ||||
| 	// There can be more than one struct if there are embedded structs | ||||
| 	// that are squashed. | ||||
| 	structs := make([]reflect.Value, 1, 5) | ||||
| 	structs[0] = result | ||||
| 
 | ||||
| 	// Compile the list of all the fields that we're going to be decoding | ||||
| 	// from all the structs. | ||||
| 	type field struct { | ||||
| 		field reflect.StructField | ||||
| 		val   reflect.Value | ||||
| 	} | ||||
| 	fields := []field{} | ||||
| 	for len(structs) > 0 { | ||||
| 		structVal := structs[0] | ||||
| 		structs = structs[1:] | ||||
| 
 | ||||
| 		structType := structVal.Type() | ||||
| 		for i := 0; i < structType.NumField(); i++ { | ||||
| 			fieldType := structType.Field(i) | ||||
| 			tagParts := strings.Split(fieldType.Tag.Get(tagName), ",") | ||||
| 
 | ||||
| 			// Ignore fields with tag name "-" | ||||
| 			if tagParts[0] == "-" { | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			if fieldType.Anonymous { | ||||
| 				fieldKind := fieldType.Type.Kind() | ||||
| 				if fieldKind != reflect.Struct { | ||||
| 					return &parser.PosError{ | ||||
| 						Pos: node.Pos(), | ||||
| 						Err: fmt.Errorf("%s: unsupported type to struct: %s", | ||||
| 							fieldType.Name, fieldKind), | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				// We have an embedded field. We "squash" the fields down | ||||
| 				// if specified in the tag. | ||||
| 				squash := false | ||||
| 				for _, tag := range tagParts[1:] { | ||||
| 					if tag == "squash" { | ||||
| 						squash = true | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if squash { | ||||
| 					structs = append( | ||||
| 						structs, result.FieldByName(fieldType.Name)) | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// Normal struct field, store it away | ||||
| 			fields = append(fields, field{fieldType, structVal.Field(i)}) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	usedKeys := make(map[string]struct{}) | ||||
| 	decodedFields := make([]string, 0, len(fields)) | ||||
| 	decodedFieldsVal := make([]reflect.Value, 0) | ||||
| 	unusedKeysVal := make([]reflect.Value, 0) | ||||
| 	for _, f := range fields { | ||||
| 		field, fieldValue := f.field, f.val | ||||
| 		if !fieldValue.IsValid() { | ||||
| 			// This should never happen | ||||
| 			panic("field is not valid") | ||||
| 		} | ||||
| 
 | ||||
| 		// If we can't set the field, then it is unexported or something, | ||||
| 		// and we just continue onwards. | ||||
| 		if !fieldValue.CanSet() { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		fieldName := field.Name | ||||
| 
 | ||||
| 		tagValue := field.Tag.Get(tagName) | ||||
| 		tagParts := strings.SplitN(tagValue, ",", 2) | ||||
| 		if len(tagParts) >= 2 { | ||||
| 			switch tagParts[1] { | ||||
| 			case "decodedFields": | ||||
| 				decodedFieldsVal = append(decodedFieldsVal, fieldValue) | ||||
| 				continue | ||||
| 			case "key": | ||||
| 				if item == nil { | ||||
| 					return &parser.PosError{ | ||||
| 						Pos: node.Pos(), | ||||
| 						Err: fmt.Errorf("%s: %s asked for 'key', impossible", | ||||
| 							name, fieldName), | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				fieldValue.SetString(item.Keys[0].Token.Value().(string)) | ||||
| 				continue | ||||
| 			case "unusedKeys": | ||||
| 				unusedKeysVal = append(unusedKeysVal, fieldValue) | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if tagParts[0] != "" { | ||||
| 			fieldName = tagParts[0] | ||||
| 		} | ||||
| 
 | ||||
| 		// Determine the element we'll use to decode. If it is a single | ||||
| 		// match (only object with the field), then we decode it exactly. | ||||
| 		// If it is a prefix match, then we decode the matches. | ||||
| 		filter := list.Filter(fieldName) | ||||
| 
 | ||||
| 		prefixMatches := filter.Children() | ||||
| 		matches := filter.Elem() | ||||
| 		if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		// Track the used key | ||||
| 		usedKeys[fieldName] = struct{}{} | ||||
| 
 | ||||
| 		// Create the field name and decode. We range over the elements | ||||
| 		// because we actually want the value. | ||||
| 		fieldName = fmt.Sprintf("%s.%s", name, fieldName) | ||||
| 		if len(prefixMatches.Items) > 0 { | ||||
| 			if err := d.decode(fieldName, prefixMatches, fieldValue); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 		for _, match := range matches.Items { | ||||
| 			var decodeNode ast.Node = match.Val | ||||
| 			if ot, ok := decodeNode.(*ast.ObjectType); ok { | ||||
| 				decodeNode = &ast.ObjectList{Items: ot.List.Items} | ||||
| 			} | ||||
| 
 | ||||
| 			if err := d.decode(fieldName, decodeNode, fieldValue); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		decodedFields = append(decodedFields, field.Name) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(decodedFieldsVal) > 0 { | ||||
| 		// Sort it so that it is deterministic | ||||
| 		sort.Strings(decodedFields) | ||||
| 
 | ||||
| 		for _, v := range decodedFieldsVal { | ||||
| 			v.Set(reflect.ValueOf(decodedFields)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // findNodeType returns the type of ast.Node | ||||
| func findNodeType() reflect.Type { | ||||
| 	var nodeContainer struct { | ||||
| 		Node ast.Node | ||||
| 	} | ||||
| 	value := reflect.ValueOf(nodeContainer).FieldByName("Node") | ||||
| 	return value.Type() | ||||
| } | ||||
							
								
								
									
										11
									
								
								vendor/github.com/hashicorp/hcl/hcl.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/hashicorp/hcl/hcl.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,11 +0,0 @@ | |||
| // Package hcl decodes HCL into usable Go structures. | ||||
| // | ||||
| // hcl input can come in either pure HCL format or JSON format. | ||||
| // It can be parsed into an AST, and then decoded into a structure, | ||||
| // or it can be decoded directly from a string into a structure. | ||||
| // | ||||
| // If you choose to parse HCL into a raw AST, the benefit is that you | ||||
| // can write custom visitor implementations to implement custom | ||||
| // semantic checks. By default, HCL does not perform any semantic | ||||
| // checks. | ||||
| package hcl | ||||
							
								
								
									
										219
									
								
								vendor/github.com/hashicorp/hcl/hcl/ast/ast.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										219
									
								
								vendor/github.com/hashicorp/hcl/hcl/ast/ast.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,219 +0,0 @@ | |||
| // Package ast declares the types used to represent syntax trees for HCL | ||||
| // (HashiCorp Configuration Language) | ||||
| package ast | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/token" | ||||
| ) | ||||
| 
 | ||||
| // Node is an element in the abstract syntax tree. | ||||
| type Node interface { | ||||
| 	node() | ||||
| 	Pos() token.Pos | ||||
| } | ||||
| 
 | ||||
| func (File) node()         {} | ||||
| func (ObjectList) node()   {} | ||||
| func (ObjectKey) node()    {} | ||||
| func (ObjectItem) node()   {} | ||||
| func (Comment) node()      {} | ||||
| func (CommentGroup) node() {} | ||||
| func (ObjectType) node()   {} | ||||
| func (LiteralType) node()  {} | ||||
| func (ListType) node()     {} | ||||
| 
 | ||||
| // File represents a single HCL file | ||||
| type File struct { | ||||
| 	Node     Node            // usually a *ObjectList | ||||
| 	Comments []*CommentGroup // list of all comments in the source | ||||
| } | ||||
| 
 | ||||
| func (f *File) Pos() token.Pos { | ||||
| 	return f.Node.Pos() | ||||
| } | ||||
| 
 | ||||
| // ObjectList represents a list of ObjectItems. An HCL file itself is an | ||||
| // ObjectList. | ||||
| type ObjectList struct { | ||||
| 	Items []*ObjectItem | ||||
| } | ||||
| 
 | ||||
| func (o *ObjectList) Add(item *ObjectItem) { | ||||
| 	o.Items = append(o.Items, item) | ||||
| } | ||||
| 
 | ||||
| // Filter filters out the objects with the given key list as a prefix. | ||||
| // | ||||
| // The returned list of objects contain ObjectItems where the keys have | ||||
| // this prefix already stripped off. This might result in objects with | ||||
| // zero-length key lists if they have no children. | ||||
| // | ||||
| // If no matches are found, an empty ObjectList (non-nil) is returned. | ||||
| func (o *ObjectList) Filter(keys ...string) *ObjectList { | ||||
| 	var result ObjectList | ||||
| 	for _, item := range o.Items { | ||||
| 		// If there aren't enough keys, then ignore this | ||||
| 		if len(item.Keys) < len(keys) { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		match := true | ||||
| 		for i, key := range item.Keys[:len(keys)] { | ||||
| 			key := key.Token.Value().(string) | ||||
| 			if key != keys[i] && !strings.EqualFold(key, keys[i]) { | ||||
| 				match = false | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if !match { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		// Strip off the prefix from the children | ||||
| 		newItem := *item | ||||
| 		newItem.Keys = newItem.Keys[len(keys):] | ||||
| 		result.Add(&newItem) | ||||
| 	} | ||||
| 
 | ||||
| 	return &result | ||||
| } | ||||
| 
 | ||||
| // Children returns further nested objects (key length > 0) within this | ||||
| // ObjectList. This should be used with Filter to get at child items. | ||||
| func (o *ObjectList) Children() *ObjectList { | ||||
| 	var result ObjectList | ||||
| 	for _, item := range o.Items { | ||||
| 		if len(item.Keys) > 0 { | ||||
| 			result.Add(item) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &result | ||||
| } | ||||
| 
 | ||||
| // Elem returns items in the list that are direct element assignments | ||||
| // (key length == 0). This should be used with Filter to get at elements. | ||||
| func (o *ObjectList) Elem() *ObjectList { | ||||
| 	var result ObjectList | ||||
| 	for _, item := range o.Items { | ||||
| 		if len(item.Keys) == 0 { | ||||
| 			result.Add(item) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &result | ||||
| } | ||||
| 
 | ||||
| func (o *ObjectList) Pos() token.Pos { | ||||
| 	// always returns the uninitiliazed position | ||||
| 	return o.Items[0].Pos() | ||||
| } | ||||
| 
 | ||||
| // ObjectItem represents a HCL Object Item. An item is represented with a key | ||||
| // (or keys). It can be an assignment or an object (both normal and nested) | ||||
| type ObjectItem struct { | ||||
| 	// keys is only one length long if it's of type assignment. If it's a | ||||
| 	// nested object it can be larger than one. In that case "assign" is | ||||
| 	// invalid as there is no assignments for a nested object. | ||||
| 	Keys []*ObjectKey | ||||
| 
 | ||||
| 	// assign contains the position of "=", if any | ||||
| 	Assign token.Pos | ||||
| 
 | ||||
| 	// val is the item itself. It can be an object,list, number, bool or a | ||||
| 	// string. If key length is larger than one, val can be only of type | ||||
| 	// Object. | ||||
| 	Val Node | ||||
| 
 | ||||
| 	LeadComment *CommentGroup // associated lead comment | ||||
| 	LineComment *CommentGroup // associated line comment | ||||
| } | ||||
| 
 | ||||
| func (o *ObjectItem) Pos() token.Pos { | ||||
| 	// I'm not entirely sure what causes this, but removing this causes | ||||
| 	// a test failure. We should investigate at some point. | ||||
| 	if len(o.Keys) == 0 { | ||||
| 		return token.Pos{} | ||||
| 	} | ||||
| 
 | ||||
| 	return o.Keys[0].Pos() | ||||
| } | ||||
| 
 | ||||
| // ObjectKeys are either an identifier or of type string. | ||||
| type ObjectKey struct { | ||||
| 	Token token.Token | ||||
| } | ||||
| 
 | ||||
| func (o *ObjectKey) Pos() token.Pos { | ||||
| 	return o.Token.Pos | ||||
| } | ||||
| 
 | ||||
| // LiteralType represents a literal of basic type. Valid types are: | ||||
| // token.NUMBER, token.FLOAT, token.BOOL and token.STRING | ||||
| type LiteralType struct { | ||||
| 	Token token.Token | ||||
| 
 | ||||
| 	// comment types, only used when in a list | ||||
| 	LeadComment *CommentGroup | ||||
| 	LineComment *CommentGroup | ||||
| } | ||||
| 
 | ||||
| func (l *LiteralType) Pos() token.Pos { | ||||
| 	return l.Token.Pos | ||||
| } | ||||
| 
 | ||||
| // ListStatement represents a HCL List type | ||||
| type ListType struct { | ||||
| 	Lbrack token.Pos // position of "[" | ||||
| 	Rbrack token.Pos // position of "]" | ||||
| 	List   []Node    // the elements in lexical order | ||||
| } | ||||
| 
 | ||||
| func (l *ListType) Pos() token.Pos { | ||||
| 	return l.Lbrack | ||||
| } | ||||
| 
 | ||||
| func (l *ListType) Add(node Node) { | ||||
| 	l.List = append(l.List, node) | ||||
| } | ||||
| 
 | ||||
| // ObjectType represents a HCL Object Type | ||||
| type ObjectType struct { | ||||
| 	Lbrace token.Pos   // position of "{" | ||||
| 	Rbrace token.Pos   // position of "}" | ||||
| 	List   *ObjectList // the nodes in lexical order | ||||
| } | ||||
| 
 | ||||
| func (o *ObjectType) Pos() token.Pos { | ||||
| 	return o.Lbrace | ||||
| } | ||||
| 
 | ||||
| // Comment node represents a single //, # style or /*- style commment | ||||
| type Comment struct { | ||||
| 	Start token.Pos // position of / or # | ||||
| 	Text  string | ||||
| } | ||||
| 
 | ||||
| func (c *Comment) Pos() token.Pos { | ||||
| 	return c.Start | ||||
| } | ||||
| 
 | ||||
| // CommentGroup node represents a sequence of comments with no other tokens and | ||||
| // no empty lines between. | ||||
| type CommentGroup struct { | ||||
| 	List []*Comment // len(List) > 0 | ||||
| } | ||||
| 
 | ||||
| func (c *CommentGroup) Pos() token.Pos { | ||||
| 	return c.List[0].Pos() | ||||
| } | ||||
| 
 | ||||
| //------------------------------------------------------------------- | ||||
| // GoStringer | ||||
| //------------------------------------------------------------------- | ||||
| 
 | ||||
| func (o *ObjectKey) GoString() string  { return fmt.Sprintf("*%#v", *o) } | ||||
| func (o *ObjectList) GoString() string { return fmt.Sprintf("*%#v", *o) } | ||||
							
								
								
									
										52
									
								
								vendor/github.com/hashicorp/hcl/hcl/ast/walk.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/hashicorp/hcl/hcl/ast/walk.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,52 +0,0 @@ | |||
| package ast | ||||
| 
 | ||||
| import "fmt" | ||||
| 
 | ||||
| // WalkFunc describes a function to be called for each node during a Walk. The | ||||
| // returned node can be used to rewrite the AST. Walking stops the returned | ||||
| // bool is false. | ||||
| type WalkFunc func(Node) (Node, bool) | ||||
| 
 | ||||
| // Walk traverses an AST in depth-first order: It starts by calling fn(node); | ||||
| // node must not be nil. If fn returns true, Walk invokes fn recursively for | ||||
| // each of the non-nil children of node, followed by a call of fn(nil). The | ||||
| // returned node of fn can be used to rewrite the passed node to fn. | ||||
| func Walk(node Node, fn WalkFunc) Node { | ||||
| 	rewritten, ok := fn(node) | ||||
| 	if !ok { | ||||
| 		return rewritten | ||||
| 	} | ||||
| 
 | ||||
| 	switch n := node.(type) { | ||||
| 	case *File: | ||||
| 		n.Node = Walk(n.Node, fn) | ||||
| 	case *ObjectList: | ||||
| 		for i, item := range n.Items { | ||||
| 			n.Items[i] = Walk(item, fn).(*ObjectItem) | ||||
| 		} | ||||
| 	case *ObjectKey: | ||||
| 		// nothing to do | ||||
| 	case *ObjectItem: | ||||
| 		for i, k := range n.Keys { | ||||
| 			n.Keys[i] = Walk(k, fn).(*ObjectKey) | ||||
| 		} | ||||
| 
 | ||||
| 		if n.Val != nil { | ||||
| 			n.Val = Walk(n.Val, fn) | ||||
| 		} | ||||
| 	case *LiteralType: | ||||
| 		// nothing to do | ||||
| 	case *ListType: | ||||
| 		for i, l := range n.List { | ||||
| 			n.List[i] = Walk(l, fn) | ||||
| 		} | ||||
| 	case *ObjectType: | ||||
| 		n.List = Walk(n.List, fn).(*ObjectList) | ||||
| 	default: | ||||
| 		// should we panic here? | ||||
| 		fmt.Printf("unknown type: %T\n", n) | ||||
| 	} | ||||
| 
 | ||||
| 	fn(nil) | ||||
| 	return rewritten | ||||
| } | ||||
							
								
								
									
										17
									
								
								vendor/github.com/hashicorp/hcl/hcl/parser/error.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/hashicorp/hcl/hcl/parser/error.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,17 +0,0 @@ | |||
| package parser | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/token" | ||||
| ) | ||||
| 
 | ||||
| // PosError is a parse error that contains a position. | ||||
| type PosError struct { | ||||
| 	Pos token.Pos | ||||
| 	Err error | ||||
| } | ||||
| 
 | ||||
| func (e *PosError) Error() string { | ||||
| 	return fmt.Sprintf("At %s: %s", e.Pos, e.Err) | ||||
| } | ||||
							
								
								
									
										532
									
								
								vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										532
									
								
								vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,532 +0,0 @@ | |||
| // Package parser implements a parser for HCL (HashiCorp Configuration | ||||
| // Language) | ||||
| package parser | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| 	"github.com/hashicorp/hcl/hcl/scanner" | ||||
| 	"github.com/hashicorp/hcl/hcl/token" | ||||
| ) | ||||
| 
 | ||||
| type Parser struct { | ||||
| 	sc *scanner.Scanner | ||||
| 
 | ||||
| 	// Last read token | ||||
| 	tok       token.Token | ||||
| 	commaPrev token.Token | ||||
| 
 | ||||
| 	comments    []*ast.CommentGroup | ||||
| 	leadComment *ast.CommentGroup // last lead comment | ||||
| 	lineComment *ast.CommentGroup // last line comment | ||||
| 
 | ||||
| 	enableTrace bool | ||||
| 	indent      int | ||||
| 	n           int // buffer size (max = 1) | ||||
| } | ||||
| 
 | ||||
| func newParser(src []byte) *Parser { | ||||
| 	return &Parser{ | ||||
| 		sc: scanner.New(src), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Parse returns the fully parsed source and returns the abstract syntax tree. | ||||
| func Parse(src []byte) (*ast.File, error) { | ||||
| 	// normalize all line endings | ||||
| 	// since the scanner and output only work with "\n" line endings, we may | ||||
| 	// end up with dangling "\r" characters in the parsed data. | ||||
| 	src = bytes.Replace(src, []byte("\r\n"), []byte("\n"), -1) | ||||
| 
 | ||||
| 	p := newParser(src) | ||||
| 	return p.Parse() | ||||
| } | ||||
| 
 | ||||
| var errEofToken = errors.New("EOF token found") | ||||
| 
 | ||||
| // Parse returns the fully parsed source and returns the abstract syntax tree. | ||||
| func (p *Parser) Parse() (*ast.File, error) { | ||||
| 	f := &ast.File{} | ||||
| 	var err, scerr error | ||||
| 	p.sc.Error = func(pos token.Pos, msg string) { | ||||
| 		scerr = &PosError{Pos: pos, Err: errors.New(msg)} | ||||
| 	} | ||||
| 
 | ||||
| 	f.Node, err = p.objectList(false) | ||||
| 	if scerr != nil { | ||||
| 		return nil, scerr | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	f.Comments = p.comments | ||||
| 	return f, nil | ||||
| } | ||||
| 
 | ||||
| // objectList parses a list of items within an object (generally k/v pairs). | ||||
| // The parameter" obj" tells this whether to we are within an object (braces: | ||||
| // '{', '}') or just at the top level. If we're within an object, we end | ||||
| // at an RBRACE. | ||||
| func (p *Parser) objectList(obj bool) (*ast.ObjectList, error) { | ||||
| 	defer un(trace(p, "ParseObjectList")) | ||||
| 	node := &ast.ObjectList{} | ||||
| 
 | ||||
| 	for { | ||||
| 		if obj { | ||||
| 			tok := p.scan() | ||||
| 			p.unscan() | ||||
| 			if tok.Type == token.RBRACE { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		n, err := p.objectItem() | ||||
| 		if err == errEofToken { | ||||
| 			break // we are finished | ||||
| 		} | ||||
| 
 | ||||
| 		// we don't return a nil node, because might want to use already | ||||
| 		// collected items. | ||||
| 		if err != nil { | ||||
| 			return node, err | ||||
| 		} | ||||
| 
 | ||||
| 		node.Add(n) | ||||
| 
 | ||||
| 		// object lists can be optionally comma-delimited e.g. when a list of maps | ||||
| 		// is being expressed, so a comma is allowed here - it's simply consumed | ||||
| 		tok := p.scan() | ||||
| 		if tok.Type != token.COMMA { | ||||
| 			p.unscan() | ||||
| 		} | ||||
| 	} | ||||
| 	return node, nil | ||||
| } | ||||
| 
 | ||||
| func (p *Parser) consumeComment() (comment *ast.Comment, endline int) { | ||||
| 	endline = p.tok.Pos.Line | ||||
| 
 | ||||
| 	// count the endline if it's multiline comment, ie starting with /* | ||||
| 	if len(p.tok.Text) > 1 && p.tok.Text[1] == '*' { | ||||
| 		// don't use range here - no need to decode Unicode code points | ||||
| 		for i := 0; i < len(p.tok.Text); i++ { | ||||
| 			if p.tok.Text[i] == '\n' { | ||||
| 				endline++ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	comment = &ast.Comment{Start: p.tok.Pos, Text: p.tok.Text} | ||||
| 	p.tok = p.sc.Scan() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (p *Parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) { | ||||
| 	var list []*ast.Comment | ||||
| 	endline = p.tok.Pos.Line | ||||
| 
 | ||||
| 	for p.tok.Type == token.COMMENT && p.tok.Pos.Line <= endline+n { | ||||
| 		var comment *ast.Comment | ||||
| 		comment, endline = p.consumeComment() | ||||
| 		list = append(list, comment) | ||||
| 	} | ||||
| 
 | ||||
| 	// add comment group to the comments list | ||||
| 	comments = &ast.CommentGroup{List: list} | ||||
| 	p.comments = append(p.comments, comments) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // objectItem parses a single object item | ||||
| func (p *Parser) objectItem() (*ast.ObjectItem, error) { | ||||
| 	defer un(trace(p, "ParseObjectItem")) | ||||
| 
 | ||||
| 	keys, err := p.objectKey() | ||||
| 	if len(keys) > 0 && err == errEofToken { | ||||
| 		// We ignore eof token here since it is an error if we didn't | ||||
| 		// receive a value (but we did receive a key) for the item. | ||||
| 		err = nil | ||||
| 	} | ||||
| 	if len(keys) > 0 && err != nil && p.tok.Type == token.RBRACE { | ||||
| 		// This is a strange boolean statement, but what it means is: | ||||
| 		// We have keys with no value, and we're likely in an object | ||||
| 		// (since RBrace ends an object). For this, we set err to nil so | ||||
| 		// we continue and get the error below of having the wrong value | ||||
| 		// type. | ||||
| 		err = nil | ||||
| 
 | ||||
| 		// Reset the token type so we don't think it completed fine. See | ||||
| 		// objectType which uses p.tok.Type to check if we're done with | ||||
| 		// the object. | ||||
| 		p.tok.Type = token.EOF | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	o := &ast.ObjectItem{ | ||||
| 		Keys: keys, | ||||
| 	} | ||||
| 
 | ||||
| 	if p.leadComment != nil { | ||||
| 		o.LeadComment = p.leadComment | ||||
| 		p.leadComment = nil | ||||
| 	} | ||||
| 
 | ||||
| 	switch p.tok.Type { | ||||
| 	case token.ASSIGN: | ||||
| 		o.Assign = p.tok.Pos | ||||
| 		o.Val, err = p.object() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	case token.LBRACE: | ||||
| 		o.Val, err = p.objectType() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	default: | ||||
| 		keyStr := make([]string, 0, len(keys)) | ||||
| 		for _, k := range keys { | ||||
| 			keyStr = append(keyStr, k.Token.Text) | ||||
| 		} | ||||
| 
 | ||||
| 		return nil, &PosError{ | ||||
| 			Pos: p.tok.Pos, | ||||
| 			Err: fmt.Errorf( | ||||
| 				"key '%s' expected start of object ('{') or assignment ('=')", | ||||
| 				strings.Join(keyStr, " ")), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// key=#comment | ||||
| 	// val | ||||
| 	if p.lineComment != nil { | ||||
| 		o.LineComment, p.lineComment = p.lineComment, nil | ||||
| 	} | ||||
| 
 | ||||
| 	// do a look-ahead for line comment | ||||
| 	p.scan() | ||||
| 	if len(keys) > 0 && o.Val.Pos().Line == keys[0].Pos().Line && p.lineComment != nil { | ||||
| 		o.LineComment = p.lineComment | ||||
| 		p.lineComment = nil | ||||
| 	} | ||||
| 	p.unscan() | ||||
| 	return o, nil | ||||
| } | ||||
| 
 | ||||
| // objectKey parses an object key and returns a ObjectKey AST | ||||
| func (p *Parser) objectKey() ([]*ast.ObjectKey, error) { | ||||
| 	keyCount := 0 | ||||
| 	keys := make([]*ast.ObjectKey, 0) | ||||
| 
 | ||||
| 	for { | ||||
| 		tok := p.scan() | ||||
| 		switch tok.Type { | ||||
| 		case token.EOF: | ||||
| 			// It is very important to also return the keys here as well as | ||||
| 			// the error. This is because we need to be able to tell if we | ||||
| 			// did parse keys prior to finding the EOF, or if we just found | ||||
| 			// a bare EOF. | ||||
| 			return keys, errEofToken | ||||
| 		case token.ASSIGN: | ||||
| 			// assignment or object only, but not nested objects. this is not | ||||
| 			// allowed: `foo bar = {}` | ||||
| 			if keyCount > 1 { | ||||
| 				return nil, &PosError{ | ||||
| 					Pos: p.tok.Pos, | ||||
| 					Err: fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type), | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if keyCount == 0 { | ||||
| 				return nil, &PosError{ | ||||
| 					Pos: p.tok.Pos, | ||||
| 					Err: errors.New("no object keys found!"), | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			return keys, nil | ||||
| 		case token.LBRACE: | ||||
| 			var err error | ||||
| 
 | ||||
| 			// If we have no keys, then it is a syntax error. i.e. {{}} is not | ||||
| 			// allowed. | ||||
| 			if len(keys) == 0 { | ||||
| 				err = &PosError{ | ||||
| 					Pos: p.tok.Pos, | ||||
| 					Err: fmt.Errorf("expected: IDENT | STRING got: %s", p.tok.Type), | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// object | ||||
| 			return keys, err | ||||
| 		case token.IDENT, token.STRING: | ||||
| 			keyCount++ | ||||
| 			keys = append(keys, &ast.ObjectKey{Token: p.tok}) | ||||
| 		case token.ILLEGAL: | ||||
| 			return keys, &PosError{ | ||||
| 				Pos: p.tok.Pos, | ||||
| 				Err: fmt.Errorf("illegal character"), | ||||
| 			} | ||||
| 		default: | ||||
| 			return keys, &PosError{ | ||||
| 				Pos: p.tok.Pos, | ||||
| 				Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type), | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // object parses any type of object, such as number, bool, string, object or | ||||
| // list. | ||||
| func (p *Parser) object() (ast.Node, error) { | ||||
| 	defer un(trace(p, "ParseType")) | ||||
| 	tok := p.scan() | ||||
| 
 | ||||
| 	switch tok.Type { | ||||
| 	case token.NUMBER, token.FLOAT, token.BOOL, token.STRING, token.HEREDOC: | ||||
| 		return p.literalType() | ||||
| 	case token.LBRACE: | ||||
| 		return p.objectType() | ||||
| 	case token.LBRACK: | ||||
| 		return p.listType() | ||||
| 	case token.COMMENT: | ||||
| 		// implement comment | ||||
| 	case token.EOF: | ||||
| 		return nil, errEofToken | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, &PosError{ | ||||
| 		Pos: tok.Pos, | ||||
| 		Err: fmt.Errorf("Unknown token: %+v", tok), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // objectType parses an object type and returns a ObjectType AST | ||||
| func (p *Parser) objectType() (*ast.ObjectType, error) { | ||||
| 	defer un(trace(p, "ParseObjectType")) | ||||
| 
 | ||||
| 	// we assume that the currently scanned token is a LBRACE | ||||
| 	o := &ast.ObjectType{ | ||||
| 		Lbrace: p.tok.Pos, | ||||
| 	} | ||||
| 
 | ||||
| 	l, err := p.objectList(true) | ||||
| 
 | ||||
| 	// if we hit RBRACE, we are good to go (means we parsed all Items), if it's | ||||
| 	// not a RBRACE, it's an syntax error and we just return it. | ||||
| 	if err != nil && p.tok.Type != token.RBRACE { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// No error, scan and expect the ending to be a brace | ||||
| 	if tok := p.scan(); tok.Type != token.RBRACE { | ||||
| 		return nil, &PosError{ | ||||
| 			Pos: tok.Pos, | ||||
| 			Err: fmt.Errorf("object expected closing RBRACE got: %s", tok.Type), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	o.List = l | ||||
| 	o.Rbrace = p.tok.Pos // advanced via parseObjectList | ||||
| 	return o, nil | ||||
| } | ||||
| 
 | ||||
| // listType parses a list type and returns a ListType AST | ||||
| func (p *Parser) listType() (*ast.ListType, error) { | ||||
| 	defer un(trace(p, "ParseListType")) | ||||
| 
 | ||||
| 	// we assume that the currently scanned token is a LBRACK | ||||
| 	l := &ast.ListType{ | ||||
| 		Lbrack: p.tok.Pos, | ||||
| 	} | ||||
| 
 | ||||
| 	needComma := false | ||||
| 	for { | ||||
| 		tok := p.scan() | ||||
| 		if needComma { | ||||
| 			switch tok.Type { | ||||
| 			case token.COMMA, token.RBRACK: | ||||
| 			default: | ||||
| 				return nil, &PosError{ | ||||
| 					Pos: tok.Pos, | ||||
| 					Err: fmt.Errorf( | ||||
| 						"error parsing list, expected comma or list end, got: %s", | ||||
| 						tok.Type), | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		switch tok.Type { | ||||
| 		case token.BOOL, token.NUMBER, token.FLOAT, token.STRING, token.HEREDOC: | ||||
| 			node, err := p.literalType() | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 
 | ||||
| 			// If there is a lead comment, apply it | ||||
| 			if p.leadComment != nil { | ||||
| 				node.LeadComment = p.leadComment | ||||
| 				p.leadComment = nil | ||||
| 			} | ||||
| 
 | ||||
| 			l.Add(node) | ||||
| 			needComma = true | ||||
| 		case token.COMMA: | ||||
| 			// get next list item or we are at the end | ||||
| 			// do a look-ahead for line comment | ||||
| 			p.scan() | ||||
| 			if p.lineComment != nil && len(l.List) > 0 { | ||||
| 				lit, ok := l.List[len(l.List)-1].(*ast.LiteralType) | ||||
| 				if ok { | ||||
| 					lit.LineComment = p.lineComment | ||||
| 					l.List[len(l.List)-1] = lit | ||||
| 					p.lineComment = nil | ||||
| 				} | ||||
| 			} | ||||
| 			p.unscan() | ||||
| 
 | ||||
| 			needComma = false | ||||
| 			continue | ||||
| 		case token.LBRACE: | ||||
| 			// Looks like a nested object, so parse it out | ||||
| 			node, err := p.objectType() | ||||
| 			if err != nil { | ||||
| 				return nil, &PosError{ | ||||
| 					Pos: tok.Pos, | ||||
| 					Err: fmt.Errorf( | ||||
| 						"error while trying to parse object within list: %s", err), | ||||
| 				} | ||||
| 			} | ||||
| 			l.Add(node) | ||||
| 			needComma = true | ||||
| 		case token.LBRACK: | ||||
| 			node, err := p.listType() | ||||
| 			if err != nil { | ||||
| 				return nil, &PosError{ | ||||
| 					Pos: tok.Pos, | ||||
| 					Err: fmt.Errorf( | ||||
| 						"error while trying to parse list within list: %s", err), | ||||
| 				} | ||||
| 			} | ||||
| 			l.Add(node) | ||||
| 		case token.RBRACK: | ||||
| 			// finished | ||||
| 			l.Rbrack = p.tok.Pos | ||||
| 			return l, nil | ||||
| 		default: | ||||
| 			return nil, &PosError{ | ||||
| 				Pos: tok.Pos, | ||||
| 				Err: fmt.Errorf("unexpected token while parsing list: %s", tok.Type), | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // literalType parses a literal type and returns a LiteralType AST | ||||
| func (p *Parser) literalType() (*ast.LiteralType, error) { | ||||
| 	defer un(trace(p, "ParseLiteral")) | ||||
| 
 | ||||
| 	return &ast.LiteralType{ | ||||
| 		Token: p.tok, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| // scan returns the next token from the underlying scanner. If a token has | ||||
| // been unscanned then read that instead. In the process, it collects any | ||||
| // comment groups encountered, and remembers the last lead and line comments. | ||||
| func (p *Parser) scan() token.Token { | ||||
| 	// If we have a token on the buffer, then return it. | ||||
| 	if p.n != 0 { | ||||
| 		p.n = 0 | ||||
| 		return p.tok | ||||
| 	} | ||||
| 
 | ||||
| 	// Otherwise read the next token from the scanner and Save it to the buffer | ||||
| 	// in case we unscan later. | ||||
| 	prev := p.tok | ||||
| 	p.tok = p.sc.Scan() | ||||
| 
 | ||||
| 	if p.tok.Type == token.COMMENT { | ||||
| 		var comment *ast.CommentGroup | ||||
| 		var endline int | ||||
| 
 | ||||
| 		// fmt.Printf("p.tok.Pos.Line = %+v prev: %d endline %d \n", | ||||
| 		// p.tok.Pos.Line, prev.Pos.Line, endline) | ||||
| 		if p.tok.Pos.Line == prev.Pos.Line { | ||||
| 			// The comment is on same line as the previous token; it | ||||
| 			// cannot be a lead comment but may be a line comment. | ||||
| 			comment, endline = p.consumeCommentGroup(0) | ||||
| 			if p.tok.Pos.Line != endline { | ||||
| 				// The next token is on a different line, thus | ||||
| 				// the last comment group is a line comment. | ||||
| 				p.lineComment = comment | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// consume successor comments, if any | ||||
| 		endline = -1 | ||||
| 		for p.tok.Type == token.COMMENT { | ||||
| 			comment, endline = p.consumeCommentGroup(1) | ||||
| 		} | ||||
| 
 | ||||
| 		if endline+1 == p.tok.Pos.Line && p.tok.Type != token.RBRACE { | ||||
| 			switch p.tok.Type { | ||||
| 			case token.RBRACE, token.RBRACK: | ||||
| 				// Do not count for these cases | ||||
| 			default: | ||||
| 				// The next token is following on the line immediately after the | ||||
| 				// comment group, thus the last comment group is a lead comment. | ||||
| 				p.leadComment = comment | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	return p.tok | ||||
| } | ||||
| 
 | ||||
| // unscan pushes the previously read token back onto the buffer. | ||||
| func (p *Parser) unscan() { | ||||
| 	p.n = 1 | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Parsing support | ||||
| 
 | ||||
| func (p *Parser) printTrace(a ...interface{}) { | ||||
| 	if !p.enableTrace { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " | ||||
| 	const n = len(dots) | ||||
| 	fmt.Printf("%5d:%3d: ", p.tok.Pos.Line, p.tok.Pos.Column) | ||||
| 
 | ||||
| 	i := 2 * p.indent | ||||
| 	for i > n { | ||||
| 		fmt.Print(dots) | ||||
| 		i -= n | ||||
| 	} | ||||
| 	// i <= n | ||||
| 	fmt.Print(dots[0:i]) | ||||
| 	fmt.Println(a...) | ||||
| } | ||||
| 
 | ||||
| func trace(p *Parser, msg string) *Parser { | ||||
| 	p.printTrace(msg, "(") | ||||
| 	p.indent++ | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| // Usage pattern: defer un(trace(p, "...")) | ||||
| func un(p *Parser) { | ||||
| 	p.indent-- | ||||
| 	p.printTrace(")") | ||||
| } | ||||
							
								
								
									
										789
									
								
								vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										789
									
								
								vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,789 +0,0 @@ | |||
| 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.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()) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		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: | ||||
| 		// File doesn't trace so we add the tracing here | ||||
| 		defer un(trace(p, "File")) | ||||
| 		return p.output(t.Node) | ||||
| 	case *ast.ObjectList: | ||||
| 		defer un(trace(p, "ObjectList")) | ||||
| 
 | ||||
| 		var index int | ||||
| 		for { | ||||
| 			// Determine the location of the next actual non-comment | ||||
| 			// item. If we're at the end, the next item is at "infinity" | ||||
| 			var nextItem token.Pos | ||||
| 			if index != len(t.Items) { | ||||
| 				nextItem = t.Items[index].Pos() | ||||
| 			} else { | ||||
| 				nextItem = token.Pos{Offset: infinity, Line: infinity} | ||||
| 			} | ||||
| 
 | ||||
| 			// Go through the standalone comments in the file and print out | ||||
| 			// the comments that we should be for this object item. | ||||
| 			for _, c := range p.standaloneComments { | ||||
| 				// Go through all the comments in the group. The group | ||||
| 				// should be printed together, not separated by double newlines. | ||||
| 				printed := false | ||||
| 				newlinePrinted := false | ||||
| 				for _, comment := range c.List { | ||||
| 					// We only care about comments after the previous item | ||||
| 					// we've printed so that comments are printed in the | ||||
| 					// correct locations (between two objects for example). | ||||
| 					// And before the next item. | ||||
| 					if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) { | ||||
| 						// if we hit the end add newlines so we can print the comment | ||||
| 						// we don't do this if prev is invalid which means the | ||||
| 						// beginning of the file since the first comment should | ||||
| 						// be at the first line. | ||||
| 						if !newlinePrinted && p.prev.IsValid() && index == len(t.Items) { | ||||
| 							buf.Write([]byte{newline, newline}) | ||||
| 							newlinePrinted = true | ||||
| 						} | ||||
| 
 | ||||
| 						// Write the actual comment. | ||||
| 						buf.WriteString(comment.Text) | ||||
| 						buf.WriteByte(newline) | ||||
| 
 | ||||
| 						// Set printed to true to note that we printed something | ||||
| 						printed = true | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				// If we're not at the last item, write a new line so | ||||
| 				// that there is a newline separating this comment from | ||||
| 				// the next object. | ||||
| 				if printed && index != len(t.Items) { | ||||
| 					buf.WriteByte(newline) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if index == len(t.Items) { | ||||
| 				break | ||||
| 			} | ||||
| 
 | ||||
| 			buf.Write(p.output(t.Items[index])) | ||||
| 			if index != len(t.Items)-1 { | ||||
| 				// Always write a newline to separate us from the next item | ||||
| 				buf.WriteByte(newline) | ||||
| 
 | ||||
| 				// Need to determine if we're going to separate the next item | ||||
| 				// with a blank line. The logic here is simple, though there | ||||
| 				// are a few conditions: | ||||
| 				// | ||||
| 				//   1. The next object is more than one line away anyways, | ||||
| 				//      so we need an empty line. | ||||
| 				// | ||||
| 				//   2. The next object is not a "single line" object, so | ||||
| 				//      we need an empty line. | ||||
| 				// | ||||
| 				//   3. This current object is not a single line object, | ||||
| 				//      so we need an empty line. | ||||
| 				current := t.Items[index] | ||||
| 				next := t.Items[index+1] | ||||
| 				if next.Pos().Line != t.Items[index].Pos().Line+1 || | ||||
| 					!p.isSingleLineObject(next) || | ||||
| 					!p.isSingleLineObject(current) { | ||||
| 					buf.WriteByte(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) | ||||
| 	switch lit.Token.Type { | ||||
| 	case 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) | ||||
| 	case token.STRING: | ||||
| 		// If this is a multiline string, poison lines 2+ so we don't | ||||
| 		// indent them. | ||||
| 		if bytes.IndexRune(result, '\n') >= 0 { | ||||
| 			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) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// If key and val are on different lines, treat line comments like lead comments. | ||||
| 	if o.LineComment != nil && o.Val.Pos().Line != o.Keys[0].Pos().Line { | ||||
| 		for _, comment := range o.LineComment.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.LineComment != nil && o.Val.Pos().Line == o.Keys[0].Pos().Line { | ||||
| 		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 { | ||||
| 		// Determine the location of the next actual non-comment | ||||
| 		// item. If we're at the end, the next item is the closing brace | ||||
| 		if index != len(o.List.Items) { | ||||
| 			nextItem = o.List.Items[index].Pos() | ||||
| 		} else { | ||||
| 			nextItem = o.Rbrace | ||||
| 		} | ||||
| 
 | ||||
| 		// Go through the standalone comments in the file and print out | ||||
| 		// the comments that we should be for this object item. | ||||
| 		for _, c := range p.standaloneComments { | ||||
| 			printed := false | ||||
| 			var lastCommentPos token.Pos | ||||
| 			for _, comment := range c.List { | ||||
| 				// We only care about comments after the previous item | ||||
| 				// we've printed so that comments are printed in the | ||||
| 				// correct locations (between two objects for example). | ||||
| 				// And before the next item. | ||||
| 				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) | ||||
| 					} | ||||
| 
 | ||||
| 					// Store this position | ||||
| 					lastCommentPos = comment.Pos() | ||||
| 
 | ||||
| 					// output the comment itself | ||||
| 					buf.Write(p.indent(p.heredocIndent([]byte(comment.Text)))) | ||||
| 
 | ||||
| 					// Set printed to true to note that we printed something | ||||
| 					printed = true | ||||
| 
 | ||||
| 					/* | ||||
| 						if index != len(o.List.Items) { | ||||
| 							buf.WriteByte(newline) // do not print on the end | ||||
| 						} | ||||
| 					*/ | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// Stuff to do if we had comments | ||||
| 			if printed { | ||||
| 				// Always write a newline | ||||
| 				buf.WriteByte(newline) | ||||
| 
 | ||||
| 				// If there is another item in the object and our comment | ||||
| 				// didn't hug it directly, then make sure there is a blank | ||||
| 				// line separating them. | ||||
| 				if nextItem != o.Rbrace && nextItem.Line != lastCommentPos.Line+1 { | ||||
| 					buf.WriteByte(newline) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		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 { | ||||
| 	if p.isSingleLineList(l) { | ||||
| 		return p.singleLineList(l) | ||||
| 	} | ||||
| 
 | ||||
| 	var buf bytes.Buffer | ||||
| 	buf.WriteString("[") | ||||
| 	buf.WriteByte(newline) | ||||
| 
 | ||||
| 	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 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	haveEmptyLine := false | ||||
| 	for i, item := range l.List { | ||||
| 		// If we have a lead comment, then we want to write that first | ||||
| 		leadComment := false | ||||
| 		if lit, ok := item.(*ast.LiteralType); ok && lit.LeadComment != nil { | ||||
| 			leadComment = true | ||||
| 
 | ||||
| 			// Ensure an empty line before every element with a | ||||
| 			// lead comment (except the first item in a list). | ||||
| 			if !haveEmptyLine && i != 0 { | ||||
| 				buf.WriteByte(newline) | ||||
| 			} | ||||
| 
 | ||||
| 			for _, comment := range lit.LeadComment.List { | ||||
| 				buf.Write(p.indent([]byte(comment.Text))) | ||||
| 				buf.WriteByte(newline) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// also indent each line | ||||
| 		val := p.output(item) | ||||
| 		curLen := len(val) | ||||
| 		buf.Write(p.indent(val)) | ||||
| 
 | ||||
| 		// if this item is a heredoc, then we output the comma on | ||||
| 		// the next line. This is the only case this happens. | ||||
| 		comma := []byte{','} | ||||
| 		if lit, ok := item.(*ast.LiteralType); ok && lit.Token.Type == token.HEREDOC { | ||||
| 			buf.WriteByte(newline) | ||||
| 			comma = p.indent(comma) | ||||
| 		} | ||||
| 
 | ||||
| 		buf.Write(comma) | ||||
| 
 | ||||
| 		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) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		buf.WriteByte(newline) | ||||
| 
 | ||||
| 		// Ensure an empty line after every element with a | ||||
| 		// lead comment (except the first item in a list). | ||||
| 		haveEmptyLine = leadComment && i != len(l.List)-1 | ||||
| 		if haveEmptyLine { | ||||
| 			buf.WriteByte(newline) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	buf.WriteString("]") | ||||
| 	return buf.Bytes() | ||||
| } | ||||
| 
 | ||||
| // isSingleLineList returns true if: | ||||
| // * they were previously formatted entirely on one line | ||||
| // * they consist entirely of literals | ||||
| // * there are either no heredoc strings or the list has exactly one element | ||||
| // * there are no line comments | ||||
| func (printer) isSingleLineList(l *ast.ListType) bool { | ||||
| 	for _, item := range l.List { | ||||
| 		if item.Pos().Line != l.Lbrack.Line { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		lit, ok := item.(*ast.LiteralType) | ||||
| 		if !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		if lit.Token.Type == token.HEREDOC && len(l.List) != 1 { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		if lit.LineComment != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // singleLineList prints a simple single line list. | ||||
| // For a definition of "simple", see isSingleLineList above. | ||||
| func (p *printer) singleLineList(l *ast.ListType) []byte { | ||||
| 	buf := &bytes.Buffer{} | ||||
| 
 | ||||
| 	buf.WriteString("[") | ||||
| 	for i, item := range l.List { | ||||
| 		if i != 0 { | ||||
| 			buf.WriteString(", ") | ||||
| 		} | ||||
| 
 | ||||
| 		// Output the item itself | ||||
| 		buf.Write(p.output(item)) | ||||
| 
 | ||||
| 		// The heredoc marker needs to be at the end of line. | ||||
| 		if lit, ok := item.(*ast.LiteralType); ok && lit.Token.Type == token.HEREDOC { | ||||
| 			buf.WriteByte(newline) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	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 | ||||
| } | ||||
| 
 | ||||
| // isSingleLineObject tells whether the given object item is a single | ||||
| // line object such as "obj {}". | ||||
| // | ||||
| // A single line object: | ||||
| // | ||||
| //   * has no lead comments (hence multi-line) | ||||
| //   * has no assignment | ||||
| //   * has no values in the stanza (within {}) | ||||
| // | ||||
| func (p *printer) isSingleLineObject(val *ast.ObjectItem) bool { | ||||
| 	// If there is a lead comment, can't be one line | ||||
| 	if val.LeadComment != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// If there is assignment, we always break by line | ||||
| 	if val.Assign.IsValid() { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// If it isn't an object type, then its not a single line object | ||||
| 	ot, ok := val.Val.(*ast.ObjectType) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// If the object has no items, it is single line! | ||||
| 	return len(ot.List.Items) == 0 | ||||
| } | ||||
| 
 | ||||
| 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(")") | ||||
| } | ||||
							
								
								
									
										66
									
								
								vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										66
									
								
								vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,66 +0,0 @@ | |||
| // 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 | ||||
| } | ||||
							
								
								
									
										652
									
								
								vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										652
									
								
								vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,652 +0,0 @@ | |||
| // Package scanner implements a scanner for HCL (HashiCorp Configuration | ||||
| // Language) source text. | ||||
| package scanner | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"regexp" | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/token" | ||||
| ) | ||||
| 
 | ||||
| // eof represents a marker rune for the end of the reader. | ||||
| const eof = rune(0) | ||||
| 
 | ||||
| // Scanner defines a lexical scanner | ||||
| type Scanner struct { | ||||
| 	buf *bytes.Buffer // Source buffer for advancing and scanning | ||||
| 	src []byte        // Source buffer for immutable access | ||||
| 
 | ||||
| 	// Source Position | ||||
| 	srcPos  token.Pos // current position | ||||
| 	prevPos token.Pos // previous position, used for peek() method | ||||
| 
 | ||||
| 	lastCharLen int // length of last character in bytes | ||||
| 	lastLineLen int // length of last line in characters (for correct column reporting) | ||||
| 
 | ||||
| 	tokStart int // token text start position | ||||
| 	tokEnd   int // token text end  position | ||||
| 
 | ||||
| 	// Error is called for each error encountered. If no Error | ||||
| 	// function is set, the error is reported to os.Stderr. | ||||
| 	Error func(pos token.Pos, msg string) | ||||
| 
 | ||||
| 	// ErrorCount is incremented by one for each error encountered. | ||||
| 	ErrorCount int | ||||
| 
 | ||||
| 	// tokPos is the start position of most recently scanned token; set by | ||||
| 	// Scan. The Filename field is always left untouched by the Scanner.  If | ||||
| 	// an error is reported (via Error) and Position is invalid, the scanner is | ||||
| 	// not inside a token. | ||||
| 	tokPos token.Pos | ||||
| } | ||||
| 
 | ||||
| // New creates and initializes a new instance of Scanner using src as | ||||
| // its source content. | ||||
| func New(src []byte) *Scanner { | ||||
| 	// even though we accept a src, we read from a io.Reader compatible type | ||||
| 	// (*bytes.Buffer). So in the future we might easily change it to streaming | ||||
| 	// read. | ||||
| 	b := bytes.NewBuffer(src) | ||||
| 	s := &Scanner{ | ||||
| 		buf: b, | ||||
| 		src: src, | ||||
| 	} | ||||
| 
 | ||||
| 	// srcPosition always starts with 1 | ||||
| 	s.srcPos.Line = 1 | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // next reads the next rune from the bufferred reader. Returns the rune(0) if | ||||
| // an error occurs (or io.EOF is returned). | ||||
| func (s *Scanner) next() rune { | ||||
| 	ch, size, err := s.buf.ReadRune() | ||||
| 	if err != nil { | ||||
| 		// advance for error reporting | ||||
| 		s.srcPos.Column++ | ||||
| 		s.srcPos.Offset += size | ||||
| 		s.lastCharLen = size | ||||
| 		return eof | ||||
| 	} | ||||
| 
 | ||||
| 	// remember last position | ||||
| 	s.prevPos = s.srcPos | ||||
| 
 | ||||
| 	s.srcPos.Column++ | ||||
| 	s.lastCharLen = size | ||||
| 	s.srcPos.Offset += size | ||||
| 
 | ||||
| 	if ch == utf8.RuneError && size == 1 { | ||||
| 		s.err("illegal UTF-8 encoding") | ||||
| 		return ch | ||||
| 	} | ||||
| 
 | ||||
| 	if ch == '\n' { | ||||
| 		s.srcPos.Line++ | ||||
| 		s.lastLineLen = s.srcPos.Column | ||||
| 		s.srcPos.Column = 0 | ||||
| 	} | ||||
| 
 | ||||
| 	if ch == '\x00' { | ||||
| 		s.err("unexpected null character (0x00)") | ||||
| 		return eof | ||||
| 	} | ||||
| 
 | ||||
| 	if ch == '\uE123' { | ||||
| 		s.err("unicode code point U+E123 reserved for internal use") | ||||
| 		return utf8.RuneError | ||||
| 	} | ||||
| 
 | ||||
| 	// debug | ||||
| 	// fmt.Printf("ch: %q, offset:column: %d:%d\n", ch, s.srcPos.Offset, s.srcPos.Column) | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // unread unreads the previous read Rune and updates the source position | ||||
| func (s *Scanner) unread() { | ||||
| 	if err := s.buf.UnreadRune(); err != nil { | ||||
| 		panic(err) // this is user fault, we should catch it | ||||
| 	} | ||||
| 	s.srcPos = s.prevPos // put back last position | ||||
| } | ||||
| 
 | ||||
| // peek returns the next rune without advancing the reader. | ||||
| func (s *Scanner) peek() rune { | ||||
| 	peek, _, err := s.buf.ReadRune() | ||||
| 	if err != nil { | ||||
| 		return eof | ||||
| 	} | ||||
| 
 | ||||
| 	s.buf.UnreadRune() | ||||
| 	return peek | ||||
| } | ||||
| 
 | ||||
| // Scan scans the next token and returns the token. | ||||
| func (s *Scanner) Scan() token.Token { | ||||
| 	ch := s.next() | ||||
| 
 | ||||
| 	// skip white space | ||||
| 	for isWhitespace(ch) { | ||||
| 		ch = s.next() | ||||
| 	} | ||||
| 
 | ||||
| 	var tok token.Type | ||||
| 
 | ||||
| 	// token text markings | ||||
| 	s.tokStart = s.srcPos.Offset - s.lastCharLen | ||||
| 
 | ||||
| 	// token position, initial next() is moving the offset by one(size of rune | ||||
| 	// actually), though we are interested with the starting point | ||||
| 	s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen | ||||
| 	if s.srcPos.Column > 0 { | ||||
| 		// common case: last character was not a '\n' | ||||
| 		s.tokPos.Line = s.srcPos.Line | ||||
| 		s.tokPos.Column = s.srcPos.Column | ||||
| 	} else { | ||||
| 		// last character was a '\n' | ||||
| 		// (we cannot be at the beginning of the source | ||||
| 		// since we have called next() at least once) | ||||
| 		s.tokPos.Line = s.srcPos.Line - 1 | ||||
| 		s.tokPos.Column = s.lastLineLen | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case isLetter(ch): | ||||
| 		tok = token.IDENT | ||||
| 		lit := s.scanIdentifier() | ||||
| 		if lit == "true" || lit == "false" { | ||||
| 			tok = token.BOOL | ||||
| 		} | ||||
| 	case isDecimal(ch): | ||||
| 		tok = s.scanNumber(ch) | ||||
| 	default: | ||||
| 		switch ch { | ||||
| 		case eof: | ||||
| 			tok = token.EOF | ||||
| 		case '"': | ||||
| 			tok = token.STRING | ||||
| 			s.scanString() | ||||
| 		case '#', '/': | ||||
| 			tok = token.COMMENT | ||||
| 			s.scanComment(ch) | ||||
| 		case '.': | ||||
| 			tok = token.PERIOD | ||||
| 			ch = s.peek() | ||||
| 			if isDecimal(ch) { | ||||
| 				tok = token.FLOAT | ||||
| 				ch = s.scanMantissa(ch) | ||||
| 				ch = s.scanExponent(ch) | ||||
| 			} | ||||
| 		case '<': | ||||
| 			tok = token.HEREDOC | ||||
| 			s.scanHeredoc() | ||||
| 		case '[': | ||||
| 			tok = token.LBRACK | ||||
| 		case ']': | ||||
| 			tok = token.RBRACK | ||||
| 		case '{': | ||||
| 			tok = token.LBRACE | ||||
| 		case '}': | ||||
| 			tok = token.RBRACE | ||||
| 		case ',': | ||||
| 			tok = token.COMMA | ||||
| 		case '=': | ||||
| 			tok = token.ASSIGN | ||||
| 		case '+': | ||||
| 			tok = token.ADD | ||||
| 		case '-': | ||||
| 			if isDecimal(s.peek()) { | ||||
| 				ch := s.next() | ||||
| 				tok = s.scanNumber(ch) | ||||
| 			} else { | ||||
| 				tok = token.SUB | ||||
| 			} | ||||
| 		default: | ||||
| 			s.err("illegal char") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// finish token ending | ||||
| 	s.tokEnd = s.srcPos.Offset | ||||
| 
 | ||||
| 	// create token literal | ||||
| 	var tokenText string | ||||
| 	if s.tokStart >= 0 { | ||||
| 		tokenText = string(s.src[s.tokStart:s.tokEnd]) | ||||
| 	} | ||||
| 	s.tokStart = s.tokEnd // ensure idempotency of tokenText() call | ||||
| 
 | ||||
| 	return token.Token{ | ||||
| 		Type: tok, | ||||
| 		Pos:  s.tokPos, | ||||
| 		Text: tokenText, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (s *Scanner) scanComment(ch rune) { | ||||
| 	// single line comments | ||||
| 	if ch == '#' || (ch == '/' && s.peek() != '*') { | ||||
| 		if ch == '/' && s.peek() != '/' { | ||||
| 			s.err("expected '/' for comment") | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		ch = s.next() | ||||
| 		for ch != '\n' && ch >= 0 && ch != eof { | ||||
| 			ch = s.next() | ||||
| 		} | ||||
| 		if ch != eof && ch >= 0 { | ||||
| 			s.unread() | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// be sure we get the character after /* This allows us to find comment's | ||||
| 	// that are not erminated | ||||
| 	if ch == '/' { | ||||
| 		s.next() | ||||
| 		ch = s.next() // read character after "/*" | ||||
| 	} | ||||
| 
 | ||||
| 	// look for /* - style comments | ||||
| 	for { | ||||
| 		if ch < 0 || ch == eof { | ||||
| 			s.err("comment not terminated") | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		ch0 := ch | ||||
| 		ch = s.next() | ||||
| 		if ch0 == '*' && ch == '/' { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // scanNumber scans a HCL number definition starting with the given rune | ||||
| func (s *Scanner) scanNumber(ch rune) token.Type { | ||||
| 	if ch == '0' { | ||||
| 		// check for hexadecimal, octal or float | ||||
| 		ch = s.next() | ||||
| 		if ch == 'x' || ch == 'X' { | ||||
| 			// hexadecimal | ||||
| 			ch = s.next() | ||||
| 			found := false | ||||
| 			for isHexadecimal(ch) { | ||||
| 				ch = s.next() | ||||
| 				found = true | ||||
| 			} | ||||
| 
 | ||||
| 			if !found { | ||||
| 				s.err("illegal hexadecimal number") | ||||
| 			} | ||||
| 
 | ||||
| 			if ch != eof { | ||||
| 				s.unread() | ||||
| 			} | ||||
| 
 | ||||
| 			return token.NUMBER | ||||
| 		} | ||||
| 
 | ||||
| 		// now it's either something like: 0421(octal) or 0.1231(float) | ||||
| 		illegalOctal := false | ||||
| 		for isDecimal(ch) { | ||||
| 			ch = s.next() | ||||
| 			if ch == '8' || ch == '9' { | ||||
| 				// this is just a possibility. For example 0159 is illegal, but | ||||
| 				// 0159.23 is valid. So we mark a possible illegal octal. If | ||||
| 				// the next character is not a period, we'll print the error. | ||||
| 				illegalOctal = true | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == 'e' || ch == 'E' { | ||||
| 			ch = s.scanExponent(ch) | ||||
| 			return token.FLOAT | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == '.' { | ||||
| 			ch = s.scanFraction(ch) | ||||
| 
 | ||||
| 			if ch == 'e' || ch == 'E' { | ||||
| 				ch = s.next() | ||||
| 				ch = s.scanExponent(ch) | ||||
| 			} | ||||
| 			return token.FLOAT | ||||
| 		} | ||||
| 
 | ||||
| 		if illegalOctal { | ||||
| 			s.err("illegal octal number") | ||||
| 		} | ||||
| 
 | ||||
| 		if ch != eof { | ||||
| 			s.unread() | ||||
| 		} | ||||
| 		return token.NUMBER | ||||
| 	} | ||||
| 
 | ||||
| 	s.scanMantissa(ch) | ||||
| 	ch = s.next() // seek forward | ||||
| 	if ch == 'e' || ch == 'E' { | ||||
| 		ch = s.scanExponent(ch) | ||||
| 		return token.FLOAT | ||||
| 	} | ||||
| 
 | ||||
| 	if ch == '.' { | ||||
| 		ch = s.scanFraction(ch) | ||||
| 		if ch == 'e' || ch == 'E' { | ||||
| 			ch = s.next() | ||||
| 			ch = s.scanExponent(ch) | ||||
| 		} | ||||
| 		return token.FLOAT | ||||
| 	} | ||||
| 
 | ||||
| 	if ch != eof { | ||||
| 		s.unread() | ||||
| 	} | ||||
| 	return token.NUMBER | ||||
| } | ||||
| 
 | ||||
| // scanMantissa scans the mantissa beginning from the rune. It returns the next | ||||
| // non decimal rune. It's used to determine wheter it's a fraction or exponent. | ||||
| func (s *Scanner) scanMantissa(ch rune) rune { | ||||
| 	scanned := false | ||||
| 	for isDecimal(ch) { | ||||
| 		ch = s.next() | ||||
| 		scanned = true | ||||
| 	} | ||||
| 
 | ||||
| 	if scanned && ch != eof { | ||||
| 		s.unread() | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanFraction scans the fraction after the '.' rune | ||||
| func (s *Scanner) scanFraction(ch rune) rune { | ||||
| 	if ch == '.' { | ||||
| 		ch = s.peek() // we peek just to see if we can move forward | ||||
| 		ch = s.scanMantissa(ch) | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanExponent scans the remaining parts of an exponent after the 'e' or 'E' | ||||
| // rune. | ||||
| func (s *Scanner) scanExponent(ch rune) rune { | ||||
| 	if ch == 'e' || ch == 'E' { | ||||
| 		ch = s.next() | ||||
| 		if ch == '-' || ch == '+' { | ||||
| 			ch = s.next() | ||||
| 		} | ||||
| 		ch = s.scanMantissa(ch) | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanHeredoc scans a heredoc string | ||||
| func (s *Scanner) scanHeredoc() { | ||||
| 	// Scan the second '<' in example: '<<EOF' | ||||
| 	if s.next() != '<' { | ||||
| 		s.err("heredoc expected second '<', didn't see it") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the original offset so we can read just the heredoc ident | ||||
| 	offs := s.srcPos.Offset | ||||
| 
 | ||||
| 	// Scan the identifier | ||||
| 	ch := s.next() | ||||
| 
 | ||||
| 	// Indented heredoc syntax | ||||
| 	if ch == '-' { | ||||
| 		ch = s.next() | ||||
| 	} | ||||
| 
 | ||||
| 	for isLetter(ch) || isDigit(ch) { | ||||
| 		ch = s.next() | ||||
| 	} | ||||
| 
 | ||||
| 	// If we reached an EOF then that is not good | ||||
| 	if ch == eof { | ||||
| 		s.err("heredoc not terminated") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Ignore the '\r' in Windows line endings | ||||
| 	if ch == '\r' { | ||||
| 		if s.peek() == '\n' { | ||||
| 			ch = s.next() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// If we didn't reach a newline then that is also not good | ||||
| 	if ch != '\n' { | ||||
| 		s.err("invalid characters in heredoc anchor") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Read the identifier | ||||
| 	identBytes := s.src[offs : s.srcPos.Offset-s.lastCharLen] | ||||
| 	if len(identBytes) == 0 || (len(identBytes) == 1 && identBytes[0] == '-') { | ||||
| 		s.err("zero-length heredoc anchor") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	var identRegexp *regexp.Regexp | ||||
| 	if identBytes[0] == '-' { | ||||
| 		identRegexp = regexp.MustCompile(fmt.Sprintf(`^[[:space:]]*%s\r*\z`, identBytes[1:])) | ||||
| 	} else { | ||||
| 		identRegexp = regexp.MustCompile(fmt.Sprintf(`^[[:space:]]*%s\r*\z`, identBytes)) | ||||
| 	} | ||||
| 
 | ||||
| 	// Read the actual string value | ||||
| 	lineStart := s.srcPos.Offset | ||||
| 	for { | ||||
| 		ch := s.next() | ||||
| 
 | ||||
| 		// Special newline handling. | ||||
| 		if ch == '\n' { | ||||
| 			// Math is fast, so we first compare the byte counts to see if we have a chance | ||||
| 			// of seeing the same identifier - if the length is less than the number of bytes | ||||
| 			// in the identifier, this cannot be a valid terminator. | ||||
| 			lineBytesLen := s.srcPos.Offset - s.lastCharLen - lineStart | ||||
| 			if lineBytesLen >= len(identBytes) && identRegexp.Match(s.src[lineStart:s.srcPos.Offset-s.lastCharLen]) { | ||||
| 				break | ||||
| 			} | ||||
| 
 | ||||
| 			// Not an anchor match, record the start of a new line | ||||
| 			lineStart = s.srcPos.Offset | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == eof { | ||||
| 			s.err("heredoc not terminated") | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // scanString scans a quoted string | ||||
| func (s *Scanner) scanString() { | ||||
| 	braces := 0 | ||||
| 	for { | ||||
| 		// '"' opening already consumed | ||||
| 		// read character after quote | ||||
| 		ch := s.next() | ||||
| 
 | ||||
| 		if (ch == '\n' && braces == 0) || ch < 0 || ch == eof { | ||||
| 			s.err("literal not terminated") | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == '"' && braces == 0 { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		// If we're going into a ${} then we can ignore quotes for awhile | ||||
| 		if braces == 0 && ch == '$' && s.peek() == '{' { | ||||
| 			braces++ | ||||
| 			s.next() | ||||
| 		} else if braces > 0 && ch == '{' { | ||||
| 			braces++ | ||||
| 		} | ||||
| 		if braces > 0 && ch == '}' { | ||||
| 			braces-- | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == '\\' { | ||||
| 			s.scanEscape() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // scanEscape scans an escape sequence | ||||
| func (s *Scanner) scanEscape() rune { | ||||
| 	// http://en.cppreference.com/w/cpp/language/escape | ||||
| 	ch := s.next() // read character after '/' | ||||
| 	switch ch { | ||||
| 	case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"': | ||||
| 		// nothing to do | ||||
| 	case '0', '1', '2', '3', '4', '5', '6', '7': | ||||
| 		// octal notation | ||||
| 		ch = s.scanDigits(ch, 8, 3) | ||||
| 	case 'x': | ||||
| 		// hexademical notation | ||||
| 		ch = s.scanDigits(s.next(), 16, 2) | ||||
| 	case 'u': | ||||
| 		// universal character name | ||||
| 		ch = s.scanDigits(s.next(), 16, 4) | ||||
| 	case 'U': | ||||
| 		// universal character name | ||||
| 		ch = s.scanDigits(s.next(), 16, 8) | ||||
| 	default: | ||||
| 		s.err("illegal char escape") | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanDigits scans a rune with the given base for n times. For example an | ||||
| // octal notation \184 would yield in scanDigits(ch, 8, 3) | ||||
| func (s *Scanner) scanDigits(ch rune, base, n int) rune { | ||||
| 	start := n | ||||
| 	for n > 0 && digitVal(ch) < base { | ||||
| 		ch = s.next() | ||||
| 		if ch == eof { | ||||
| 			// If we see an EOF, we halt any more scanning of digits | ||||
| 			// immediately. | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		n-- | ||||
| 	} | ||||
| 	if n > 0 { | ||||
| 		s.err("illegal char escape") | ||||
| 	} | ||||
| 
 | ||||
| 	if n != start && ch != eof { | ||||
| 		// we scanned all digits, put the last non digit char back, | ||||
| 		// only if we read anything at all | ||||
| 		s.unread() | ||||
| 	} | ||||
| 
 | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanIdentifier scans an identifier and returns the literal string | ||||
| func (s *Scanner) scanIdentifier() string { | ||||
| 	offs := s.srcPos.Offset - s.lastCharLen | ||||
| 	ch := s.next() | ||||
| 	for isLetter(ch) || isDigit(ch) || ch == '-' || ch == '.' { | ||||
| 		ch = s.next() | ||||
| 	} | ||||
| 
 | ||||
| 	if ch != eof { | ||||
| 		s.unread() // we got identifier, put back latest char | ||||
| 	} | ||||
| 
 | ||||
| 	return string(s.src[offs:s.srcPos.Offset]) | ||||
| } | ||||
| 
 | ||||
| // recentPosition returns the position of the character immediately after the | ||||
| // character or token returned by the last call to Scan. | ||||
| func (s *Scanner) recentPosition() (pos token.Pos) { | ||||
| 	pos.Offset = s.srcPos.Offset - s.lastCharLen | ||||
| 	switch { | ||||
| 	case s.srcPos.Column > 0: | ||||
| 		// common case: last character was not a '\n' | ||||
| 		pos.Line = s.srcPos.Line | ||||
| 		pos.Column = s.srcPos.Column | ||||
| 	case s.lastLineLen > 0: | ||||
| 		// last character was a '\n' | ||||
| 		// (we cannot be at the beginning of the source | ||||
| 		// since we have called next() at least once) | ||||
| 		pos.Line = s.srcPos.Line - 1 | ||||
| 		pos.Column = s.lastLineLen | ||||
| 	default: | ||||
| 		// at the beginning of the source | ||||
| 		pos.Line = 1 | ||||
| 		pos.Column = 1 | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // err prints the error of any scanning to s.Error function. If the function is | ||||
| // not defined, by default it prints them to os.Stderr | ||||
| func (s *Scanner) err(msg string) { | ||||
| 	s.ErrorCount++ | ||||
| 	pos := s.recentPosition() | ||||
| 
 | ||||
| 	if s.Error != nil { | ||||
| 		s.Error(pos, msg) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg) | ||||
| } | ||||
| 
 | ||||
| // isHexadecimal returns true if the given rune is a letter | ||||
| func isLetter(ch rune) bool { | ||||
| 	return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) | ||||
| } | ||||
| 
 | ||||
| // isDigit returns true if the given rune is a decimal digit | ||||
| func isDigit(ch rune) bool { | ||||
| 	return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) | ||||
| } | ||||
| 
 | ||||
| // isDecimal returns true if the given rune is a decimal number | ||||
| func isDecimal(ch rune) bool { | ||||
| 	return '0' <= ch && ch <= '9' | ||||
| } | ||||
| 
 | ||||
| // isHexadecimal returns true if the given rune is an hexadecimal number | ||||
| func isHexadecimal(ch rune) bool { | ||||
| 	return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F' | ||||
| } | ||||
| 
 | ||||
| // isWhitespace returns true if the rune is a space, tab, newline or carriage return | ||||
| func isWhitespace(ch rune) bool { | ||||
| 	return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' | ||||
| } | ||||
| 
 | ||||
| // digitVal returns the integer value of a given octal,decimal or hexadecimal rune | ||||
| func digitVal(ch rune) int { | ||||
| 	switch { | ||||
| 	case '0' <= ch && ch <= '9': | ||||
| 		return int(ch - '0') | ||||
| 	case 'a' <= ch && ch <= 'f': | ||||
| 		return int(ch - 'a' + 10) | ||||
| 	case 'A' <= ch && ch <= 'F': | ||||
| 		return int(ch - 'A' + 10) | ||||
| 	} | ||||
| 	return 16 // larger than any legal digit val | ||||
| } | ||||
							
								
								
									
										241
									
								
								vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										241
									
								
								vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,241 +0,0 @@ | |||
| package strconv | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
| 
 | ||||
| // ErrSyntax indicates that a value does not have the right syntax for the target type. | ||||
| var ErrSyntax = errors.New("invalid syntax") | ||||
| 
 | ||||
| // Unquote interprets s as a single-quoted, double-quoted, | ||||
| // or backquoted Go string literal, returning the string value | ||||
| // that s quotes.  (If s is single-quoted, it would be a Go | ||||
| // character literal; Unquote returns the corresponding | ||||
| // one-character string.) | ||||
| func Unquote(s string) (t string, err error) { | ||||
| 	n := len(s) | ||||
| 	if n < 2 { | ||||
| 		return "", ErrSyntax | ||||
| 	} | ||||
| 	quote := s[0] | ||||
| 	if quote != s[n-1] { | ||||
| 		return "", ErrSyntax | ||||
| 	} | ||||
| 	s = s[1 : n-1] | ||||
| 
 | ||||
| 	if quote != '"' { | ||||
| 		return "", ErrSyntax | ||||
| 	} | ||||
| 	if !contains(s, '$') && !contains(s, '{') && contains(s, '\n') { | ||||
| 		return "", ErrSyntax | ||||
| 	} | ||||
| 
 | ||||
| 	// Is it trivial?  Avoid allocation. | ||||
| 	if !contains(s, '\\') && !contains(s, quote) && !contains(s, '$') { | ||||
| 		switch quote { | ||||
| 		case '"': | ||||
| 			return s, nil | ||||
| 		case '\'': | ||||
| 			r, size := utf8.DecodeRuneInString(s) | ||||
| 			if size == len(s) && (r != utf8.RuneError || size != 1) { | ||||
| 				return s, nil | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var runeTmp [utf8.UTFMax]byte | ||||
| 	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations. | ||||
| 	for len(s) > 0 { | ||||
| 		// If we're starting a '${}' then let it through un-unquoted. | ||||
| 		// Specifically: we don't unquote any characters within the `${}` | ||||
| 		// section. | ||||
| 		if s[0] == '$' && len(s) > 1 && s[1] == '{' { | ||||
| 			buf = append(buf, '$', '{') | ||||
| 			s = s[2:] | ||||
| 
 | ||||
| 			// Continue reading until we find the closing brace, copying as-is | ||||
| 			braces := 1 | ||||
| 			for len(s) > 0 && braces > 0 { | ||||
| 				r, size := utf8.DecodeRuneInString(s) | ||||
| 				if r == utf8.RuneError { | ||||
| 					return "", ErrSyntax | ||||
| 				} | ||||
| 
 | ||||
| 				s = s[size:] | ||||
| 
 | ||||
| 				n := utf8.EncodeRune(runeTmp[:], r) | ||||
| 				buf = append(buf, runeTmp[:n]...) | ||||
| 
 | ||||
| 				switch r { | ||||
| 				case '{': | ||||
| 					braces++ | ||||
| 				case '}': | ||||
| 					braces-- | ||||
| 				} | ||||
| 			} | ||||
| 			if braces != 0 { | ||||
| 				return "", ErrSyntax | ||||
| 			} | ||||
| 			if len(s) == 0 { | ||||
| 				// If there's no string left, we're done! | ||||
| 				break | ||||
| 			} else { | ||||
| 				// If there's more left, we need to pop back up to the top of the loop | ||||
| 				// in case there's another interpolation in this string. | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if s[0] == '\n' { | ||||
| 			return "", ErrSyntax | ||||
| 		} | ||||
| 
 | ||||
| 		c, multibyte, ss, err := unquoteChar(s, quote) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		s = ss | ||||
| 		if c < utf8.RuneSelf || !multibyte { | ||||
| 			buf = append(buf, byte(c)) | ||||
| 		} else { | ||||
| 			n := utf8.EncodeRune(runeTmp[:], c) | ||||
| 			buf = append(buf, runeTmp[:n]...) | ||||
| 		} | ||||
| 		if quote == '\'' && len(s) != 0 { | ||||
| 			// single-quoted must be single character | ||||
| 			return "", ErrSyntax | ||||
| 		} | ||||
| 	} | ||||
| 	return string(buf), nil | ||||
| } | ||||
| 
 | ||||
| // contains reports whether the string contains the byte c. | ||||
| func contains(s string, c byte) bool { | ||||
| 	for i := 0; i < len(s); i++ { | ||||
| 		if s[i] == c { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func unhex(b byte) (v rune, ok bool) { | ||||
| 	c := rune(b) | ||||
| 	switch { | ||||
| 	case '0' <= c && c <= '9': | ||||
| 		return c - '0', true | ||||
| 	case 'a' <= c && c <= 'f': | ||||
| 		return c - 'a' + 10, true | ||||
| 	case 'A' <= c && c <= 'F': | ||||
| 		return c - 'A' + 10, true | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func unquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) { | ||||
| 	// easy cases | ||||
| 	switch c := s[0]; { | ||||
| 	case c == quote && (quote == '\'' || quote == '"'): | ||||
| 		err = ErrSyntax | ||||
| 		return | ||||
| 	case c >= utf8.RuneSelf: | ||||
| 		r, size := utf8.DecodeRuneInString(s) | ||||
| 		return r, true, s[size:], nil | ||||
| 	case c != '\\': | ||||
| 		return rune(s[0]), false, s[1:], nil | ||||
| 	} | ||||
| 
 | ||||
| 	// hard case: c is backslash | ||||
| 	if len(s) <= 1 { | ||||
| 		err = ErrSyntax | ||||
| 		return | ||||
| 	} | ||||
| 	c := s[1] | ||||
| 	s = s[2:] | ||||
| 
 | ||||
| 	switch c { | ||||
| 	case 'a': | ||||
| 		value = '\a' | ||||
| 	case 'b': | ||||
| 		value = '\b' | ||||
| 	case 'f': | ||||
| 		value = '\f' | ||||
| 	case 'n': | ||||
| 		value = '\n' | ||||
| 	case 'r': | ||||
| 		value = '\r' | ||||
| 	case 't': | ||||
| 		value = '\t' | ||||
| 	case 'v': | ||||
| 		value = '\v' | ||||
| 	case 'x', 'u', 'U': | ||||
| 		n := 0 | ||||
| 		switch c { | ||||
| 		case 'x': | ||||
| 			n = 2 | ||||
| 		case 'u': | ||||
| 			n = 4 | ||||
| 		case 'U': | ||||
| 			n = 8 | ||||
| 		} | ||||
| 		var v rune | ||||
| 		if len(s) < n { | ||||
| 			err = ErrSyntax | ||||
| 			return | ||||
| 		} | ||||
| 		for j := 0; j < n; j++ { | ||||
| 			x, ok := unhex(s[j]) | ||||
| 			if !ok { | ||||
| 				err = ErrSyntax | ||||
| 				return | ||||
| 			} | ||||
| 			v = v<<4 | x | ||||
| 		} | ||||
| 		s = s[n:] | ||||
| 		if c == 'x' { | ||||
| 			// single-byte string, possibly not UTF-8 | ||||
| 			value = v | ||||
| 			break | ||||
| 		} | ||||
| 		if v > utf8.MaxRune { | ||||
| 			err = ErrSyntax | ||||
| 			return | ||||
| 		} | ||||
| 		value = v | ||||
| 		multibyte = true | ||||
| 	case '0', '1', '2', '3', '4', '5', '6', '7': | ||||
| 		v := rune(c) - '0' | ||||
| 		if len(s) < 2 { | ||||
| 			err = ErrSyntax | ||||
| 			return | ||||
| 		} | ||||
| 		for j := 0; j < 2; j++ { // one digit already; two more | ||||
| 			x := rune(s[j]) - '0' | ||||
| 			if x < 0 || x > 7 { | ||||
| 				err = ErrSyntax | ||||
| 				return | ||||
| 			} | ||||
| 			v = (v << 3) | x | ||||
| 		} | ||||
| 		s = s[2:] | ||||
| 		if v > 255 { | ||||
| 			err = ErrSyntax | ||||
| 			return | ||||
| 		} | ||||
| 		value = v | ||||
| 	case '\\': | ||||
| 		value = '\\' | ||||
| 	case '\'', '"': | ||||
| 		if c != quote { | ||||
| 			err = ErrSyntax | ||||
| 			return | ||||
| 		} | ||||
| 		value = rune(c) | ||||
| 	default: | ||||
| 		err = ErrSyntax | ||||
| 		return | ||||
| 	} | ||||
| 	tail = s | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										46
									
								
								vendor/github.com/hashicorp/hcl/hcl/token/position.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/hashicorp/hcl/hcl/token/position.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,46 +0,0 @@ | |||
| package token | ||||
| 
 | ||||
| import "fmt" | ||||
| 
 | ||||
| // Pos describes an arbitrary source position | ||||
| // including the file, line, and column location. | ||||
| // A Position is valid if the line number is > 0. | ||||
| type Pos struct { | ||||
| 	Filename string // filename, if any | ||||
| 	Offset   int    // offset, starting at 0 | ||||
| 	Line     int    // line number, starting at 1 | ||||
| 	Column   int    // column number, starting at 1 (character count) | ||||
| } | ||||
| 
 | ||||
| // IsValid returns true if the position is valid. | ||||
| func (p *Pos) IsValid() bool { return p.Line > 0 } | ||||
| 
 | ||||
| // String returns a string in one of several forms: | ||||
| // | ||||
| //	file:line:column    valid position with file name | ||||
| //	line:column         valid position without file name | ||||
| //	file                invalid position with file name | ||||
| //	-                   invalid position without file name | ||||
| func (p Pos) String() string { | ||||
| 	s := p.Filename | ||||
| 	if p.IsValid() { | ||||
| 		if s != "" { | ||||
| 			s += ":" | ||||
| 		} | ||||
| 		s += fmt.Sprintf("%d:%d", p.Line, p.Column) | ||||
| 	} | ||||
| 	if s == "" { | ||||
| 		s = "-" | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // Before reports whether the position p is before u. | ||||
| func (p Pos) Before(u Pos) bool { | ||||
| 	return u.Offset > p.Offset || u.Line > p.Line | ||||
| } | ||||
| 
 | ||||
| // After reports whether the position p is after u. | ||||
| func (p Pos) After(u Pos) bool { | ||||
| 	return u.Offset < p.Offset || u.Line < p.Line | ||||
| } | ||||
							
								
								
									
										219
									
								
								vendor/github.com/hashicorp/hcl/hcl/token/token.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										219
									
								
								vendor/github.com/hashicorp/hcl/hcl/token/token.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,219 +0,0 @@ | |||
| // Package token defines constants representing the lexical tokens for HCL | ||||
| // (HashiCorp Configuration Language) | ||||
| package token | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	hclstrconv "github.com/hashicorp/hcl/hcl/strconv" | ||||
| ) | ||||
| 
 | ||||
| // Token defines a single HCL token which can be obtained via the Scanner | ||||
| type Token struct { | ||||
| 	Type Type | ||||
| 	Pos  Pos | ||||
| 	Text string | ||||
| 	JSON bool | ||||
| } | ||||
| 
 | ||||
| // Type is the set of lexical tokens of the HCL (HashiCorp Configuration Language) | ||||
| type Type int | ||||
| 
 | ||||
| const ( | ||||
| 	// Special tokens | ||||
| 	ILLEGAL Type = iota | ||||
| 	EOF | ||||
| 	COMMENT | ||||
| 
 | ||||
| 	identifier_beg | ||||
| 	IDENT // literals | ||||
| 	literal_beg | ||||
| 	NUMBER  // 12345 | ||||
| 	FLOAT   // 123.45 | ||||
| 	BOOL    // true,false | ||||
| 	STRING  // "abc" | ||||
| 	HEREDOC // <<FOO\nbar\nFOO | ||||
| 	literal_end | ||||
| 	identifier_end | ||||
| 
 | ||||
| 	operator_beg | ||||
| 	LBRACK // [ | ||||
| 	LBRACE // { | ||||
| 	COMMA  // , | ||||
| 	PERIOD // . | ||||
| 
 | ||||
| 	RBRACK // ] | ||||
| 	RBRACE // } | ||||
| 
 | ||||
| 	ASSIGN // = | ||||
| 	ADD    // + | ||||
| 	SUB    // - | ||||
| 	operator_end | ||||
| ) | ||||
| 
 | ||||
| var tokens = [...]string{ | ||||
| 	ILLEGAL: "ILLEGAL", | ||||
| 
 | ||||
| 	EOF:     "EOF", | ||||
| 	COMMENT: "COMMENT", | ||||
| 
 | ||||
| 	IDENT:  "IDENT", | ||||
| 	NUMBER: "NUMBER", | ||||
| 	FLOAT:  "FLOAT", | ||||
| 	BOOL:   "BOOL", | ||||
| 	STRING: "STRING", | ||||
| 
 | ||||
| 	LBRACK:  "LBRACK", | ||||
| 	LBRACE:  "LBRACE", | ||||
| 	COMMA:   "COMMA", | ||||
| 	PERIOD:  "PERIOD", | ||||
| 	HEREDOC: "HEREDOC", | ||||
| 
 | ||||
| 	RBRACK: "RBRACK", | ||||
| 	RBRACE: "RBRACE", | ||||
| 
 | ||||
| 	ASSIGN: "ASSIGN", | ||||
| 	ADD:    "ADD", | ||||
| 	SUB:    "SUB", | ||||
| } | ||||
| 
 | ||||
| // String returns the string corresponding to the token tok. | ||||
| func (t Type) String() string { | ||||
| 	s := "" | ||||
| 	if 0 <= t && t < Type(len(tokens)) { | ||||
| 		s = tokens[t] | ||||
| 	} | ||||
| 	if s == "" { | ||||
| 		s = "token(" + strconv.Itoa(int(t)) + ")" | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // IsIdentifier returns true for tokens corresponding to identifiers and basic | ||||
| // type literals; it returns false otherwise. | ||||
| func (t Type) IsIdentifier() bool { return identifier_beg < t && t < identifier_end } | ||||
| 
 | ||||
| // IsLiteral returns true for tokens corresponding to basic type literals; it | ||||
| // returns false otherwise. | ||||
| func (t Type) IsLiteral() bool { return literal_beg < t && t < literal_end } | ||||
| 
 | ||||
| // IsOperator returns true for tokens corresponding to operators and | ||||
| // delimiters; it returns false otherwise. | ||||
| func (t Type) IsOperator() bool { return operator_beg < t && t < operator_end } | ||||
| 
 | ||||
| // String returns the token's literal text. Note that this is only | ||||
| // applicable for certain token types, such as token.IDENT, | ||||
| // token.STRING, etc.. | ||||
| func (t Token) String() string { | ||||
| 	return fmt.Sprintf("%s %s %s", t.Pos.String(), t.Type.String(), t.Text) | ||||
| } | ||||
| 
 | ||||
| // Value returns the properly typed value for this token. The type of | ||||
| // the returned interface{} is guaranteed based on the Type field. | ||||
| // | ||||
| // This can only be called for literal types. If it is called for any other | ||||
| // type, this will panic. | ||||
| func (t Token) Value() interface{} { | ||||
| 	switch t.Type { | ||||
| 	case BOOL: | ||||
| 		if t.Text == "true" { | ||||
| 			return true | ||||
| 		} else if t.Text == "false" { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		panic("unknown bool value: " + t.Text) | ||||
| 	case FLOAT: | ||||
| 		v, err := strconv.ParseFloat(t.Text, 64) | ||||
| 		if err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 
 | ||||
| 		return float64(v) | ||||
| 	case NUMBER: | ||||
| 		v, err := strconv.ParseInt(t.Text, 0, 64) | ||||
| 		if err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 
 | ||||
| 		return int64(v) | ||||
| 	case IDENT: | ||||
| 		return t.Text | ||||
| 	case HEREDOC: | ||||
| 		return unindentHeredoc(t.Text) | ||||
| 	case STRING: | ||||
| 		// Determine the Unquote method to use. If it came from JSON, | ||||
| 		// then we need to use the built-in unquote since we have to | ||||
| 		// escape interpolations there. | ||||
| 		f := hclstrconv.Unquote | ||||
| 		if t.JSON { | ||||
| 			f = strconv.Unquote | ||||
| 		} | ||||
| 
 | ||||
| 		// This case occurs if json null is used | ||||
| 		if t.Text == "" { | ||||
| 			return "" | ||||
| 		} | ||||
| 
 | ||||
| 		v, err := f(t.Text) | ||||
| 		if err != nil { | ||||
| 			panic(fmt.Sprintf("unquote %s err: %s", t.Text, err)) | ||||
| 		} | ||||
| 
 | ||||
| 		return v | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unimplemented Value for type: %s", t.Type)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // unindentHeredoc returns the string content of a HEREDOC if it is started with << | ||||
| // and the content of a HEREDOC with the hanging indent removed if it is started with | ||||
| // a <<-, and the terminating line is at least as indented as the least indented line. | ||||
| func unindentHeredoc(heredoc string) string { | ||||
| 	// We need to find the end of the marker | ||||
| 	idx := strings.IndexByte(heredoc, '\n') | ||||
| 	if idx == -1 { | ||||
| 		panic("heredoc doesn't contain newline") | ||||
| 	} | ||||
| 
 | ||||
| 	unindent := heredoc[2] == '-' | ||||
| 
 | ||||
| 	// We can optimize if the heredoc isn't marked for indentation | ||||
| 	if !unindent { | ||||
| 		return string(heredoc[idx+1 : len(heredoc)-idx+1]) | ||||
| 	} | ||||
| 
 | ||||
| 	// We need to unindent each line based on the indentation level of the marker | ||||
| 	lines := strings.Split(string(heredoc[idx+1:len(heredoc)-idx+2]), "\n") | ||||
| 	whitespacePrefix := lines[len(lines)-1] | ||||
| 
 | ||||
| 	isIndented := true | ||||
| 	for _, v := range lines { | ||||
| 		if strings.HasPrefix(v, whitespacePrefix) { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		isIndented = false | ||||
| 		break | ||||
| 	} | ||||
| 
 | ||||
| 	// If all lines are not at least as indented as the terminating mark, return the | ||||
| 	// heredoc as is, but trim the leading space from the marker on the final line. | ||||
| 	if !isIndented { | ||||
| 		return strings.TrimRight(string(heredoc[idx+1:len(heredoc)-idx+1]), " \t") | ||||
| 	} | ||||
| 
 | ||||
| 	unindentedLines := make([]string, len(lines)) | ||||
| 	for k, v := range lines { | ||||
| 		if k == len(lines)-1 { | ||||
| 			unindentedLines[k] = "" | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		unindentedLines[k] = strings.TrimPrefix(v, whitespacePrefix) | ||||
| 	} | ||||
| 
 | ||||
| 	return strings.Join(unindentedLines, "\n") | ||||
| } | ||||
							
								
								
									
										117
									
								
								vendor/github.com/hashicorp/hcl/json/parser/flatten.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										117
									
								
								vendor/github.com/hashicorp/hcl/json/parser/flatten.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,117 +0,0 @@ | |||
| package parser | ||||
| 
 | ||||
| import "github.com/hashicorp/hcl/hcl/ast" | ||||
| 
 | ||||
| // flattenObjects takes an AST node, walks it, and flattens | ||||
| func flattenObjects(node ast.Node) { | ||||
| 	ast.Walk(node, func(n ast.Node) (ast.Node, bool) { | ||||
| 		// We only care about lists, because this is what we modify | ||||
| 		list, ok := n.(*ast.ObjectList) | ||||
| 		if !ok { | ||||
| 			return n, true | ||||
| 		} | ||||
| 
 | ||||
| 		// Rebuild the item list | ||||
| 		items := make([]*ast.ObjectItem, 0, len(list.Items)) | ||||
| 		frontier := make([]*ast.ObjectItem, len(list.Items)) | ||||
| 		copy(frontier, list.Items) | ||||
| 		for len(frontier) > 0 { | ||||
| 			// Pop the current item | ||||
| 			n := len(frontier) | ||||
| 			item := frontier[n-1] | ||||
| 			frontier = frontier[:n-1] | ||||
| 
 | ||||
| 			switch v := item.Val.(type) { | ||||
| 			case *ast.ObjectType: | ||||
| 				items, frontier = flattenObjectType(v, item, items, frontier) | ||||
| 			case *ast.ListType: | ||||
| 				items, frontier = flattenListType(v, item, items, frontier) | ||||
| 			default: | ||||
| 				items = append(items, item) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// Reverse the list since the frontier model runs things backwards | ||||
| 		for i := len(items)/2 - 1; i >= 0; i-- { | ||||
| 			opp := len(items) - 1 - i | ||||
| 			items[i], items[opp] = items[opp], items[i] | ||||
| 		} | ||||
| 
 | ||||
| 		// Done! Set the original items | ||||
| 		list.Items = items | ||||
| 		return n, true | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func flattenListType( | ||||
| 	ot *ast.ListType, | ||||
| 	item *ast.ObjectItem, | ||||
| 	items []*ast.ObjectItem, | ||||
| 	frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) { | ||||
| 	// If the list is empty, keep the original list | ||||
| 	if len(ot.List) == 0 { | ||||
| 		items = append(items, item) | ||||
| 		return items, frontier | ||||
| 	} | ||||
| 
 | ||||
| 	// All the elements of this object must also be objects! | ||||
| 	for _, subitem := range ot.List { | ||||
| 		if _, ok := subitem.(*ast.ObjectType); !ok { | ||||
| 			items = append(items, item) | ||||
| 			return items, frontier | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Great! We have a match go through all the items and flatten | ||||
| 	for _, elem := range ot.List { | ||||
| 		// Add it to the frontier so that we can recurse | ||||
| 		frontier = append(frontier, &ast.ObjectItem{ | ||||
| 			Keys:        item.Keys, | ||||
| 			Assign:      item.Assign, | ||||
| 			Val:         elem, | ||||
| 			LeadComment: item.LeadComment, | ||||
| 			LineComment: item.LineComment, | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	return items, frontier | ||||
| } | ||||
| 
 | ||||
| func flattenObjectType( | ||||
| 	ot *ast.ObjectType, | ||||
| 	item *ast.ObjectItem, | ||||
| 	items []*ast.ObjectItem, | ||||
| 	frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) { | ||||
| 	// If the list has no items we do not have to flatten anything | ||||
| 	if ot.List.Items == nil { | ||||
| 		items = append(items, item) | ||||
| 		return items, frontier | ||||
| 	} | ||||
| 
 | ||||
| 	// All the elements of this object must also be objects! | ||||
| 	for _, subitem := range ot.List.Items { | ||||
| 		if _, ok := subitem.Val.(*ast.ObjectType); !ok { | ||||
| 			items = append(items, item) | ||||
| 			return items, frontier | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Great! We have a match go through all the items and flatten | ||||
| 	for _, subitem := range ot.List.Items { | ||||
| 		// Copy the new key | ||||
| 		keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys)) | ||||
| 		copy(keys, item.Keys) | ||||
| 		copy(keys[len(item.Keys):], subitem.Keys) | ||||
| 
 | ||||
| 		// Add it to the frontier so that we can recurse | ||||
| 		frontier = append(frontier, &ast.ObjectItem{ | ||||
| 			Keys:        keys, | ||||
| 			Assign:      item.Assign, | ||||
| 			Val:         subitem.Val, | ||||
| 			LeadComment: item.LeadComment, | ||||
| 			LineComment: item.LineComment, | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	return items, frontier | ||||
| } | ||||
							
								
								
									
										313
									
								
								vendor/github.com/hashicorp/hcl/json/parser/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										313
									
								
								vendor/github.com/hashicorp/hcl/json/parser/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,313 +0,0 @@ | |||
| package parser | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| 	hcltoken "github.com/hashicorp/hcl/hcl/token" | ||||
| 	"github.com/hashicorp/hcl/json/scanner" | ||||
| 	"github.com/hashicorp/hcl/json/token" | ||||
| ) | ||||
| 
 | ||||
| type Parser struct { | ||||
| 	sc *scanner.Scanner | ||||
| 
 | ||||
| 	// Last read token | ||||
| 	tok       token.Token | ||||
| 	commaPrev token.Token | ||||
| 
 | ||||
| 	enableTrace bool | ||||
| 	indent      int | ||||
| 	n           int // buffer size (max = 1) | ||||
| } | ||||
| 
 | ||||
| func newParser(src []byte) *Parser { | ||||
| 	return &Parser{ | ||||
| 		sc: scanner.New(src), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Parse returns the fully parsed source and returns the abstract syntax tree. | ||||
| func Parse(src []byte) (*ast.File, error) { | ||||
| 	p := newParser(src) | ||||
| 	return p.Parse() | ||||
| } | ||||
| 
 | ||||
| var errEofToken = errors.New("EOF token found") | ||||
| 
 | ||||
| // Parse returns the fully parsed source and returns the abstract syntax tree. | ||||
| func (p *Parser) Parse() (*ast.File, error) { | ||||
| 	f := &ast.File{} | ||||
| 	var err, scerr error | ||||
| 	p.sc.Error = func(pos token.Pos, msg string) { | ||||
| 		scerr = fmt.Errorf("%s: %s", pos, msg) | ||||
| 	} | ||||
| 
 | ||||
| 	// The root must be an object in JSON | ||||
| 	object, err := p.object() | ||||
| 	if scerr != nil { | ||||
| 		return nil, scerr | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// We make our final node an object list so it is more HCL compatible | ||||
| 	f.Node = object.List | ||||
| 
 | ||||
| 	// Flatten it, which finds patterns and turns them into more HCL-like | ||||
| 	// AST trees. | ||||
| 	flattenObjects(f.Node) | ||||
| 
 | ||||
| 	return f, nil | ||||
| } | ||||
| 
 | ||||
| func (p *Parser) objectList() (*ast.ObjectList, error) { | ||||
| 	defer un(trace(p, "ParseObjectList")) | ||||
| 	node := &ast.ObjectList{} | ||||
| 
 | ||||
| 	for { | ||||
| 		n, err := p.objectItem() | ||||
| 		if err == errEofToken { | ||||
| 			break // we are finished | ||||
| 		} | ||||
| 
 | ||||
| 		// we don't return a nil node, because might want to use already | ||||
| 		// collected items. | ||||
| 		if err != nil { | ||||
| 			return node, err | ||||
| 		} | ||||
| 
 | ||||
| 		node.Add(n) | ||||
| 
 | ||||
| 		// Check for a followup comma. If it isn't a comma, then we're done | ||||
| 		if tok := p.scan(); tok.Type != token.COMMA { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return node, nil | ||||
| } | ||||
| 
 | ||||
| // objectItem parses a single object item | ||||
| func (p *Parser) objectItem() (*ast.ObjectItem, error) { | ||||
| 	defer un(trace(p, "ParseObjectItem")) | ||||
| 
 | ||||
| 	keys, err := p.objectKey() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	o := &ast.ObjectItem{ | ||||
| 		Keys: keys, | ||||
| 	} | ||||
| 
 | ||||
| 	switch p.tok.Type { | ||||
| 	case token.COLON: | ||||
| 		pos := p.tok.Pos | ||||
| 		o.Assign = hcltoken.Pos{ | ||||
| 			Filename: pos.Filename, | ||||
| 			Offset:   pos.Offset, | ||||
| 			Line:     pos.Line, | ||||
| 			Column:   pos.Column, | ||||
| 		} | ||||
| 
 | ||||
| 		o.Val, err = p.objectValue() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return o, nil | ||||
| } | ||||
| 
 | ||||
| // objectKey parses an object key and returns a ObjectKey AST | ||||
| func (p *Parser) objectKey() ([]*ast.ObjectKey, error) { | ||||
| 	keyCount := 0 | ||||
| 	keys := make([]*ast.ObjectKey, 0) | ||||
| 
 | ||||
| 	for { | ||||
| 		tok := p.scan() | ||||
| 		switch tok.Type { | ||||
| 		case token.EOF: | ||||
| 			return nil, errEofToken | ||||
| 		case token.STRING: | ||||
| 			keyCount++ | ||||
| 			keys = append(keys, &ast.ObjectKey{ | ||||
| 				Token: p.tok.HCLToken(), | ||||
| 			}) | ||||
| 		case token.COLON: | ||||
| 			// If we have a zero keycount it means that we never got | ||||
| 			// an object key, i.e. `{ :`. This is a syntax error. | ||||
| 			if keyCount == 0 { | ||||
| 				return nil, fmt.Errorf("expected: STRING got: %s", p.tok.Type) | ||||
| 			} | ||||
| 
 | ||||
| 			// Done | ||||
| 			return keys, nil | ||||
| 		case token.ILLEGAL: | ||||
| 			return nil, errors.New("illegal") | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("expected: STRING got: %s", p.tok.Type) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // object parses any type of object, such as number, bool, string, object or | ||||
| // list. | ||||
| func (p *Parser) objectValue() (ast.Node, error) { | ||||
| 	defer un(trace(p, "ParseObjectValue")) | ||||
| 	tok := p.scan() | ||||
| 
 | ||||
| 	switch tok.Type { | ||||
| 	case token.NUMBER, token.FLOAT, token.BOOL, token.NULL, token.STRING: | ||||
| 		return p.literalType() | ||||
| 	case token.LBRACE: | ||||
| 		return p.objectType() | ||||
| 	case token.LBRACK: | ||||
| 		return p.listType() | ||||
| 	case token.EOF: | ||||
| 		return nil, errEofToken | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, fmt.Errorf("Expected object value, got unknown token: %+v", tok) | ||||
| } | ||||
| 
 | ||||
| // object parses any type of object, such as number, bool, string, object or | ||||
| // list. | ||||
| func (p *Parser) object() (*ast.ObjectType, error) { | ||||
| 	defer un(trace(p, "ParseType")) | ||||
| 	tok := p.scan() | ||||
| 
 | ||||
| 	switch tok.Type { | ||||
| 	case token.LBRACE: | ||||
| 		return p.objectType() | ||||
| 	case token.EOF: | ||||
| 		return nil, errEofToken | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, fmt.Errorf("Expected object, got unknown token: %+v", tok) | ||||
| } | ||||
| 
 | ||||
| // objectType parses an object type and returns a ObjectType AST | ||||
| func (p *Parser) objectType() (*ast.ObjectType, error) { | ||||
| 	defer un(trace(p, "ParseObjectType")) | ||||
| 
 | ||||
| 	// we assume that the currently scanned token is a LBRACE | ||||
| 	o := &ast.ObjectType{} | ||||
| 
 | ||||
| 	l, err := p.objectList() | ||||
| 
 | ||||
| 	// if we hit RBRACE, we are good to go (means we parsed all Items), if it's | ||||
| 	// not a RBRACE, it's an syntax error and we just return it. | ||||
| 	if err != nil && p.tok.Type != token.RBRACE { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	o.List = l | ||||
| 	return o, nil | ||||
| } | ||||
| 
 | ||||
| // listType parses a list type and returns a ListType AST | ||||
| func (p *Parser) listType() (*ast.ListType, error) { | ||||
| 	defer un(trace(p, "ParseListType")) | ||||
| 
 | ||||
| 	// we assume that the currently scanned token is a LBRACK | ||||
| 	l := &ast.ListType{} | ||||
| 
 | ||||
| 	for { | ||||
| 		tok := p.scan() | ||||
| 		switch tok.Type { | ||||
| 		case token.NUMBER, token.FLOAT, token.STRING: | ||||
| 			node, err := p.literalType() | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 
 | ||||
| 			l.Add(node) | ||||
| 		case token.COMMA: | ||||
| 			continue | ||||
| 		case token.LBRACE: | ||||
| 			node, err := p.objectType() | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 
 | ||||
| 			l.Add(node) | ||||
| 		case token.BOOL: | ||||
| 			// TODO(arslan) should we support? not supported by HCL yet | ||||
| 		case token.LBRACK: | ||||
| 			// TODO(arslan) should we support nested lists? Even though it's | ||||
| 			// written in README of HCL, it's not a part of the grammar | ||||
| 			// (not defined in parse.y) | ||||
| 		case token.RBRACK: | ||||
| 			// finished | ||||
| 			return l, nil | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("unexpected token while parsing list: %s", tok.Type) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // literalType parses a literal type and returns a LiteralType AST | ||||
| func (p *Parser) literalType() (*ast.LiteralType, error) { | ||||
| 	defer un(trace(p, "ParseLiteral")) | ||||
| 
 | ||||
| 	return &ast.LiteralType{ | ||||
| 		Token: p.tok.HCLToken(), | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| // scan returns the next token from the underlying scanner. If a token has | ||||
| // been unscanned then read that instead. | ||||
| func (p *Parser) scan() token.Token { | ||||
| 	// If we have a token on the buffer, then return it. | ||||
| 	if p.n != 0 { | ||||
| 		p.n = 0 | ||||
| 		return p.tok | ||||
| 	} | ||||
| 
 | ||||
| 	p.tok = p.sc.Scan() | ||||
| 	return p.tok | ||||
| } | ||||
| 
 | ||||
| // unscan pushes the previously read token back onto the buffer. | ||||
| func (p *Parser) unscan() { | ||||
| 	p.n = 1 | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Parsing support | ||||
| 
 | ||||
| func (p *Parser) printTrace(a ...interface{}) { | ||||
| 	if !p.enableTrace { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " | ||||
| 	const n = len(dots) | ||||
| 	fmt.Printf("%5d:%3d: ", p.tok.Pos.Line, p.tok.Pos.Column) | ||||
| 
 | ||||
| 	i := 2 * p.indent | ||||
| 	for i > n { | ||||
| 		fmt.Print(dots) | ||||
| 		i -= n | ||||
| 	} | ||||
| 	// i <= n | ||||
| 	fmt.Print(dots[0:i]) | ||||
| 	fmt.Println(a...) | ||||
| } | ||||
| 
 | ||||
| func trace(p *Parser, msg string) *Parser { | ||||
| 	p.printTrace(msg, "(") | ||||
| 	p.indent++ | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| // Usage pattern: defer un(trace(p, "...")) | ||||
| func un(p *Parser) { | ||||
| 	p.indent-- | ||||
| 	p.printTrace(")") | ||||
| } | ||||
							
								
								
									
										451
									
								
								vendor/github.com/hashicorp/hcl/json/scanner/scanner.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										451
									
								
								vendor/github.com/hashicorp/hcl/json/scanner/scanner.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,451 +0,0 @@ | |||
| package scanner | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/json/token" | ||||
| ) | ||||
| 
 | ||||
| // eof represents a marker rune for the end of the reader. | ||||
| const eof = rune(0) | ||||
| 
 | ||||
| // Scanner defines a lexical scanner | ||||
| type Scanner struct { | ||||
| 	buf *bytes.Buffer // Source buffer for advancing and scanning | ||||
| 	src []byte        // Source buffer for immutable access | ||||
| 
 | ||||
| 	// Source Position | ||||
| 	srcPos  token.Pos // current position | ||||
| 	prevPos token.Pos // previous position, used for peek() method | ||||
| 
 | ||||
| 	lastCharLen int // length of last character in bytes | ||||
| 	lastLineLen int // length of last line in characters (for correct column reporting) | ||||
| 
 | ||||
| 	tokStart int // token text start position | ||||
| 	tokEnd   int // token text end  position | ||||
| 
 | ||||
| 	// Error is called for each error encountered. If no Error | ||||
| 	// function is set, the error is reported to os.Stderr. | ||||
| 	Error func(pos token.Pos, msg string) | ||||
| 
 | ||||
| 	// ErrorCount is incremented by one for each error encountered. | ||||
| 	ErrorCount int | ||||
| 
 | ||||
| 	// tokPos is the start position of most recently scanned token; set by | ||||
| 	// Scan. The Filename field is always left untouched by the Scanner.  If | ||||
| 	// an error is reported (via Error) and Position is invalid, the scanner is | ||||
| 	// not inside a token. | ||||
| 	tokPos token.Pos | ||||
| } | ||||
| 
 | ||||
| // New creates and initializes a new instance of Scanner using src as | ||||
| // its source content. | ||||
| func New(src []byte) *Scanner { | ||||
| 	// even though we accept a src, we read from a io.Reader compatible type | ||||
| 	// (*bytes.Buffer). So in the future we might easily change it to streaming | ||||
| 	// read. | ||||
| 	b := bytes.NewBuffer(src) | ||||
| 	s := &Scanner{ | ||||
| 		buf: b, | ||||
| 		src: src, | ||||
| 	} | ||||
| 
 | ||||
| 	// srcPosition always starts with 1 | ||||
| 	s.srcPos.Line = 1 | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // next reads the next rune from the bufferred reader. Returns the rune(0) if | ||||
| // an error occurs (or io.EOF is returned). | ||||
| func (s *Scanner) next() rune { | ||||
| 	ch, size, err := s.buf.ReadRune() | ||||
| 	if err != nil { | ||||
| 		// advance for error reporting | ||||
| 		s.srcPos.Column++ | ||||
| 		s.srcPos.Offset += size | ||||
| 		s.lastCharLen = size | ||||
| 		return eof | ||||
| 	} | ||||
| 
 | ||||
| 	if ch == utf8.RuneError && size == 1 { | ||||
| 		s.srcPos.Column++ | ||||
| 		s.srcPos.Offset += size | ||||
| 		s.lastCharLen = size | ||||
| 		s.err("illegal UTF-8 encoding") | ||||
| 		return ch | ||||
| 	} | ||||
| 
 | ||||
| 	// remember last position | ||||
| 	s.prevPos = s.srcPos | ||||
| 
 | ||||
| 	s.srcPos.Column++ | ||||
| 	s.lastCharLen = size | ||||
| 	s.srcPos.Offset += size | ||||
| 
 | ||||
| 	if ch == '\n' { | ||||
| 		s.srcPos.Line++ | ||||
| 		s.lastLineLen = s.srcPos.Column | ||||
| 		s.srcPos.Column = 0 | ||||
| 	} | ||||
| 
 | ||||
| 	// debug | ||||
| 	// fmt.Printf("ch: %q, offset:column: %d:%d\n", ch, s.srcPos.Offset, s.srcPos.Column) | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // unread unreads the previous read Rune and updates the source position | ||||
| func (s *Scanner) unread() { | ||||
| 	if err := s.buf.UnreadRune(); err != nil { | ||||
| 		panic(err) // this is user fault, we should catch it | ||||
| 	} | ||||
| 	s.srcPos = s.prevPos // put back last position | ||||
| } | ||||
| 
 | ||||
| // peek returns the next rune without advancing the reader. | ||||
| func (s *Scanner) peek() rune { | ||||
| 	peek, _, err := s.buf.ReadRune() | ||||
| 	if err != nil { | ||||
| 		return eof | ||||
| 	} | ||||
| 
 | ||||
| 	s.buf.UnreadRune() | ||||
| 	return peek | ||||
| } | ||||
| 
 | ||||
| // Scan scans the next token and returns the token. | ||||
| func (s *Scanner) Scan() token.Token { | ||||
| 	ch := s.next() | ||||
| 
 | ||||
| 	// skip white space | ||||
| 	for isWhitespace(ch) { | ||||
| 		ch = s.next() | ||||
| 	} | ||||
| 
 | ||||
| 	var tok token.Type | ||||
| 
 | ||||
| 	// token text markings | ||||
| 	s.tokStart = s.srcPos.Offset - s.lastCharLen | ||||
| 
 | ||||
| 	// token position, initial next() is moving the offset by one(size of rune | ||||
| 	// actually), though we are interested with the starting point | ||||
| 	s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen | ||||
| 	if s.srcPos.Column > 0 { | ||||
| 		// common case: last character was not a '\n' | ||||
| 		s.tokPos.Line = s.srcPos.Line | ||||
| 		s.tokPos.Column = s.srcPos.Column | ||||
| 	} else { | ||||
| 		// last character was a '\n' | ||||
| 		// (we cannot be at the beginning of the source | ||||
| 		// since we have called next() at least once) | ||||
| 		s.tokPos.Line = s.srcPos.Line - 1 | ||||
| 		s.tokPos.Column = s.lastLineLen | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case isLetter(ch): | ||||
| 		lit := s.scanIdentifier() | ||||
| 		if lit == "true" || lit == "false" { | ||||
| 			tok = token.BOOL | ||||
| 		} else if lit == "null" { | ||||
| 			tok = token.NULL | ||||
| 		} else { | ||||
| 			s.err("illegal char") | ||||
| 		} | ||||
| 	case isDecimal(ch): | ||||
| 		tok = s.scanNumber(ch) | ||||
| 	default: | ||||
| 		switch ch { | ||||
| 		case eof: | ||||
| 			tok = token.EOF | ||||
| 		case '"': | ||||
| 			tok = token.STRING | ||||
| 			s.scanString() | ||||
| 		case '.': | ||||
| 			tok = token.PERIOD | ||||
| 			ch = s.peek() | ||||
| 			if isDecimal(ch) { | ||||
| 				tok = token.FLOAT | ||||
| 				ch = s.scanMantissa(ch) | ||||
| 				ch = s.scanExponent(ch) | ||||
| 			} | ||||
| 		case '[': | ||||
| 			tok = token.LBRACK | ||||
| 		case ']': | ||||
| 			tok = token.RBRACK | ||||
| 		case '{': | ||||
| 			tok = token.LBRACE | ||||
| 		case '}': | ||||
| 			tok = token.RBRACE | ||||
| 		case ',': | ||||
| 			tok = token.COMMA | ||||
| 		case ':': | ||||
| 			tok = token.COLON | ||||
| 		case '-': | ||||
| 			if isDecimal(s.peek()) { | ||||
| 				ch := s.next() | ||||
| 				tok = s.scanNumber(ch) | ||||
| 			} else { | ||||
| 				s.err("illegal char") | ||||
| 			} | ||||
| 		default: | ||||
| 			s.err("illegal char: " + string(ch)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// finish token ending | ||||
| 	s.tokEnd = s.srcPos.Offset | ||||
| 
 | ||||
| 	// create token literal | ||||
| 	var tokenText string | ||||
| 	if s.tokStart >= 0 { | ||||
| 		tokenText = string(s.src[s.tokStart:s.tokEnd]) | ||||
| 	} | ||||
| 	s.tokStart = s.tokEnd // ensure idempotency of tokenText() call | ||||
| 
 | ||||
| 	return token.Token{ | ||||
| 		Type: tok, | ||||
| 		Pos:  s.tokPos, | ||||
| 		Text: tokenText, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // scanNumber scans a HCL number definition starting with the given rune | ||||
| func (s *Scanner) scanNumber(ch rune) token.Type { | ||||
| 	zero := ch == '0' | ||||
| 	pos := s.srcPos | ||||
| 
 | ||||
| 	s.scanMantissa(ch) | ||||
| 	ch = s.next() // seek forward | ||||
| 	if ch == 'e' || ch == 'E' { | ||||
| 		ch = s.scanExponent(ch) | ||||
| 		return token.FLOAT | ||||
| 	} | ||||
| 
 | ||||
| 	if ch == '.' { | ||||
| 		ch = s.scanFraction(ch) | ||||
| 		if ch == 'e' || ch == 'E' { | ||||
| 			ch = s.next() | ||||
| 			ch = s.scanExponent(ch) | ||||
| 		} | ||||
| 		return token.FLOAT | ||||
| 	} | ||||
| 
 | ||||
| 	if ch != eof { | ||||
| 		s.unread() | ||||
| 	} | ||||
| 
 | ||||
| 	// If we have a larger number and this is zero, error | ||||
| 	if zero && pos != s.srcPos { | ||||
| 		s.err("numbers cannot start with 0") | ||||
| 	} | ||||
| 
 | ||||
| 	return token.NUMBER | ||||
| } | ||||
| 
 | ||||
| // scanMantissa scans the mantissa beginning from the rune. It returns the next | ||||
| // non decimal rune. It's used to determine wheter it's a fraction or exponent. | ||||
| func (s *Scanner) scanMantissa(ch rune) rune { | ||||
| 	scanned := false | ||||
| 	for isDecimal(ch) { | ||||
| 		ch = s.next() | ||||
| 		scanned = true | ||||
| 	} | ||||
| 
 | ||||
| 	if scanned && ch != eof { | ||||
| 		s.unread() | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanFraction scans the fraction after the '.' rune | ||||
| func (s *Scanner) scanFraction(ch rune) rune { | ||||
| 	if ch == '.' { | ||||
| 		ch = s.peek() // we peek just to see if we can move forward | ||||
| 		ch = s.scanMantissa(ch) | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanExponent scans the remaining parts of an exponent after the 'e' or 'E' | ||||
| // rune. | ||||
| func (s *Scanner) scanExponent(ch rune) rune { | ||||
| 	if ch == 'e' || ch == 'E' { | ||||
| 		ch = s.next() | ||||
| 		if ch == '-' || ch == '+' { | ||||
| 			ch = s.next() | ||||
| 		} | ||||
| 		ch = s.scanMantissa(ch) | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanString scans a quoted string | ||||
| func (s *Scanner) scanString() { | ||||
| 	braces := 0 | ||||
| 	for { | ||||
| 		// '"' opening already consumed | ||||
| 		// read character after quote | ||||
| 		ch := s.next() | ||||
| 
 | ||||
| 		if ch == '\n' || ch < 0 || ch == eof { | ||||
| 			s.err("literal not terminated") | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == '"' { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		// If we're going into a ${} then we can ignore quotes for awhile | ||||
| 		if braces == 0 && ch == '$' && s.peek() == '{' { | ||||
| 			braces++ | ||||
| 			s.next() | ||||
| 		} else if braces > 0 && ch == '{' { | ||||
| 			braces++ | ||||
| 		} | ||||
| 		if braces > 0 && ch == '}' { | ||||
| 			braces-- | ||||
| 		} | ||||
| 
 | ||||
| 		if ch == '\\' { | ||||
| 			s.scanEscape() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // scanEscape scans an escape sequence | ||||
| func (s *Scanner) scanEscape() rune { | ||||
| 	// http://en.cppreference.com/w/cpp/language/escape | ||||
| 	ch := s.next() // read character after '/' | ||||
| 	switch ch { | ||||
| 	case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"': | ||||
| 		// nothing to do | ||||
| 	case '0', '1', '2', '3', '4', '5', '6', '7': | ||||
| 		// octal notation | ||||
| 		ch = s.scanDigits(ch, 8, 3) | ||||
| 	case 'x': | ||||
| 		// hexademical notation | ||||
| 		ch = s.scanDigits(s.next(), 16, 2) | ||||
| 	case 'u': | ||||
| 		// universal character name | ||||
| 		ch = s.scanDigits(s.next(), 16, 4) | ||||
| 	case 'U': | ||||
| 		// universal character name | ||||
| 		ch = s.scanDigits(s.next(), 16, 8) | ||||
| 	default: | ||||
| 		s.err("illegal char escape") | ||||
| 	} | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanDigits scans a rune with the given base for n times. For example an | ||||
| // octal notation \184 would yield in scanDigits(ch, 8, 3) | ||||
| func (s *Scanner) scanDigits(ch rune, base, n int) rune { | ||||
| 	for n > 0 && digitVal(ch) < base { | ||||
| 		ch = s.next() | ||||
| 		n-- | ||||
| 	} | ||||
| 	if n > 0 { | ||||
| 		s.err("illegal char escape") | ||||
| 	} | ||||
| 
 | ||||
| 	// we scanned all digits, put the last non digit char back | ||||
| 	s.unread() | ||||
| 	return ch | ||||
| } | ||||
| 
 | ||||
| // scanIdentifier scans an identifier and returns the literal string | ||||
| func (s *Scanner) scanIdentifier() string { | ||||
| 	offs := s.srcPos.Offset - s.lastCharLen | ||||
| 	ch := s.next() | ||||
| 	for isLetter(ch) || isDigit(ch) || ch == '-' { | ||||
| 		ch = s.next() | ||||
| 	} | ||||
| 
 | ||||
| 	if ch != eof { | ||||
| 		s.unread() // we got identifier, put back latest char | ||||
| 	} | ||||
| 
 | ||||
| 	return string(s.src[offs:s.srcPos.Offset]) | ||||
| } | ||||
| 
 | ||||
| // recentPosition returns the position of the character immediately after the | ||||
| // character or token returned by the last call to Scan. | ||||
| func (s *Scanner) recentPosition() (pos token.Pos) { | ||||
| 	pos.Offset = s.srcPos.Offset - s.lastCharLen | ||||
| 	switch { | ||||
| 	case s.srcPos.Column > 0: | ||||
| 		// common case: last character was not a '\n' | ||||
| 		pos.Line = s.srcPos.Line | ||||
| 		pos.Column = s.srcPos.Column | ||||
| 	case s.lastLineLen > 0: | ||||
| 		// last character was a '\n' | ||||
| 		// (we cannot be at the beginning of the source | ||||
| 		// since we have called next() at least once) | ||||
| 		pos.Line = s.srcPos.Line - 1 | ||||
| 		pos.Column = s.lastLineLen | ||||
| 	default: | ||||
| 		// at the beginning of the source | ||||
| 		pos.Line = 1 | ||||
| 		pos.Column = 1 | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // err prints the error of any scanning to s.Error function. If the function is | ||||
| // not defined, by default it prints them to os.Stderr | ||||
| func (s *Scanner) err(msg string) { | ||||
| 	s.ErrorCount++ | ||||
| 	pos := s.recentPosition() | ||||
| 
 | ||||
| 	if s.Error != nil { | ||||
| 		s.Error(pos, msg) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg) | ||||
| } | ||||
| 
 | ||||
| // isHexadecimal returns true if the given rune is a letter | ||||
| func isLetter(ch rune) bool { | ||||
| 	return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) | ||||
| } | ||||
| 
 | ||||
| // isHexadecimal returns true if the given rune is a decimal digit | ||||
| func isDigit(ch rune) bool { | ||||
| 	return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) | ||||
| } | ||||
| 
 | ||||
| // isHexadecimal returns true if the given rune is a decimal number | ||||
| func isDecimal(ch rune) bool { | ||||
| 	return '0' <= ch && ch <= '9' | ||||
| } | ||||
| 
 | ||||
| // isHexadecimal returns true if the given rune is an hexadecimal number | ||||
| func isHexadecimal(ch rune) bool { | ||||
| 	return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F' | ||||
| } | ||||
| 
 | ||||
| // isWhitespace returns true if the rune is a space, tab, newline or carriage return | ||||
| func isWhitespace(ch rune) bool { | ||||
| 	return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' | ||||
| } | ||||
| 
 | ||||
| // digitVal returns the integer value of a given octal,decimal or hexadecimal rune | ||||
| func digitVal(ch rune) int { | ||||
| 	switch { | ||||
| 	case '0' <= ch && ch <= '9': | ||||
| 		return int(ch - '0') | ||||
| 	case 'a' <= ch && ch <= 'f': | ||||
| 		return int(ch - 'a' + 10) | ||||
| 	case 'A' <= ch && ch <= 'F': | ||||
| 		return int(ch - 'A' + 10) | ||||
| 	} | ||||
| 	return 16 // larger than any legal digit val | ||||
| } | ||||
							
								
								
									
										46
									
								
								vendor/github.com/hashicorp/hcl/json/token/position.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/hashicorp/hcl/json/token/position.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,46 +0,0 @@ | |||
| package token | ||||
| 
 | ||||
| import "fmt" | ||||
| 
 | ||||
| // Pos describes an arbitrary source position | ||||
| // including the file, line, and column location. | ||||
| // A Position is valid if the line number is > 0. | ||||
| type Pos struct { | ||||
| 	Filename string // filename, if any | ||||
| 	Offset   int    // offset, starting at 0 | ||||
| 	Line     int    // line number, starting at 1 | ||||
| 	Column   int    // column number, starting at 1 (character count) | ||||
| } | ||||
| 
 | ||||
| // IsValid returns true if the position is valid. | ||||
| func (p *Pos) IsValid() bool { return p.Line > 0 } | ||||
| 
 | ||||
| // String returns a string in one of several forms: | ||||
| // | ||||
| //	file:line:column    valid position with file name | ||||
| //	line:column         valid position without file name | ||||
| //	file                invalid position with file name | ||||
| //	-                   invalid position without file name | ||||
| func (p Pos) String() string { | ||||
| 	s := p.Filename | ||||
| 	if p.IsValid() { | ||||
| 		if s != "" { | ||||
| 			s += ":" | ||||
| 		} | ||||
| 		s += fmt.Sprintf("%d:%d", p.Line, p.Column) | ||||
| 	} | ||||
| 	if s == "" { | ||||
| 		s = "-" | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // Before reports whether the position p is before u. | ||||
| func (p Pos) Before(u Pos) bool { | ||||
| 	return u.Offset > p.Offset || u.Line > p.Line | ||||
| } | ||||
| 
 | ||||
| // After reports whether the position p is after u. | ||||
| func (p Pos) After(u Pos) bool { | ||||
| 	return u.Offset < p.Offset || u.Line < p.Line | ||||
| } | ||||
							
								
								
									
										118
									
								
								vendor/github.com/hashicorp/hcl/json/token/token.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										118
									
								
								vendor/github.com/hashicorp/hcl/json/token/token.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,118 +0,0 @@ | |||
| package token | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	hcltoken "github.com/hashicorp/hcl/hcl/token" | ||||
| ) | ||||
| 
 | ||||
| // Token defines a single HCL token which can be obtained via the Scanner | ||||
| type Token struct { | ||||
| 	Type Type | ||||
| 	Pos  Pos | ||||
| 	Text string | ||||
| } | ||||
| 
 | ||||
| // Type is the set of lexical tokens of the HCL (HashiCorp Configuration Language) | ||||
| type Type int | ||||
| 
 | ||||
| const ( | ||||
| 	// Special tokens | ||||
| 	ILLEGAL Type = iota | ||||
| 	EOF | ||||
| 
 | ||||
| 	identifier_beg | ||||
| 	literal_beg | ||||
| 	NUMBER // 12345 | ||||
| 	FLOAT  // 123.45 | ||||
| 	BOOL   // true,false | ||||
| 	STRING // "abc" | ||||
| 	NULL   // null | ||||
| 	literal_end | ||||
| 	identifier_end | ||||
| 
 | ||||
| 	operator_beg | ||||
| 	LBRACK // [ | ||||
| 	LBRACE // { | ||||
| 	COMMA  // , | ||||
| 	PERIOD // . | ||||
| 	COLON  // : | ||||
| 
 | ||||
| 	RBRACK // ] | ||||
| 	RBRACE // } | ||||
| 
 | ||||
| 	operator_end | ||||
| ) | ||||
| 
 | ||||
| var tokens = [...]string{ | ||||
| 	ILLEGAL: "ILLEGAL", | ||||
| 
 | ||||
| 	EOF: "EOF", | ||||
| 
 | ||||
| 	NUMBER: "NUMBER", | ||||
| 	FLOAT:  "FLOAT", | ||||
| 	BOOL:   "BOOL", | ||||
| 	STRING: "STRING", | ||||
| 	NULL:   "NULL", | ||||
| 
 | ||||
| 	LBRACK: "LBRACK", | ||||
| 	LBRACE: "LBRACE", | ||||
| 	COMMA:  "COMMA", | ||||
| 	PERIOD: "PERIOD", | ||||
| 	COLON:  "COLON", | ||||
| 
 | ||||
| 	RBRACK: "RBRACK", | ||||
| 	RBRACE: "RBRACE", | ||||
| } | ||||
| 
 | ||||
| // String returns the string corresponding to the token tok. | ||||
| func (t Type) String() string { | ||||
| 	s := "" | ||||
| 	if 0 <= t && t < Type(len(tokens)) { | ||||
| 		s = tokens[t] | ||||
| 	} | ||||
| 	if s == "" { | ||||
| 		s = "token(" + strconv.Itoa(int(t)) + ")" | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // IsIdentifier returns true for tokens corresponding to identifiers and basic | ||||
| // type literals; it returns false otherwise. | ||||
| func (t Type) IsIdentifier() bool { return identifier_beg < t && t < identifier_end } | ||||
| 
 | ||||
| // IsLiteral returns true for tokens corresponding to basic type literals; it | ||||
| // returns false otherwise. | ||||
| func (t Type) IsLiteral() bool { return literal_beg < t && t < literal_end } | ||||
| 
 | ||||
| // IsOperator returns true for tokens corresponding to operators and | ||||
| // delimiters; it returns false otherwise. | ||||
| func (t Type) IsOperator() bool { return operator_beg < t && t < operator_end } | ||||
| 
 | ||||
| // String returns the token's literal text. Note that this is only | ||||
| // applicable for certain token types, such as token.IDENT, | ||||
| // token.STRING, etc.. | ||||
| func (t Token) String() string { | ||||
| 	return fmt.Sprintf("%s %s %s", t.Pos.String(), t.Type.String(), t.Text) | ||||
| } | ||||
| 
 | ||||
| // HCLToken converts this token to an HCL token. | ||||
| // | ||||
| // The token type must be a literal type or this will panic. | ||||
| func (t Token) HCLToken() hcltoken.Token { | ||||
| 	switch t.Type { | ||||
| 	case BOOL: | ||||
| 		return hcltoken.Token{Type: hcltoken.BOOL, Text: t.Text} | ||||
| 	case FLOAT: | ||||
| 		return hcltoken.Token{Type: hcltoken.FLOAT, Text: t.Text} | ||||
| 	case NULL: | ||||
| 		return hcltoken.Token{Type: hcltoken.STRING, Text: ""} | ||||
| 	case NUMBER: | ||||
| 		return hcltoken.Token{Type: hcltoken.NUMBER, Text: t.Text} | ||||
| 	case STRING: | ||||
| 		return hcltoken.Token{Type: hcltoken.STRING, Text: t.Text, JSON: true} | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unimplemented HCLToken for type: %s", t.Type)) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										38
									
								
								vendor/github.com/hashicorp/hcl/lex.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/hashicorp/hcl/lex.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,38 +0,0 @@ | |||
| package hcl | ||||
| 
 | ||||
| import ( | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
| 
 | ||||
| type lexModeValue byte | ||||
| 
 | ||||
| const ( | ||||
| 	lexModeUnknown lexModeValue = iota | ||||
| 	lexModeHcl | ||||
| 	lexModeJson | ||||
| ) | ||||
| 
 | ||||
| // lexMode returns whether we're going to be parsing in JSON | ||||
| // mode or HCL mode. | ||||
| func lexMode(v []byte) lexModeValue { | ||||
| 	var ( | ||||
| 		r      rune | ||||
| 		w      int | ||||
| 		offset int | ||||
| 	) | ||||
| 
 | ||||
| 	for { | ||||
| 		r, w = utf8.DecodeRune(v[offset:]) | ||||
| 		offset += w | ||||
| 		if unicode.IsSpace(r) { | ||||
| 			continue | ||||
| 		} | ||||
| 		if r == '{' { | ||||
| 			return lexModeJson | ||||
| 		} | ||||
| 		break | ||||
| 	} | ||||
| 
 | ||||
| 	return lexModeHcl | ||||
| } | ||||
							
								
								
									
										39
									
								
								vendor/github.com/hashicorp/hcl/parse.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/hashicorp/hcl/parse.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,39 +0,0 @@ | |||
| package hcl | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| 	hclParser "github.com/hashicorp/hcl/hcl/parser" | ||||
| 	jsonParser "github.com/hashicorp/hcl/json/parser" | ||||
| ) | ||||
| 
 | ||||
| // ParseBytes accepts as input byte slice and returns ast tree. | ||||
| // | ||||
| // Input can be either JSON or HCL | ||||
| func ParseBytes(in []byte) (*ast.File, error) { | ||||
| 	return parse(in) | ||||
| } | ||||
| 
 | ||||
| // ParseString accepts input as a string and returns ast tree. | ||||
| func ParseString(input string) (*ast.File, error) { | ||||
| 	return parse([]byte(input)) | ||||
| } | ||||
| 
 | ||||
| func parse(in []byte) (*ast.File, error) { | ||||
| 	switch lexMode(in) { | ||||
| 	case lexModeHcl: | ||||
| 		return hclParser.Parse(in) | ||||
| 	case lexModeJson: | ||||
| 		return jsonParser.Parse(in) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, fmt.Errorf("unknown config format") | ||||
| } | ||||
| 
 | ||||
| // Parse parses the given input and returns the root object. | ||||
| // | ||||
| // The input format can be either HCL or JSON. | ||||
| func Parse(input string) (*ast.File, error) { | ||||
| 	return parse([]byte(input)) | ||||
| } | ||||
							
								
								
									
										6
									
								
								vendor/github.com/magiconair/properties/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/magiconair/properties/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,6 +0,0 @@ | |||
| *.sublime-project | ||||
| *.sublime-workspace | ||||
| *.un~ | ||||
| *.swp | ||||
| .idea/ | ||||
| *.iml | ||||
							
								
								
									
										205
									
								
								vendor/github.com/magiconair/properties/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										205
									
								
								vendor/github.com/magiconair/properties/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,205 +0,0 @@ | |||
| ## Changelog | ||||
| 
 | ||||
| ### [1.8.7](https://github.com/magiconair/properties/tree/v1.8.7) - 08 Dec 2022 | ||||
| 
 | ||||
|  * [PR #65](https://github.com/magiconair/properties/pull/65): Speedup Merge | ||||
| 
 | ||||
|    Thanks to [@AdityaVallabh](https://github.com/AdityaVallabh) for the patch. | ||||
| 
 | ||||
|  * [PR #66](https://github.com/magiconair/properties/pull/66): use github actions | ||||
| 
 | ||||
| ### [1.8.6](https://github.com/magiconair/properties/tree/v1.8.6) - 23 Feb 2022 | ||||
| 
 | ||||
|  * [PR #57](https://github.com/magiconair/properties/pull/57):Fix "unreachable code" lint error | ||||
| 
 | ||||
|    Thanks to [@ellie](https://github.com/ellie) for the patch. | ||||
| 
 | ||||
|  * [PR #63](https://github.com/magiconair/properties/pull/63): Make TestMustGetParsedDuration backwards compatible | ||||
| 
 | ||||
|    This patch ensures that the `TestMustGetParsedDuration` still works with `go1.3` to make the | ||||
|    author happy until it affects real users. | ||||
| 
 | ||||
|    Thanks to [@maage](https://github.com/maage) for the patch. | ||||
| 
 | ||||
| ### [1.8.5](https://github.com/magiconair/properties/tree/v1.8.5) - 24 Mar 2021 | ||||
| 
 | ||||
|  * [PR #55](https://github.com/magiconair/properties/pull/55): Fix: Encoding Bug in Comments | ||||
| 
 | ||||
|    When reading comments \ are loaded correctly, but when writing they are then | ||||
|    replaced by \\. This leads to wrong comments when writing and reading multiple times. | ||||
| 
 | ||||
|    Thanks to [@doxsch](https://github.com/doxsch) for the patch. | ||||
| 
 | ||||
| ### [1.8.4](https://github.com/magiconair/properties/tree/v1.8.4) - 23 Sep 2020 | ||||
| 
 | ||||
|  * [PR #50](https://github.com/magiconair/properties/pull/50): enhance error message for circular references | ||||
| 
 | ||||
|    Thanks to [@sriv](https://github.com/sriv) for the patch. | ||||
| 
 | ||||
| ### [1.8.3](https://github.com/magiconair/properties/tree/v1.8.3) - 14 Sep 2020 | ||||
| 
 | ||||
|  * [PR #49](https://github.com/magiconair/properties/pull/49): Include the key in error message causing the circular reference | ||||
| 
 | ||||
|    The change is include the key in the error message which is causing the circular | ||||
|    reference when parsing/loading the properties files. | ||||
| 
 | ||||
|    Thanks to [@haroon-sheikh](https://github.com/haroon-sheikh) for the patch. | ||||
| 
 | ||||
| ### [1.8.2](https://github.com/magiconair/properties/tree/v1.8.2) - 25 Aug 2020 | ||||
| 
 | ||||
|  * [PR #36](https://github.com/magiconair/properties/pull/36): Escape backslash on write | ||||
| 
 | ||||
|    This patch ensures that backslashes are escaped on write. Existing applications which | ||||
|    rely on the old behavior may need to be updated. | ||||
| 
 | ||||
|    Thanks to [@apesternikov](https://github.com/apesternikov) for the patch. | ||||
| 
 | ||||
|  * [PR #42](https://github.com/magiconair/properties/pull/42): Made Content-Type check whitespace agnostic in LoadURL() | ||||
| 
 | ||||
|    Thanks to [@aliras1](https://github.com/aliras1) for the patch. | ||||
| 
 | ||||
|  * [PR #41](https://github.com/magiconair/properties/pull/41): Make key/value separator configurable on Write() | ||||
| 
 | ||||
|    Thanks to [@mkjor](https://github.com/mkjor) for the patch. | ||||
| 
 | ||||
|  * [PR #40](https://github.com/magiconair/properties/pull/40): Add method to return a sorted list of keys | ||||
| 
 | ||||
|    Thanks to [@mkjor](https://github.com/mkjor) for the patch. | ||||
| 
 | ||||
| ### [1.8.1](https://github.com/magiconair/properties/tree/v1.8.1) - 10 May 2019 | ||||
| 
 | ||||
|  * [PR #35](https://github.com/magiconair/properties/pull/35): Close body always after request | ||||
| 
 | ||||
|    This patch ensures that in `LoadURL` the response body is always closed. | ||||
| 
 | ||||
|    Thanks to [@liubog2008](https://github.com/liubog2008) for the patch. | ||||
| 
 | ||||
| ### [1.8](https://github.com/magiconair/properties/tree/v1.8) - 15 May 2018 | ||||
| 
 | ||||
|  * [PR #26](https://github.com/magiconair/properties/pull/26): Disable expansion during loading | ||||
| 
 | ||||
|    This adds the option to disable property expansion during loading. | ||||
| 
 | ||||
|    Thanks to [@kmala](https://github.com/kmala) for the patch. | ||||
| 
 | ||||
| ### [1.7.6](https://github.com/magiconair/properties/tree/v1.7.6) - 14 Feb 2018 | ||||
| 
 | ||||
|  * [PR #29](https://github.com/magiconair/properties/pull/29): Reworked expansion logic to handle more complex cases. | ||||
| 
 | ||||
|    See PR for an example. | ||||
| 
 | ||||
|    Thanks to [@yobert](https://github.com/yobert) for the fix. | ||||
| 
 | ||||
| ### [1.7.5](https://github.com/magiconair/properties/tree/v1.7.5) - 13 Feb 2018 | ||||
| 
 | ||||
|  * [PR #28](https://github.com/magiconair/properties/pull/28): Support duplicate expansions in the same value | ||||
| 
 | ||||
|    Values which expand the same key multiple times (e.g. `key=${a} ${a}`) will no longer fail | ||||
|    with a `circular reference error`. | ||||
| 
 | ||||
|    Thanks to [@yobert](https://github.com/yobert) for the fix. | ||||
| 
 | ||||
| ### [1.7.4](https://github.com/magiconair/properties/tree/v1.7.4) - 31 Oct 2017 | ||||
| 
 | ||||
|  * [Issue #23](https://github.com/magiconair/properties/issues/23): Ignore blank lines with whitespaces | ||||
| 
 | ||||
|  * [PR #24](https://github.com/magiconair/properties/pull/24): Update keys when DisableExpansion is enabled | ||||
| 
 | ||||
|    Thanks to [@mgurov](https://github.com/mgurov) for the fix. | ||||
| 
 | ||||
| ### [1.7.3](https://github.com/magiconair/properties/tree/v1.7.3) - 10 Jul 2017 | ||||
| 
 | ||||
|  * [Issue #17](https://github.com/magiconair/properties/issues/17): Add [SetValue()](http://godoc.org/github.com/magiconair/properties#Properties.SetValue) method to set values generically | ||||
|  * [Issue #22](https://github.com/magiconair/properties/issues/22): Add [LoadMap()](http://godoc.org/github.com/magiconair/properties#LoadMap) function to load properties from a string map | ||||
| 
 | ||||
| ### [1.7.2](https://github.com/magiconair/properties/tree/v1.7.2) - 20 Mar 2017 | ||||
| 
 | ||||
|  * [Issue #15](https://github.com/magiconair/properties/issues/15): Drop gocheck dependency | ||||
|  * [PR #21](https://github.com/magiconair/properties/pull/21): Add [Map()](http://godoc.org/github.com/magiconair/properties#Properties.Map) and [FilterFunc()](http://godoc.org/github.com/magiconair/properties#Properties.FilterFunc) | ||||
| 
 | ||||
| ### [1.7.1](https://github.com/magiconair/properties/tree/v1.7.1) - 13 Jan 2017 | ||||
| 
 | ||||
|  * [Issue #14](https://github.com/magiconair/properties/issues/14): Decouple TestLoadExpandedFile from `$USER` | ||||
|  * [PR #12](https://github.com/magiconair/properties/pull/12): Load from files and URLs | ||||
|  * [PR #16](https://github.com/magiconair/properties/pull/16): Keep gofmt happy | ||||
|  * [PR #18](https://github.com/magiconair/properties/pull/18): Fix Delete() function | ||||
| 
 | ||||
| ### [1.7.0](https://github.com/magiconair/properties/tree/v1.7.0) - 20 Mar 2016 | ||||
| 
 | ||||
|  * [Issue #10](https://github.com/magiconair/properties/issues/10): Add [LoadURL,LoadURLs,MustLoadURL,MustLoadURLs](http://godoc.org/github.com/magiconair/properties#LoadURL) method to load properties from a URL. | ||||
|  * [Issue #11](https://github.com/magiconair/properties/issues/11): Add [LoadString,MustLoadString](http://godoc.org/github.com/magiconair/properties#LoadString) method to load properties from an UTF8 string. | ||||
|  * [PR #8](https://github.com/magiconair/properties/pull/8): Add [MustFlag](http://godoc.org/github.com/magiconair/properties#Properties.MustFlag) method to provide overrides via command line flags. (@pascaldekloe) | ||||
| 
 | ||||
| ### [1.6.0](https://github.com/magiconair/properties/tree/v1.6.0) - 11 Dec 2015 | ||||
| 
 | ||||
|  * Add [Decode](http://godoc.org/github.com/magiconair/properties#Properties.Decode) method to populate struct from properties via tags. | ||||
| 
 | ||||
| ### [1.5.6](https://github.com/magiconair/properties/tree/v1.5.6) - 18 Oct 2015 | ||||
| 
 | ||||
|  * Vendored in gopkg.in/check.v1 | ||||
| 
 | ||||
| ### [1.5.5](https://github.com/magiconair/properties/tree/v1.5.5) - 31 Jul 2015 | ||||
| 
 | ||||
|  * [PR #6](https://github.com/magiconair/properties/pull/6): Add [Delete](http://godoc.org/github.com/magiconair/properties#Properties.Delete) method to remove keys including comments. (@gerbenjacobs) | ||||
| 
 | ||||
| ### [1.5.4](https://github.com/magiconair/properties/tree/v1.5.4) - 23 Jun 2015 | ||||
| 
 | ||||
|  * [Issue #5](https://github.com/magiconair/properties/issues/5): Allow disabling of property expansion [DisableExpansion](http://godoc.org/github.com/magiconair/properties#Properties.DisableExpansion). When property expansion is disabled Properties become a simple key/value store and don't check for circular references. | ||||
| 
 | ||||
| ### [1.5.3](https://github.com/magiconair/properties/tree/v1.5.3) - 02 Jun 2015 | ||||
| 
 | ||||
|  * [Issue #4](https://github.com/magiconair/properties/issues/4): Maintain key order in [Filter()](http://godoc.org/github.com/magiconair/properties#Properties.Filter), [FilterPrefix()](http://godoc.org/github.com/magiconair/properties#Properties.FilterPrefix) and [FilterRegexp()](http://godoc.org/github.com/magiconair/properties#Properties.FilterRegexp) | ||||
| 
 | ||||
| ### [1.5.2](https://github.com/magiconair/properties/tree/v1.5.2) - 10 Apr 2015 | ||||
| 
 | ||||
|  * [Issue #3](https://github.com/magiconair/properties/issues/3): Don't print comments in [WriteComment()](http://godoc.org/github.com/magiconair/properties#Properties.WriteComment) if they are all empty | ||||
|  * Add clickable links to README | ||||
| 
 | ||||
| ### [1.5.1](https://github.com/magiconair/properties/tree/v1.5.1) - 08 Dec 2014 | ||||
| 
 | ||||
|  * Added [GetParsedDuration()](http://godoc.org/github.com/magiconair/properties#Properties.GetParsedDuration) and [MustGetParsedDuration()](http://godoc.org/github.com/magiconair/properties#Properties.MustGetParsedDuration) for values specified compatible with | ||||
|    [time.ParseDuration()](http://golang.org/pkg/time/#ParseDuration). | ||||
| 
 | ||||
| ### [1.5.0](https://github.com/magiconair/properties/tree/v1.5.0) - 18 Nov 2014 | ||||
| 
 | ||||
|  * Added support for single and multi-line comments (reading, writing and updating) | ||||
|  * The order of keys is now preserved | ||||
|  * Calling [Set()](http://godoc.org/github.com/magiconair/properties#Properties.Set) with an empty key now silently ignores the call and does not create a new entry | ||||
|  * Added a [MustSet()](http://godoc.org/github.com/magiconair/properties#Properties.MustSet) method | ||||
|  * Migrated test library from launchpad.net/gocheck to [gopkg.in/check.v1](http://gopkg.in/check.v1) | ||||
| 
 | ||||
| ### [1.4.2](https://github.com/magiconair/properties/tree/v1.4.2) - 15 Nov 2014 | ||||
| 
 | ||||
|  * [Issue #2](https://github.com/magiconair/properties/issues/2): Fixed goroutine leak in parser which created two lexers but cleaned up only one | ||||
| 
 | ||||
| ### [1.4.1](https://github.com/magiconair/properties/tree/v1.4.1) - 13 Nov 2014 | ||||
| 
 | ||||
|  * [Issue #1](https://github.com/magiconair/properties/issues/1): Fixed bug in Keys() method which returned an empty string | ||||
| 
 | ||||
| ### [1.4.0](https://github.com/magiconair/properties/tree/v1.4.0) - 23 Sep 2014 | ||||
| 
 | ||||
|  * Added [Keys()](http://godoc.org/github.com/magiconair/properties#Properties.Keys) to get the keys | ||||
|  * Added [Filter()](http://godoc.org/github.com/magiconair/properties#Properties.Filter), [FilterRegexp()](http://godoc.org/github.com/magiconair/properties#Properties.FilterRegexp) and [FilterPrefix()](http://godoc.org/github.com/magiconair/properties#Properties.FilterPrefix) to get a subset of the properties | ||||
| 
 | ||||
| ### [1.3.0](https://github.com/magiconair/properties/tree/v1.3.0) - 18 Mar 2014 | ||||
| 
 | ||||
| * Added support for time.Duration | ||||
| * Made MustXXX() failure beha[ior configurable (log.Fatal, panic](https://github.com/magiconair/properties/tree/vior configurable (log.Fatal, panic) - custom) | ||||
| * Changed default of MustXXX() failure from panic to log.Fatal | ||||
| 
 | ||||
| ### [1.2.0](https://github.com/magiconair/properties/tree/v1.2.0) - 05 Mar 2014 | ||||
| 
 | ||||
| * Added MustGet... functions | ||||
| * Added support for int and uint with range checks on 32 bit platforms | ||||
| 
 | ||||
| ### [1.1.0](https://github.com/magiconair/properties/tree/v1.1.0) - 20 Jan 2014 | ||||
| 
 | ||||
| * Renamed from goproperties to properties | ||||
| * Added support for expansion of environment vars in | ||||
|   filenames and value expressions | ||||
| * Fixed bug where value expressions were not at the | ||||
|   start of the string | ||||
| 
 | ||||
| ### [1.0.0](https://github.com/magiconair/properties/tree/v1.0.0) - 7 Jan 2014 | ||||
| 
 | ||||
| * Initial release | ||||
							
								
								
									
										24
									
								
								vendor/github.com/magiconair/properties/LICENSE.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/magiconair/properties/LICENSE.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,24 +0,0 @@ | |||
| Copyright (c) 2013-2020, Frank Schroeder | ||||
| 
 | ||||
| All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
|  * Redistributions of source code must retain the above copyright notice, this | ||||
|    list of conditions and the following disclaimer. | ||||
| 
 | ||||
|  * Redistributions in binary form must reproduce the above copyright notice, | ||||
|    this list of conditions and the following disclaimer in the documentation | ||||
|    and/or other materials provided with the distribution. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||||
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||||
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										128
									
								
								vendor/github.com/magiconair/properties/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										128
									
								
								vendor/github.com/magiconair/properties/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,128 +0,0 @@ | |||
| [](https://github.com/magiconair/properties/releases) | ||||
| [](https://travis-ci.org/magiconair/properties) | ||||
| [](https://raw.githubusercontent.com/magiconair/properties/master/LICENSE) | ||||
| [](http://godoc.org/github.com/magiconair/properties) | ||||
| 
 | ||||
| # Overview | ||||
| 
 | ||||
| #### Please run `git pull --tags` to update the tags. See [below](#updated-git-tags) why. | ||||
| 
 | ||||
| properties is a Go library for reading and writing properties files. | ||||
| 
 | ||||
| It supports reading from multiple files or URLs and Spring style recursive | ||||
| property expansion of expressions like `${key}` to their corresponding value. | ||||
| Value expressions can refer to other keys like in `${key}` or to environment | ||||
| variables like in `${USER}`.  Filenames can also contain environment variables | ||||
| like in `/home/${USER}/myapp.properties`. | ||||
| 
 | ||||
| Properties can be decoded into structs, maps, arrays and values through | ||||
| struct tags. | ||||
| 
 | ||||
| Comments and the order of keys are preserved. Comments can be modified | ||||
| and can be written to the output. | ||||
| 
 | ||||
| The properties library supports both ISO-8859-1 and UTF-8 encoded data. | ||||
| 
 | ||||
| Starting from version 1.3.0 the behavior of the MustXXX() functions is | ||||
| configurable by providing a custom `ErrorHandler` function. The default has | ||||
| changed from `panic` to `log.Fatal` but this is configurable and custom | ||||
| error handling functions can be provided. See the package documentation for | ||||
| details. | ||||
| 
 | ||||
| Read the full documentation on [](http://godoc.org/github.com/magiconair/properties) | ||||
| 
 | ||||
| ## Getting Started | ||||
| 
 | ||||
| ```go | ||||
| import ( | ||||
| 	"flag" | ||||
| 	"github.com/magiconair/properties" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	// init from a file | ||||
| 	p := properties.MustLoadFile("${HOME}/config.properties", properties.UTF8) | ||||
| 
 | ||||
| 	// or multiple files | ||||
| 	p = properties.MustLoadFiles([]string{ | ||||
| 			"${HOME}/config.properties", | ||||
| 			"${HOME}/config-${USER}.properties", | ||||
| 		}, properties.UTF8, true) | ||||
| 
 | ||||
| 	// or from a map | ||||
| 	p = properties.LoadMap(map[string]string{"key": "value", "abc": "def"}) | ||||
| 
 | ||||
| 	// or from a string | ||||
| 	p = properties.MustLoadString("key=value\nabc=def") | ||||
| 
 | ||||
| 	// or from a URL | ||||
| 	p = properties.MustLoadURL("http://host/path") | ||||
| 
 | ||||
| 	// or from multiple URLs | ||||
| 	p = properties.MustLoadURL([]string{ | ||||
| 			"http://host/config", | ||||
| 			"http://host/config-${USER}", | ||||
| 		}, true) | ||||
| 
 | ||||
| 	// or from flags | ||||
| 	p.MustFlag(flag.CommandLine) | ||||
| 
 | ||||
| 	// get values through getters | ||||
| 	host := p.MustGetString("host") | ||||
| 	port := p.GetInt("port", 8080) | ||||
| 
 | ||||
| 	// or through Decode | ||||
| 	type Config struct { | ||||
| 		Host    string        `properties:"host"` | ||||
| 		Port    int           `properties:"port,default=9000"` | ||||
| 		Accept  []string      `properties:"accept,default=image/png;image;gif"` | ||||
| 		Timeout time.Duration `properties:"timeout,default=5s"` | ||||
| 	} | ||||
| 	var cfg Config | ||||
| 	if err := p.Decode(&cfg); err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
| ## Installation and Upgrade | ||||
| 
 | ||||
| ``` | ||||
| $ go get -u github.com/magiconair/properties | ||||
| ``` | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| 2 clause BSD license. See [LICENSE](https://github.com/magiconair/properties/blob/master/LICENSE) file for details. | ||||
| 
 | ||||
| ## ToDo | ||||
| 
 | ||||
| * Dump contents with passwords and secrets obscured | ||||
| 
 | ||||
| ## Updated Git tags | ||||
| 
 | ||||
| #### 13 Feb 2018 | ||||
| 
 | ||||
| I realized that all of the git tags I had pushed before v1.7.5 were lightweight tags | ||||
| and I've only recently learned that this doesn't play well with `git describe` 😞 | ||||
| 
 | ||||
| I have replaced all lightweight tags with signed tags using this script which should | ||||
| retain the commit date, name and email address. Please run `git pull --tags` to update them. | ||||
| 
 | ||||
| Worst case you have to reclone the repo. | ||||
| 
 | ||||
| ```shell | ||||
| #!/bin/bash | ||||
| tag=$1 | ||||
| echo "Updating $tag" | ||||
| date=$(git show ${tag}^0 --format=%aD | head -1) | ||||
| email=$(git show ${tag}^0 --format=%aE | head -1) | ||||
| name=$(git show ${tag}^0 --format=%aN | head -1) | ||||
| GIT_COMMITTER_DATE="$date" GIT_COMMITTER_NAME="$name" GIT_COMMITTER_EMAIL="$email" git tag -s -f ${tag} ${tag}^0 -m ${tag} | ||||
| ``` | ||||
| 
 | ||||
| I apologize for the inconvenience. | ||||
| 
 | ||||
| Frank | ||||
| 
 | ||||
							
								
								
									
										289
									
								
								vendor/github.com/magiconair/properties/decode.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										289
									
								
								vendor/github.com/magiconair/properties/decode.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,289 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // Decode assigns property values to exported fields of a struct. | ||||
| // | ||||
| // Decode traverses v recursively and returns an error if a value cannot be | ||||
| // converted to the field type or a required value is missing for a field. | ||||
| // | ||||
| // The following type dependent decodings are used: | ||||
| // | ||||
| // String, boolean, numeric fields have the value of the property key assigned. | ||||
| // The property key name is the name of the field. A different key and a default | ||||
| // value can be set in the field's tag. Fields without default value are | ||||
| // required. If the value cannot be converted to the field type an error is | ||||
| // returned. | ||||
| // | ||||
| // time.Duration fields have the result of time.ParseDuration() assigned. | ||||
| // | ||||
| // time.Time fields have the vaule of time.Parse() assigned. The default layout | ||||
| // is time.RFC3339 but can be set in the field's tag. | ||||
| // | ||||
| // Arrays and slices of string, boolean, numeric, time.Duration and time.Time | ||||
| // fields have the value interpreted as a comma separated list of values. The | ||||
| // individual values are trimmed of whitespace and empty values are ignored. A | ||||
| // default value can be provided as a semicolon separated list in the field's | ||||
| // tag. | ||||
| // | ||||
| // Struct fields are decoded recursively using the field name plus "." as | ||||
| // prefix. The prefix (without dot) can be overridden in the field's tag. | ||||
| // Default values are not supported in the field's tag. Specify them on the | ||||
| // fields of the inner struct instead. | ||||
| // | ||||
| // Map fields must have a key of type string and are decoded recursively by | ||||
| // using the field's name plus ".' as prefix and the next element of the key | ||||
| // name as map key. The prefix (without dot) can be overridden in the field's | ||||
| // tag. Default values are not supported. | ||||
| // | ||||
| // Examples: | ||||
| // | ||||
| //	// Field is ignored. | ||||
| //	Field int `properties:"-"` | ||||
| // | ||||
| //	// Field is assigned value of 'Field'. | ||||
| //	Field int | ||||
| // | ||||
| //	// Field is assigned value of 'myName'. | ||||
| //	Field int `properties:"myName"` | ||||
| // | ||||
| //	// Field is assigned value of key 'myName' and has a default | ||||
| //	// value 15 if the key does not exist. | ||||
| //	Field int `properties:"myName,default=15"` | ||||
| // | ||||
| //	// Field is assigned value of key 'Field' and has a default | ||||
| //	// value 15 if the key does not exist. | ||||
| //	Field int `properties:",default=15"` | ||||
| // | ||||
| //	// Field is assigned value of key 'date' and the date | ||||
| //	// is in format 2006-01-02 | ||||
| //	Field time.Time `properties:"date,layout=2006-01-02"` | ||||
| // | ||||
| //	// Field is assigned the non-empty and whitespace trimmed | ||||
| //	// values of key 'Field' split by commas. | ||||
| //	Field []string | ||||
| // | ||||
| //	// Field is assigned the non-empty and whitespace trimmed | ||||
| //	// values of key 'Field' split by commas and has a default | ||||
| //	// value ["a", "b", "c"] if the key does not exist. | ||||
| //	Field []string `properties:",default=a;b;c"` | ||||
| // | ||||
| //	// Field is decoded recursively with "Field." as key prefix. | ||||
| //	Field SomeStruct | ||||
| // | ||||
| //	// Field is decoded recursively with "myName." as key prefix. | ||||
| //	Field SomeStruct `properties:"myName"` | ||||
| // | ||||
| //	// Field is decoded recursively with "Field." as key prefix | ||||
| //	// and the next dotted element of the key as map key. | ||||
| //	Field map[string]string | ||||
| // | ||||
| //	// Field is decoded recursively with "myName." as key prefix | ||||
| //	// and the next dotted element of the key as map key. | ||||
| //	Field map[string]string `properties:"myName"` | ||||
| func (p *Properties) Decode(x interface{}) error { | ||||
| 	t, v := reflect.TypeOf(x), reflect.ValueOf(x) | ||||
| 	if t.Kind() != reflect.Ptr || v.Elem().Type().Kind() != reflect.Struct { | ||||
| 		return fmt.Errorf("not a pointer to struct: %s", t) | ||||
| 	} | ||||
| 	if err := dec(p, "", nil, nil, v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func dec(p *Properties, key string, def *string, opts map[string]string, v reflect.Value) error { | ||||
| 	t := v.Type() | ||||
| 
 | ||||
| 	// value returns the property value for key or the default if provided. | ||||
| 	value := func() (string, error) { | ||||
| 		if val, ok := p.Get(key); ok { | ||||
| 			return val, nil | ||||
| 		} | ||||
| 		if def != nil { | ||||
| 			return *def, nil | ||||
| 		} | ||||
| 		return "", fmt.Errorf("missing required key %s", key) | ||||
| 	} | ||||
| 
 | ||||
| 	// conv converts a string to a value of the given type. | ||||
| 	conv := func(s string, t reflect.Type) (val reflect.Value, err error) { | ||||
| 		var v interface{} | ||||
| 
 | ||||
| 		switch { | ||||
| 		case isDuration(t): | ||||
| 			v, err = time.ParseDuration(s) | ||||
| 
 | ||||
| 		case isTime(t): | ||||
| 			layout := opts["layout"] | ||||
| 			if layout == "" { | ||||
| 				layout = time.RFC3339 | ||||
| 			} | ||||
| 			v, err = time.Parse(layout, s) | ||||
| 
 | ||||
| 		case isBool(t): | ||||
| 			v, err = boolVal(s), nil | ||||
| 
 | ||||
| 		case isString(t): | ||||
| 			v, err = s, nil | ||||
| 
 | ||||
| 		case isFloat(t): | ||||
| 			v, err = strconv.ParseFloat(s, 64) | ||||
| 
 | ||||
| 		case isInt(t): | ||||
| 			v, err = strconv.ParseInt(s, 10, 64) | ||||
| 
 | ||||
| 		case isUint(t): | ||||
| 			v, err = strconv.ParseUint(s, 10, 64) | ||||
| 
 | ||||
| 		default: | ||||
| 			return reflect.Zero(t), fmt.Errorf("unsupported type %s", t) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return reflect.Zero(t), err | ||||
| 		} | ||||
| 		return reflect.ValueOf(v).Convert(t), nil | ||||
| 	} | ||||
| 
 | ||||
| 	// keydef returns the property key and the default value based on the | ||||
| 	// name of the struct field and the options in the tag. | ||||
| 	keydef := func(f reflect.StructField) (string, *string, map[string]string) { | ||||
| 		_key, _opts := parseTag(f.Tag.Get("properties")) | ||||
| 
 | ||||
| 		var _def *string | ||||
| 		if d, ok := _opts["default"]; ok { | ||||
| 			_def = &d | ||||
| 		} | ||||
| 		if _key != "" { | ||||
| 			return _key, _def, _opts | ||||
| 		} | ||||
| 		return f.Name, _def, _opts | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case isDuration(t) || isTime(t) || isBool(t) || isString(t) || isFloat(t) || isInt(t) || isUint(t): | ||||
| 		s, err := value() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		val, err := conv(s, t) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		v.Set(val) | ||||
| 
 | ||||
| 	case isPtr(t): | ||||
| 		return dec(p, key, def, opts, v.Elem()) | ||||
| 
 | ||||
| 	case isStruct(t): | ||||
| 		for i := 0; i < v.NumField(); i++ { | ||||
| 			fv := v.Field(i) | ||||
| 			fk, def, opts := keydef(t.Field(i)) | ||||
| 			if !fv.CanSet() { | ||||
| 				return fmt.Errorf("cannot set %s", t.Field(i).Name) | ||||
| 			} | ||||
| 			if fk == "-" { | ||||
| 				continue | ||||
| 			} | ||||
| 			if key != "" { | ||||
| 				fk = key + "." + fk | ||||
| 			} | ||||
| 			if err := dec(p, fk, def, opts, fv); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 
 | ||||
| 	case isArray(t): | ||||
| 		val, err := value() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		vals := split(val, ";") | ||||
| 		a := reflect.MakeSlice(t, 0, len(vals)) | ||||
| 		for _, s := range vals { | ||||
| 			val, err := conv(s, t.Elem()) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			a = reflect.Append(a, val) | ||||
| 		} | ||||
| 		v.Set(a) | ||||
| 
 | ||||
| 	case isMap(t): | ||||
| 		valT := t.Elem() | ||||
| 		m := reflect.MakeMap(t) | ||||
| 		for postfix := range p.FilterStripPrefix(key + ".").m { | ||||
| 			pp := strings.SplitN(postfix, ".", 2) | ||||
| 			mk, mv := pp[0], reflect.New(valT) | ||||
| 			if err := dec(p, key+"."+mk, nil, nil, mv); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			m.SetMapIndex(reflect.ValueOf(mk), mv.Elem()) | ||||
| 		} | ||||
| 		v.Set(m) | ||||
| 
 | ||||
| 	default: | ||||
| 		return fmt.Errorf("unsupported type %s", t) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // split splits a string on sep, trims whitespace of elements | ||||
| // and omits empty elements | ||||
| func split(s string, sep string) []string { | ||||
| 	var a []string | ||||
| 	for _, v := range strings.Split(s, sep) { | ||||
| 		if v = strings.TrimSpace(v); v != "" { | ||||
| 			a = append(a, v) | ||||
| 		} | ||||
| 	} | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| // parseTag parses a "key,k=v,k=v,..." | ||||
| func parseTag(tag string) (key string, opts map[string]string) { | ||||
| 	opts = map[string]string{} | ||||
| 	for i, s := range strings.Split(tag, ",") { | ||||
| 		if i == 0 { | ||||
| 			key = s | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		pp := strings.SplitN(s, "=", 2) | ||||
| 		if len(pp) == 1 { | ||||
| 			opts[pp[0]] = "" | ||||
| 		} else { | ||||
| 			opts[pp[0]] = pp[1] | ||||
| 		} | ||||
| 	} | ||||
| 	return key, opts | ||||
| } | ||||
| 
 | ||||
| func isArray(t reflect.Type) bool    { return t.Kind() == reflect.Array || t.Kind() == reflect.Slice } | ||||
| func isBool(t reflect.Type) bool     { return t.Kind() == reflect.Bool } | ||||
| func isDuration(t reflect.Type) bool { return t == reflect.TypeOf(time.Second) } | ||||
| func isMap(t reflect.Type) bool      { return t.Kind() == reflect.Map } | ||||
| func isPtr(t reflect.Type) bool      { return t.Kind() == reflect.Ptr } | ||||
| func isString(t reflect.Type) bool   { return t.Kind() == reflect.String } | ||||
| func isStruct(t reflect.Type) bool   { return t.Kind() == reflect.Struct } | ||||
| func isTime(t reflect.Type) bool     { return t == reflect.TypeOf(time.Time{}) } | ||||
| func isFloat(t reflect.Type) bool { | ||||
| 	return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64 | ||||
| } | ||||
| func isInt(t reflect.Type) bool { | ||||
| 	return t.Kind() == reflect.Int || t.Kind() == reflect.Int8 || t.Kind() == reflect.Int16 || t.Kind() == reflect.Int32 || t.Kind() == reflect.Int64 | ||||
| } | ||||
| func isUint(t reflect.Type) bool { | ||||
| 	return t.Kind() == reflect.Uint || t.Kind() == reflect.Uint8 || t.Kind() == reflect.Uint16 || t.Kind() == reflect.Uint32 || t.Kind() == reflect.Uint64 | ||||
| } | ||||
							
								
								
									
										155
									
								
								vendor/github.com/magiconair/properties/doc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										155
									
								
								vendor/github.com/magiconair/properties/doc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,155 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // Package properties provides functions for reading and writing | ||||
| // ISO-8859-1 and UTF-8 encoded .properties files and has | ||||
| // support for recursive property expansion. | ||||
| // | ||||
| // Java properties files are ISO-8859-1 encoded and use Unicode | ||||
| // literals for characters outside the ISO character set. Unicode | ||||
| // literals can be used in UTF-8 encoded properties files but | ||||
| // aren't necessary. | ||||
| // | ||||
| // To load a single properties file use MustLoadFile(): | ||||
| // | ||||
| //	p := properties.MustLoadFile(filename, properties.UTF8) | ||||
| // | ||||
| // To load multiple properties files use MustLoadFiles() | ||||
| // which loads the files in the given order and merges the | ||||
| // result. Missing properties files can be ignored if the | ||||
| // 'ignoreMissing' flag is set to true. | ||||
| // | ||||
| // Filenames can contain environment variables which are expanded | ||||
| // before loading. | ||||
| // | ||||
| //	f1 := "/etc/myapp/myapp.conf" | ||||
| //	f2 := "/home/${USER}/myapp.conf" | ||||
| //	p := MustLoadFiles([]string{f1, f2}, properties.UTF8, true) | ||||
| // | ||||
| // All of the different key/value delimiters ' ', ':' and '=' are | ||||
| // supported as well as the comment characters '!' and '#' and | ||||
| // multi-line values. | ||||
| // | ||||
| //	! this is a comment | ||||
| //	# and so is this | ||||
| // | ||||
| //	# the following expressions are equal | ||||
| //	key value | ||||
| //	key=value | ||||
| //	key:value | ||||
| //	key = value | ||||
| //	key : value | ||||
| //	key = val\ | ||||
| //	      ue | ||||
| // | ||||
| // Properties stores all comments preceding a key and provides | ||||
| // GetComments() and SetComments() methods to retrieve and | ||||
| // update them. The convenience functions GetComment() and | ||||
| // SetComment() allow access to the last comment. The | ||||
| // WriteComment() method writes properties files including | ||||
| // the comments and with the keys in the original order. | ||||
| // This can be used for sanitizing properties files. | ||||
| // | ||||
| // Property expansion is recursive and circular references | ||||
| // and malformed expressions are not allowed and cause an | ||||
| // error. Expansion of environment variables is supported. | ||||
| // | ||||
| //	# standard property | ||||
| //	key = value | ||||
| // | ||||
| //	# property expansion: key2 = value | ||||
| //	key2 = ${key} | ||||
| // | ||||
| //	# recursive expansion: key3 = value | ||||
| //	key3 = ${key2} | ||||
| // | ||||
| //	# circular reference (error) | ||||
| //	key = ${key} | ||||
| // | ||||
| //	# malformed expression (error) | ||||
| //	key = ${ke | ||||
| // | ||||
| //	# refers to the users' home dir | ||||
| //	home = ${HOME} | ||||
| // | ||||
| //	# local key takes precedence over env var: u = foo | ||||
| //	USER = foo | ||||
| //	u = ${USER} | ||||
| // | ||||
| // The default property expansion format is ${key} but can be | ||||
| // changed by setting different pre- and postfix values on the | ||||
| // Properties object. | ||||
| // | ||||
| //	p := properties.NewProperties() | ||||
| //	p.Prefix = "#[" | ||||
| //	p.Postfix = "]#" | ||||
| // | ||||
| // Properties provides convenience functions for getting typed | ||||
| // values with default values if the key does not exist or the | ||||
| // type conversion failed. | ||||
| // | ||||
| //	# Returns true if the value is either "1", "on", "yes" or "true" | ||||
| //	# Returns false for every other value and the default value if | ||||
| //	# the key does not exist. | ||||
| //	v = p.GetBool("key", false) | ||||
| // | ||||
| //	# Returns the value if the key exists and the format conversion | ||||
| //	# was successful. Otherwise, the default value is returned. | ||||
| //	v = p.GetInt64("key", 999) | ||||
| //	v = p.GetUint64("key", 999) | ||||
| //	v = p.GetFloat64("key", 123.0) | ||||
| //	v = p.GetString("key", "def") | ||||
| //	v = p.GetDuration("key", 999) | ||||
| // | ||||
| // As an alternative properties may be applied with the standard | ||||
| // library's flag implementation at any time. | ||||
| // | ||||
| //	# Standard configuration | ||||
| //	v = flag.Int("key", 999, "help message") | ||||
| //	flag.Parse() | ||||
| // | ||||
| //	# Merge p into the flag set | ||||
| //	p.MustFlag(flag.CommandLine) | ||||
| // | ||||
| // Properties provides several MustXXX() convenience functions | ||||
| // which will terminate the app if an error occurs. The behavior | ||||
| // of the failure is configurable and the default is to call | ||||
| // log.Fatal(err). To have the MustXXX() functions panic instead | ||||
| // of logging the error set a different ErrorHandler before | ||||
| // you use the Properties package. | ||||
| // | ||||
| //	properties.ErrorHandler = properties.PanicHandler | ||||
| // | ||||
| //	# Will panic instead of logging an error | ||||
| //	p := properties.MustLoadFile("config.properties") | ||||
| // | ||||
| // You can also provide your own ErrorHandler function. The only requirement | ||||
| // is that the error handler function must exit after handling the error. | ||||
| // | ||||
| //	  properties.ErrorHandler = func(err error) { | ||||
| //		     fmt.Println(err) | ||||
| //	      os.Exit(1) | ||||
| //	  } | ||||
| // | ||||
| //	  # Will write to stdout and then exit | ||||
| //	  p := properties.MustLoadFile("config.properties") | ||||
| // | ||||
| // Properties can also be loaded into a struct via the `Decode` | ||||
| // method, e.g. | ||||
| // | ||||
| //	type S struct { | ||||
| //	    A string        `properties:"a,default=foo"` | ||||
| //	    D time.Duration `properties:"timeout,default=5s"` | ||||
| //	    E time.Time     `properties:"expires,layout=2006-01-02,default=2015-01-01"` | ||||
| //	} | ||||
| // | ||||
| // See `Decode()` method for the full documentation. | ||||
| // | ||||
| // The following documents provide a description of the properties | ||||
| // file format. | ||||
| // | ||||
| // http://en.wikipedia.org/wiki/.properties | ||||
| // | ||||
| // http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29 | ||||
| package properties | ||||
							
								
								
									
										35
									
								
								vendor/github.com/magiconair/properties/integrate.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/magiconair/properties/integrate.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,35 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| import "flag" | ||||
| 
 | ||||
| // MustFlag sets flags that are skipped by dst.Parse when p contains | ||||
| // the respective key for flag.Flag.Name. | ||||
| // | ||||
| // It's use is recommended with command line arguments as in: | ||||
| // | ||||
| //	flag.Parse() | ||||
| //	p.MustFlag(flag.CommandLine) | ||||
| func (p *Properties) MustFlag(dst *flag.FlagSet) { | ||||
| 	m := make(map[string]*flag.Flag) | ||||
| 	dst.VisitAll(func(f *flag.Flag) { | ||||
| 		m[f.Name] = f | ||||
| 	}) | ||||
| 	dst.Visit(func(f *flag.Flag) { | ||||
| 		delete(m, f.Name) // overridden | ||||
| 	}) | ||||
| 
 | ||||
| 	for name, f := range m { | ||||
| 		v, ok := p.Get(name) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if err := f.Value.Set(v); err != nil { | ||||
| 			ErrorHandler(err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										395
									
								
								vendor/github.com/magiconair/properties/lex.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										395
									
								
								vendor/github.com/magiconair/properties/lex.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,395 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| // | ||||
| // Parts of the lexer are from the template/text/parser package | ||||
| // For these parts the following applies: | ||||
| // | ||||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file of the go 1.2 | ||||
| // distribution. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
| 
 | ||||
| // item represents a token or text string returned from the scanner. | ||||
| type item struct { | ||||
| 	typ itemType // The type of this item. | ||||
| 	pos int      // The starting position, in bytes, of this item in the input string. | ||||
| 	val string   // The value of this item. | ||||
| } | ||||
| 
 | ||||
| func (i item) String() string { | ||||
| 	switch { | ||||
| 	case i.typ == itemEOF: | ||||
| 		return "EOF" | ||||
| 	case i.typ == itemError: | ||||
| 		return i.val | ||||
| 	case len(i.val) > 10: | ||||
| 		return fmt.Sprintf("%.10q...", i.val) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%q", i.val) | ||||
| } | ||||
| 
 | ||||
| // itemType identifies the type of lex items. | ||||
| type itemType int | ||||
| 
 | ||||
| const ( | ||||
| 	itemError itemType = iota // error occurred; value is text of error | ||||
| 	itemEOF | ||||
| 	itemKey     // a key | ||||
| 	itemValue   // a value | ||||
| 	itemComment // a comment | ||||
| ) | ||||
| 
 | ||||
| // defines a constant for EOF | ||||
| const eof = -1 | ||||
| 
 | ||||
| // permitted whitespace characters space, FF and TAB | ||||
| const whitespace = " \f\t" | ||||
| 
 | ||||
| // stateFn represents the state of the scanner as a function that returns the next state. | ||||
| type stateFn func(*lexer) stateFn | ||||
| 
 | ||||
| // lexer holds the state of the scanner. | ||||
| type lexer struct { | ||||
| 	input   string    // the string being scanned | ||||
| 	state   stateFn   // the next lexing function to enter | ||||
| 	pos     int       // current position in the input | ||||
| 	start   int       // start position of this item | ||||
| 	width   int       // width of last rune read from input | ||||
| 	lastPos int       // position of most recent item returned by nextItem | ||||
| 	runes   []rune    // scanned runes for this item | ||||
| 	items   chan item // channel of scanned items | ||||
| } | ||||
| 
 | ||||
| // next returns the next rune in the input. | ||||
| func (l *lexer) next() rune { | ||||
| 	if l.pos >= len(l.input) { | ||||
| 		l.width = 0 | ||||
| 		return eof | ||||
| 	} | ||||
| 	r, w := utf8.DecodeRuneInString(l.input[l.pos:]) | ||||
| 	l.width = w | ||||
| 	l.pos += l.width | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| // peek returns but does not consume the next rune in the input. | ||||
| func (l *lexer) peek() rune { | ||||
| 	r := l.next() | ||||
| 	l.backup() | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| // backup steps back one rune. Can only be called once per call of next. | ||||
| func (l *lexer) backup() { | ||||
| 	l.pos -= l.width | ||||
| } | ||||
| 
 | ||||
| // emit passes an item back to the client. | ||||
| func (l *lexer) emit(t itemType) { | ||||
| 	i := item{t, l.start, string(l.runes)} | ||||
| 	l.items <- i | ||||
| 	l.start = l.pos | ||||
| 	l.runes = l.runes[:0] | ||||
| } | ||||
| 
 | ||||
| // ignore skips over the pending input before this point. | ||||
| func (l *lexer) ignore() { | ||||
| 	l.start = l.pos | ||||
| } | ||||
| 
 | ||||
| // appends the rune to the current value | ||||
| func (l *lexer) appendRune(r rune) { | ||||
| 	l.runes = append(l.runes, r) | ||||
| } | ||||
| 
 | ||||
| // accept consumes the next rune if it's from the valid set. | ||||
| func (l *lexer) accept(valid string) bool { | ||||
| 	if strings.ContainsRune(valid, l.next()) { | ||||
| 		return true | ||||
| 	} | ||||
| 	l.backup() | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // acceptRun consumes a run of runes from the valid set. | ||||
| func (l *lexer) acceptRun(valid string) { | ||||
| 	for strings.ContainsRune(valid, l.next()) { | ||||
| 	} | ||||
| 	l.backup() | ||||
| } | ||||
| 
 | ||||
| // lineNumber reports which line we're on, based on the position of | ||||
| // the previous item returned by nextItem. Doing it this way | ||||
| // means we don't have to worry about peek double counting. | ||||
| func (l *lexer) lineNumber() int { | ||||
| 	return 1 + strings.Count(l.input[:l.lastPos], "\n") | ||||
| } | ||||
| 
 | ||||
| // errorf returns an error token and terminates the scan by passing | ||||
| // back a nil pointer that will be the next state, terminating l.nextItem. | ||||
| func (l *lexer) errorf(format string, args ...interface{}) stateFn { | ||||
| 	l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // nextItem returns the next item from the input. | ||||
| func (l *lexer) nextItem() item { | ||||
| 	i := <-l.items | ||||
| 	l.lastPos = i.pos | ||||
| 	return i | ||||
| } | ||||
| 
 | ||||
| // lex creates a new scanner for the input string. | ||||
| func lex(input string) *lexer { | ||||
| 	l := &lexer{ | ||||
| 		input: input, | ||||
| 		items: make(chan item), | ||||
| 		runes: make([]rune, 0, 32), | ||||
| 	} | ||||
| 	go l.run() | ||||
| 	return l | ||||
| } | ||||
| 
 | ||||
| // run runs the state machine for the lexer. | ||||
| func (l *lexer) run() { | ||||
| 	for l.state = lexBeforeKey(l); l.state != nil; { | ||||
| 		l.state = l.state(l) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // state functions | ||||
| 
 | ||||
| // lexBeforeKey scans until a key begins. | ||||
| func lexBeforeKey(l *lexer) stateFn { | ||||
| 	switch r := l.next(); { | ||||
| 	case isEOF(r): | ||||
| 		l.emit(itemEOF) | ||||
| 		return nil | ||||
| 
 | ||||
| 	case isEOL(r): | ||||
| 		l.ignore() | ||||
| 		return lexBeforeKey | ||||
| 
 | ||||
| 	case isComment(r): | ||||
| 		return lexComment | ||||
| 
 | ||||
| 	case isWhitespace(r): | ||||
| 		l.ignore() | ||||
| 		return lexBeforeKey | ||||
| 
 | ||||
| 	default: | ||||
| 		l.backup() | ||||
| 		return lexKey | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // lexComment scans a comment line. The comment character has already been scanned. | ||||
| func lexComment(l *lexer) stateFn { | ||||
| 	l.acceptRun(whitespace) | ||||
| 	l.ignore() | ||||
| 	for { | ||||
| 		switch r := l.next(); { | ||||
| 		case isEOF(r): | ||||
| 			l.ignore() | ||||
| 			l.emit(itemEOF) | ||||
| 			return nil | ||||
| 		case isEOL(r): | ||||
| 			l.emit(itemComment) | ||||
| 			return lexBeforeKey | ||||
| 		default: | ||||
| 			l.appendRune(r) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // lexKey scans the key up to a delimiter | ||||
| func lexKey(l *lexer) stateFn { | ||||
| 	var r rune | ||||
| 
 | ||||
| Loop: | ||||
| 	for { | ||||
| 		switch r = l.next(); { | ||||
| 
 | ||||
| 		case isEscape(r): | ||||
| 			err := l.scanEscapeSequence() | ||||
| 			if err != nil { | ||||
| 				return l.errorf(err.Error()) | ||||
| 			} | ||||
| 
 | ||||
| 		case isEndOfKey(r): | ||||
| 			l.backup() | ||||
| 			break Loop | ||||
| 
 | ||||
| 		case isEOF(r): | ||||
| 			break Loop | ||||
| 
 | ||||
| 		default: | ||||
| 			l.appendRune(r) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if len(l.runes) > 0 { | ||||
| 		l.emit(itemKey) | ||||
| 	} | ||||
| 
 | ||||
| 	if isEOF(r) { | ||||
| 		l.emit(itemEOF) | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return lexBeforeValue | ||||
| } | ||||
| 
 | ||||
| // lexBeforeValue scans the delimiter between key and value. | ||||
| // Leading and trailing whitespace is ignored. | ||||
| // We expect to be just after the key. | ||||
| func lexBeforeValue(l *lexer) stateFn { | ||||
| 	l.acceptRun(whitespace) | ||||
| 	l.accept(":=") | ||||
| 	l.acceptRun(whitespace) | ||||
| 	l.ignore() | ||||
| 	return lexValue | ||||
| } | ||||
| 
 | ||||
| // lexValue scans text until the end of the line. We expect to be just after the delimiter. | ||||
| func lexValue(l *lexer) stateFn { | ||||
| 	for { | ||||
| 		switch r := l.next(); { | ||||
| 		case isEscape(r): | ||||
| 			if isEOL(l.peek()) { | ||||
| 				l.next() | ||||
| 				l.acceptRun(whitespace) | ||||
| 			} else { | ||||
| 				err := l.scanEscapeSequence() | ||||
| 				if err != nil { | ||||
| 					return l.errorf(err.Error()) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		case isEOL(r): | ||||
| 			l.emit(itemValue) | ||||
| 			l.ignore() | ||||
| 			return lexBeforeKey | ||||
| 
 | ||||
| 		case isEOF(r): | ||||
| 			l.emit(itemValue) | ||||
| 			l.emit(itemEOF) | ||||
| 			return nil | ||||
| 
 | ||||
| 		default: | ||||
| 			l.appendRune(r) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // scanEscapeSequence scans either one of the escaped characters | ||||
| // or a unicode literal. We expect to be after the escape character. | ||||
| func (l *lexer) scanEscapeSequence() error { | ||||
| 	switch r := l.next(); { | ||||
| 
 | ||||
| 	case isEscapedCharacter(r): | ||||
| 		l.appendRune(decodeEscapedCharacter(r)) | ||||
| 		return nil | ||||
| 
 | ||||
| 	case atUnicodeLiteral(r): | ||||
| 		return l.scanUnicodeLiteral() | ||||
| 
 | ||||
| 	case isEOF(r): | ||||
| 		return fmt.Errorf("premature EOF") | ||||
| 
 | ||||
| 	// silently drop the escape character and append the rune as is | ||||
| 	default: | ||||
| 		l.appendRune(r) | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // scans a unicode literal in the form \uXXXX. We expect to be after the \u. | ||||
| func (l *lexer) scanUnicodeLiteral() error { | ||||
| 	// scan the digits | ||||
| 	d := make([]rune, 4) | ||||
| 	for i := 0; i < 4; i++ { | ||||
| 		d[i] = l.next() | ||||
| 		if d[i] == eof || !strings.ContainsRune("0123456789abcdefABCDEF", d[i]) { | ||||
| 			return fmt.Errorf("invalid unicode literal") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// decode the digits into a rune | ||||
| 	r, err := strconv.ParseInt(string(d), 16, 0) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	l.appendRune(rune(r)) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // decodeEscapedCharacter returns the unescaped rune. We expect to be after the escape character. | ||||
| func decodeEscapedCharacter(r rune) rune { | ||||
| 	switch r { | ||||
| 	case 'f': | ||||
| 		return '\f' | ||||
| 	case 'n': | ||||
| 		return '\n' | ||||
| 	case 'r': | ||||
| 		return '\r' | ||||
| 	case 't': | ||||
| 		return '\t' | ||||
| 	default: | ||||
| 		return r | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // atUnicodeLiteral reports whether we are at a unicode literal. | ||||
| // The escape character has already been consumed. | ||||
| func atUnicodeLiteral(r rune) bool { | ||||
| 	return r == 'u' | ||||
| } | ||||
| 
 | ||||
| // isComment reports whether we are at the start of a comment. | ||||
| func isComment(r rune) bool { | ||||
| 	return r == '#' || r == '!' | ||||
| } | ||||
| 
 | ||||
| // isEndOfKey reports whether the rune terminates the current key. | ||||
| func isEndOfKey(r rune) bool { | ||||
| 	return strings.ContainsRune(" \f\t\r\n:=", r) | ||||
| } | ||||
| 
 | ||||
| // isEOF reports whether we are at EOF. | ||||
| func isEOF(r rune) bool { | ||||
| 	return r == eof | ||||
| } | ||||
| 
 | ||||
| // isEOL reports whether we are at a new line character. | ||||
| func isEOL(r rune) bool { | ||||
| 	return r == '\n' || r == '\r' | ||||
| } | ||||
| 
 | ||||
| // isEscape reports whether the rune is the escape character which | ||||
| // prefixes unicode literals and other escaped characters. | ||||
| func isEscape(r rune) bool { | ||||
| 	return r == '\\' | ||||
| } | ||||
| 
 | ||||
| // isEscapedCharacter reports whether we are at one of the characters that need escaping. | ||||
| // The escape character has already been consumed. | ||||
| func isEscapedCharacter(r rune) bool { | ||||
| 	return strings.ContainsRune(" :=fnrt", r) | ||||
| } | ||||
| 
 | ||||
| // isWhitespace reports whether the rune is a whitespace character. | ||||
| func isWhitespace(r rune) bool { | ||||
| 	return strings.ContainsRune(whitespace, r) | ||||
| } | ||||
							
								
								
									
										293
									
								
								vendor/github.com/magiconair/properties/load.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										293
									
								
								vendor/github.com/magiconair/properties/load.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,293 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // Encoding specifies encoding of the input data. | ||||
| type Encoding uint | ||||
| 
 | ||||
| const ( | ||||
| 	// utf8Default is a private placeholder for the zero value of Encoding to | ||||
| 	// ensure that it has the correct meaning. UTF8 is the default encoding but | ||||
| 	// was assigned a non-zero value which cannot be changed without breaking | ||||
| 	// existing code. Clients should continue to use the public constants. | ||||
| 	utf8Default Encoding = iota | ||||
| 
 | ||||
| 	// UTF8 interprets the input data as UTF-8. | ||||
| 	UTF8 | ||||
| 
 | ||||
| 	// ISO_8859_1 interprets the input data as ISO-8859-1. | ||||
| 	ISO_8859_1 | ||||
| ) | ||||
| 
 | ||||
| type Loader struct { | ||||
| 	// Encoding determines how the data from files and byte buffers | ||||
| 	// is interpreted. For URLs the Content-Type header is used | ||||
| 	// to determine the encoding of the data. | ||||
| 	Encoding Encoding | ||||
| 
 | ||||
| 	// DisableExpansion configures the property expansion of the | ||||
| 	// returned property object. When set to true, the property values | ||||
| 	// will not be expanded and the Property object will not be checked | ||||
| 	// for invalid expansion expressions. | ||||
| 	DisableExpansion bool | ||||
| 
 | ||||
| 	// IgnoreMissing configures whether missing files or URLs which return | ||||
| 	// 404 are reported as errors. When set to true, missing files and 404 | ||||
| 	// status codes are not reported as errors. | ||||
| 	IgnoreMissing bool | ||||
| } | ||||
| 
 | ||||
| // Load reads a buffer into a Properties struct. | ||||
| func (l *Loader) LoadBytes(buf []byte) (*Properties, error) { | ||||
| 	return l.loadBytes(buf, l.Encoding) | ||||
| } | ||||
| 
 | ||||
| // LoadAll reads the content of multiple URLs or files in the given order into | ||||
| // a Properties struct. If IgnoreMissing is true then a 404 status code or | ||||
| // missing file will not be reported as error. Encoding sets the encoding for | ||||
| // files. For the URLs see LoadURL for the Content-Type header and the | ||||
| // encoding. | ||||
| func (l *Loader) LoadAll(names []string) (*Properties, error) { | ||||
| 	all := NewProperties() | ||||
| 	for _, name := range names { | ||||
| 		n, err := expandName(name) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		var p *Properties | ||||
| 		switch { | ||||
| 		case strings.HasPrefix(n, "http://"): | ||||
| 			p, err = l.LoadURL(n) | ||||
| 		case strings.HasPrefix(n, "https://"): | ||||
| 			p, err = l.LoadURL(n) | ||||
| 		default: | ||||
| 			p, err = l.LoadFile(n) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		all.Merge(p) | ||||
| 	} | ||||
| 
 | ||||
| 	all.DisableExpansion = l.DisableExpansion | ||||
| 	if all.DisableExpansion { | ||||
| 		return all, nil | ||||
| 	} | ||||
| 	return all, all.check() | ||||
| } | ||||
| 
 | ||||
| // LoadFile reads a file into a Properties struct. | ||||
| // If IgnoreMissing is true then a missing file will not be | ||||
| // reported as error. | ||||
| func (l *Loader) LoadFile(filename string) (*Properties, error) { | ||||
| 	data, err := ioutil.ReadFile(filename) | ||||
| 	if err != nil { | ||||
| 		if l.IgnoreMissing && os.IsNotExist(err) { | ||||
| 			LogPrintf("properties: %s not found. skipping", filename) | ||||
| 			return NewProperties(), nil | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return l.loadBytes(data, l.Encoding) | ||||
| } | ||||
| 
 | ||||
| // LoadURL reads the content of the URL into a Properties struct. | ||||
| // | ||||
| // The encoding is determined via the Content-Type header which | ||||
| // should be set to 'text/plain'. If the 'charset' parameter is | ||||
| // missing, 'iso-8859-1' or 'latin1' the encoding is set to | ||||
| // ISO-8859-1. If the 'charset' parameter is set to 'utf-8' the | ||||
| // encoding is set to UTF-8. A missing content type header is | ||||
| // interpreted as 'text/plain; charset=utf-8'. | ||||
| func (l *Loader) LoadURL(url string) (*Properties, error) { | ||||
| 	resp, err := http.Get(url) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("properties: error fetching %q. %s", url, err) | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 
 | ||||
| 	if resp.StatusCode == 404 && l.IgnoreMissing { | ||||
| 		LogPrintf("properties: %s returned %d. skipping", url, resp.StatusCode) | ||||
| 		return NewProperties(), nil | ||||
| 	} | ||||
| 
 | ||||
| 	if resp.StatusCode != 200 { | ||||
| 		return nil, fmt.Errorf("properties: %s returned %d", url, resp.StatusCode) | ||||
| 	} | ||||
| 
 | ||||
| 	body, err := ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("properties: %s error reading response. %s", url, err) | ||||
| 	} | ||||
| 
 | ||||
| 	ct := resp.Header.Get("Content-Type") | ||||
| 	ct = strings.Join(strings.Fields(ct), "") | ||||
| 	var enc Encoding | ||||
| 	switch strings.ToLower(ct) { | ||||
| 	case "text/plain", "text/plain;charset=iso-8859-1", "text/plain;charset=latin1": | ||||
| 		enc = ISO_8859_1 | ||||
| 	case "", "text/plain;charset=utf-8": | ||||
| 		enc = UTF8 | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("properties: invalid content type %s", ct) | ||||
| 	} | ||||
| 
 | ||||
| 	return l.loadBytes(body, enc) | ||||
| } | ||||
| 
 | ||||
| func (l *Loader) loadBytes(buf []byte, enc Encoding) (*Properties, error) { | ||||
| 	p, err := parse(convert(buf, enc)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	p.DisableExpansion = l.DisableExpansion | ||||
| 	if p.DisableExpansion { | ||||
| 		return p, nil | ||||
| 	} | ||||
| 	return p, p.check() | ||||
| } | ||||
| 
 | ||||
| // Load reads a buffer into a Properties struct. | ||||
| func Load(buf []byte, enc Encoding) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: enc} | ||||
| 	return l.LoadBytes(buf) | ||||
| } | ||||
| 
 | ||||
| // LoadString reads an UTF8 string into a properties struct. | ||||
| func LoadString(s string) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: UTF8} | ||||
| 	return l.LoadBytes([]byte(s)) | ||||
| } | ||||
| 
 | ||||
| // LoadMap creates a new Properties struct from a string map. | ||||
| func LoadMap(m map[string]string) *Properties { | ||||
| 	p := NewProperties() | ||||
| 	for k, v := range m { | ||||
| 		p.Set(k, v) | ||||
| 	} | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| // LoadFile reads a file into a Properties struct. | ||||
| func LoadFile(filename string, enc Encoding) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: enc} | ||||
| 	return l.LoadAll([]string{filename}) | ||||
| } | ||||
| 
 | ||||
| // LoadFiles reads multiple files in the given order into | ||||
| // a Properties struct. If 'ignoreMissing' is true then | ||||
| // non-existent files will not be reported as error. | ||||
| func LoadFiles(filenames []string, enc Encoding, ignoreMissing bool) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: enc, IgnoreMissing: ignoreMissing} | ||||
| 	return l.LoadAll(filenames) | ||||
| } | ||||
| 
 | ||||
| // LoadURL reads the content of the URL into a Properties struct. | ||||
| // See Loader#LoadURL for details. | ||||
| func LoadURL(url string) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: UTF8} | ||||
| 	return l.LoadAll([]string{url}) | ||||
| } | ||||
| 
 | ||||
| // LoadURLs reads the content of multiple URLs in the given order into a | ||||
| // Properties struct. If IgnoreMissing is true then a 404 status code will | ||||
| // not be reported as error. See Loader#LoadURL for the Content-Type header | ||||
| // and the encoding. | ||||
| func LoadURLs(urls []string, ignoreMissing bool) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: UTF8, IgnoreMissing: ignoreMissing} | ||||
| 	return l.LoadAll(urls) | ||||
| } | ||||
| 
 | ||||
| // LoadAll reads the content of multiple URLs or files in the given order into a | ||||
| // Properties struct. If 'ignoreMissing' is true then a 404 status code or missing file will | ||||
| // not be reported as error. Encoding sets the encoding for files. For the URLs please see | ||||
| // LoadURL for the Content-Type header and the encoding. | ||||
| func LoadAll(names []string, enc Encoding, ignoreMissing bool) (*Properties, error) { | ||||
| 	l := &Loader{Encoding: enc, IgnoreMissing: ignoreMissing} | ||||
| 	return l.LoadAll(names) | ||||
| } | ||||
| 
 | ||||
| // MustLoadString reads an UTF8 string into a Properties struct and | ||||
| // panics on error. | ||||
| func MustLoadString(s string) *Properties { | ||||
| 	return must(LoadString(s)) | ||||
| } | ||||
| 
 | ||||
| // MustLoadFile reads a file into a Properties struct and | ||||
| // panics on error. | ||||
| func MustLoadFile(filename string, enc Encoding) *Properties { | ||||
| 	return must(LoadFile(filename, enc)) | ||||
| } | ||||
| 
 | ||||
| // MustLoadFiles reads multiple files in the given order into | ||||
| // a Properties struct and panics on error. If 'ignoreMissing' | ||||
| // is true then non-existent files will not be reported as error. | ||||
| func MustLoadFiles(filenames []string, enc Encoding, ignoreMissing bool) *Properties { | ||||
| 	return must(LoadFiles(filenames, enc, ignoreMissing)) | ||||
| } | ||||
| 
 | ||||
| // MustLoadURL reads the content of a URL into a Properties struct and | ||||
| // panics on error. | ||||
| func MustLoadURL(url string) *Properties { | ||||
| 	return must(LoadURL(url)) | ||||
| } | ||||
| 
 | ||||
| // MustLoadURLs reads the content of multiple URLs in the given order into a | ||||
| // Properties struct and panics on error. If 'ignoreMissing' is true then a 404 | ||||
| // status code will not be reported as error. | ||||
| func MustLoadURLs(urls []string, ignoreMissing bool) *Properties { | ||||
| 	return must(LoadURLs(urls, ignoreMissing)) | ||||
| } | ||||
| 
 | ||||
| // MustLoadAll reads the content of multiple URLs or files in the given order into a | ||||
| // Properties struct. If 'ignoreMissing' is true then a 404 status code or missing file will | ||||
| // not be reported as error. Encoding sets the encoding for files. For the URLs please see | ||||
| // LoadURL for the Content-Type header and the encoding. It panics on error. | ||||
| func MustLoadAll(names []string, enc Encoding, ignoreMissing bool) *Properties { | ||||
| 	return must(LoadAll(names, enc, ignoreMissing)) | ||||
| } | ||||
| 
 | ||||
| func must(p *Properties, err error) *Properties { | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| // expandName expands ${ENV_VAR} expressions in a name. | ||||
| // If the environment variable does not exist then it will be replaced | ||||
| // with an empty string. Malformed expressions like "${ENV_VAR" will | ||||
| // be reported as error. | ||||
| func expandName(name string) (string, error) { | ||||
| 	return expand(name, []string{}, "${", "}", make(map[string]string)) | ||||
| } | ||||
| 
 | ||||
| // Interprets a byte buffer either as an ISO-8859-1 or UTF-8 encoded string. | ||||
| // For ISO-8859-1 we can convert each byte straight into a rune since the | ||||
| // first 256 unicode code points cover ISO-8859-1. | ||||
| func convert(buf []byte, enc Encoding) string { | ||||
| 	switch enc { | ||||
| 	case utf8Default, UTF8: | ||||
| 		return string(buf) | ||||
| 	case ISO_8859_1: | ||||
| 		runes := make([]rune, len(buf)) | ||||
| 		for i, b := range buf { | ||||
| 			runes[i] = rune(b) | ||||
| 		} | ||||
| 		return string(runes) | ||||
| 	default: | ||||
| 		ErrorHandler(fmt.Errorf("unsupported encoding %v", enc)) | ||||
| 	} | ||||
| 	panic("ErrorHandler should exit") | ||||
| } | ||||
							
								
								
									
										86
									
								
								vendor/github.com/magiconair/properties/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										86
									
								
								vendor/github.com/magiconair/properties/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,86 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| type parser struct { | ||||
| 	lex *lexer | ||||
| } | ||||
| 
 | ||||
| func parse(input string) (properties *Properties, err error) { | ||||
| 	p := &parser{lex: lex(input)} | ||||
| 	defer p.recover(&err) | ||||
| 
 | ||||
| 	properties = NewProperties() | ||||
| 	key := "" | ||||
| 	comments := []string{} | ||||
| 
 | ||||
| 	for { | ||||
| 		token := p.expectOneOf(itemComment, itemKey, itemEOF) | ||||
| 		switch token.typ { | ||||
| 		case itemEOF: | ||||
| 			goto done | ||||
| 		case itemComment: | ||||
| 			comments = append(comments, token.val) | ||||
| 			continue | ||||
| 		case itemKey: | ||||
| 			key = token.val | ||||
| 			if _, ok := properties.m[key]; !ok { | ||||
| 				properties.k = append(properties.k, key) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		token = p.expectOneOf(itemValue, itemEOF) | ||||
| 		if len(comments) > 0 { | ||||
| 			properties.c[key] = comments | ||||
| 			comments = []string{} | ||||
| 		} | ||||
| 		switch token.typ { | ||||
| 		case itemEOF: | ||||
| 			properties.m[key] = "" | ||||
| 			goto done | ||||
| 		case itemValue: | ||||
| 			properties.m[key] = token.val | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| done: | ||||
| 	return properties, nil | ||||
| } | ||||
| 
 | ||||
| func (p *parser) errorf(format string, args ...interface{}) { | ||||
| 	format = fmt.Sprintf("properties: Line %d: %s", p.lex.lineNumber(), format) | ||||
| 	panic(fmt.Errorf(format, args...)) | ||||
| } | ||||
| 
 | ||||
| func (p *parser) expectOneOf(expected ...itemType) (token item) { | ||||
| 	token = p.lex.nextItem() | ||||
| 	for _, v := range expected { | ||||
| 		if token.typ == v { | ||||
| 			return token | ||||
| 		} | ||||
| 	} | ||||
| 	p.unexpected(token) | ||||
| 	panic("unexpected token") | ||||
| } | ||||
| 
 | ||||
| func (p *parser) unexpected(token item) { | ||||
| 	p.errorf(token.String()) | ||||
| } | ||||
| 
 | ||||
| // recover is the handler that turns panics into returns from the top level of Parse. | ||||
| func (p *parser) recover(errp *error) { | ||||
| 	e := recover() | ||||
| 	if e != nil { | ||||
| 		if _, ok := e.(runtime.Error); ok { | ||||
| 			panic(e) | ||||
| 		} | ||||
| 		*errp = e.(error) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										848
									
								
								vendor/github.com/magiconair/properties/properties.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										848
									
								
								vendor/github.com/magiconair/properties/properties.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,848 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| // BUG(frank): Set() does not check for invalid unicode literals since this is currently handled by the lexer. | ||||
| // BUG(frank): Write() does not allow to configure the newline character. Therefore, on Windows LF is used. | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"regexp" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
| 
 | ||||
| const maxExpansionDepth = 64 | ||||
| 
 | ||||
| // ErrorHandlerFunc defines the type of function which handles failures | ||||
| // of the MustXXX() functions. An error handler function must exit | ||||
| // the application after handling the error. | ||||
| type ErrorHandlerFunc func(error) | ||||
| 
 | ||||
| // ErrorHandler is the function which handles failures of the MustXXX() | ||||
| // functions. The default is LogFatalHandler. | ||||
| var ErrorHandler ErrorHandlerFunc = LogFatalHandler | ||||
| 
 | ||||
| // LogHandlerFunc defines the function prototype for logging errors. | ||||
| type LogHandlerFunc func(fmt string, args ...interface{}) | ||||
| 
 | ||||
| // LogPrintf defines a log handler which uses log.Printf. | ||||
| var LogPrintf LogHandlerFunc = log.Printf | ||||
| 
 | ||||
| // LogFatalHandler handles the error by logging a fatal error and exiting. | ||||
| func LogFatalHandler(err error) { | ||||
| 	log.Fatal(err) | ||||
| } | ||||
| 
 | ||||
| // PanicHandler handles the error by panicking. | ||||
| func PanicHandler(err error) { | ||||
| 	panic(err) | ||||
| } | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------- | ||||
| 
 | ||||
| // A Properties contains the key/value pairs from the properties input. | ||||
| // All values are stored in unexpanded form and are expanded at runtime | ||||
| type Properties struct { | ||||
| 	// Pre-/Postfix for property expansion. | ||||
| 	Prefix  string | ||||
| 	Postfix string | ||||
| 
 | ||||
| 	// DisableExpansion controls the expansion of properties on Get() | ||||
| 	// and the check for circular references on Set(). When set to | ||||
| 	// true Properties behaves like a simple key/value store and does | ||||
| 	// not check for circular references on Get() or on Set(). | ||||
| 	DisableExpansion bool | ||||
| 
 | ||||
| 	// Stores the key/value pairs | ||||
| 	m map[string]string | ||||
| 
 | ||||
| 	// Stores the comments per key. | ||||
| 	c map[string][]string | ||||
| 
 | ||||
| 	// Stores the keys in order of appearance. | ||||
| 	k []string | ||||
| 
 | ||||
| 	// WriteSeparator specifies the separator of key and value while writing the properties. | ||||
| 	WriteSeparator string | ||||
| } | ||||
| 
 | ||||
| // NewProperties creates a new Properties struct with the default | ||||
| // configuration for "${key}" expressions. | ||||
| func NewProperties() *Properties { | ||||
| 	return &Properties{ | ||||
| 		Prefix:  "${", | ||||
| 		Postfix: "}", | ||||
| 		m:       map[string]string{}, | ||||
| 		c:       map[string][]string{}, | ||||
| 		k:       []string{}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Load reads a buffer into the given Properties struct. | ||||
| func (p *Properties) Load(buf []byte, enc Encoding) error { | ||||
| 	l := &Loader{Encoding: enc, DisableExpansion: p.DisableExpansion} | ||||
| 	newProperties, err := l.LoadBytes(buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	p.Merge(newProperties) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Get returns the expanded value for the given key if exists. | ||||
| // Otherwise, ok is false. | ||||
| func (p *Properties) Get(key string) (value string, ok bool) { | ||||
| 	v, ok := p.m[key] | ||||
| 	if p.DisableExpansion { | ||||
| 		return v, ok | ||||
| 	} | ||||
| 	if !ok { | ||||
| 		return "", false | ||||
| 	} | ||||
| 
 | ||||
| 	expanded, err := p.expand(key, v) | ||||
| 
 | ||||
| 	// we guarantee that the expanded value is free of | ||||
| 	// circular references and malformed expressions | ||||
| 	// so we panic if we still get an error here. | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 
 | ||||
| 	return expanded, true | ||||
| } | ||||
| 
 | ||||
| // MustGet returns the expanded value for the given key if exists. | ||||
| // Otherwise, it panics. | ||||
| func (p *Properties) MustGet(key string) string { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		return v | ||||
| 	} | ||||
| 	ErrorHandler(invalidKeyError(key)) | ||||
| 	panic("ErrorHandler should exit") | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // ClearComments removes the comments for all keys. | ||||
| func (p *Properties) ClearComments() { | ||||
| 	p.c = map[string][]string{} | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetComment returns the last comment before the given key or an empty string. | ||||
| func (p *Properties) GetComment(key string) string { | ||||
| 	comments, ok := p.c[key] | ||||
| 	if !ok || len(comments) == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return comments[len(comments)-1] | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetComments returns all comments that appeared before the given key or nil. | ||||
| func (p *Properties) GetComments(key string) []string { | ||||
| 	if comments, ok := p.c[key]; ok { | ||||
| 		return comments | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // SetComment sets the comment for the key. | ||||
| func (p *Properties) SetComment(key, comment string) { | ||||
| 	p.c[key] = []string{comment} | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // SetComments sets the comments for the key. If the comments are nil then | ||||
| // all comments for this key are deleted. | ||||
| func (p *Properties) SetComments(key string, comments []string) { | ||||
| 	if comments == nil { | ||||
| 		delete(p.c, key) | ||||
| 		return | ||||
| 	} | ||||
| 	p.c[key] = comments | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetBool checks if the expanded value is one of '1', 'yes', | ||||
| // 'true' or 'on' if the key exists. The comparison is case-insensitive. | ||||
| // If the key does not exist the default value is returned. | ||||
| func (p *Properties) GetBool(key string, def bool) bool { | ||||
| 	v, err := p.getBool(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // MustGetBool checks if the expanded value is one of '1', 'yes', | ||||
| // 'true' or 'on' if the key exists. The comparison is case-insensitive. | ||||
| // If the key does not exist the function panics. | ||||
| func (p *Properties) MustGetBool(key string) bool { | ||||
| 	v, err := p.getBool(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| func (p *Properties) getBool(key string) (value bool, err error) { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		return boolVal(v), nil | ||||
| 	} | ||||
| 	return false, invalidKeyError(key) | ||||
| } | ||||
| 
 | ||||
| func boolVal(v string) bool { | ||||
| 	v = strings.ToLower(v) | ||||
| 	return v == "1" || v == "true" || v == "yes" || v == "on" | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetDuration parses the expanded value as an time.Duration (in ns) if the | ||||
| // key exists. If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. In almost all cases you want to use GetParsedDuration(). | ||||
| func (p *Properties) GetDuration(key string, def time.Duration) time.Duration { | ||||
| 	v, err := p.getInt64(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return time.Duration(v) | ||||
| } | ||||
| 
 | ||||
| // MustGetDuration parses the expanded value as an time.Duration (in ns) if | ||||
| // the key exists. If key does not exist or the value cannot be parsed the | ||||
| // function panics. In almost all cases you want to use MustGetParsedDuration(). | ||||
| func (p *Properties) MustGetDuration(key string) time.Duration { | ||||
| 	v, err := p.getInt64(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return time.Duration(v) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetParsedDuration parses the expanded value with time.ParseDuration() if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. | ||||
| func (p *Properties) GetParsedDuration(key string, def time.Duration) time.Duration { | ||||
| 	s, ok := p.Get(key) | ||||
| 	if !ok { | ||||
| 		return def | ||||
| 	} | ||||
| 	v, err := time.ParseDuration(s) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // MustGetParsedDuration parses the expanded value with time.ParseDuration() if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the function panics. | ||||
| func (p *Properties) MustGetParsedDuration(key string) time.Duration { | ||||
| 	s, ok := p.Get(key) | ||||
| 	if !ok { | ||||
| 		ErrorHandler(invalidKeyError(key)) | ||||
| 	} | ||||
| 	v, err := time.ParseDuration(s) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetFloat64 parses the expanded value as a float64 if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. | ||||
| func (p *Properties) GetFloat64(key string, def float64) float64 { | ||||
| 	v, err := p.getFloat64(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // MustGetFloat64 parses the expanded value as a float64 if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the function panics. | ||||
| func (p *Properties) MustGetFloat64(key string) float64 { | ||||
| 	v, err := p.getFloat64(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| func (p *Properties) getFloat64(key string) (value float64, err error) { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		value, err = strconv.ParseFloat(v, 64) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		return value, nil | ||||
| 	} | ||||
| 	return 0, invalidKeyError(key) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetInt parses the expanded value as an int if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. If the value does not fit into an int the | ||||
| // function panics with an out of range error. | ||||
| func (p *Properties) GetInt(key string, def int) int { | ||||
| 	v, err := p.getInt64(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return intRangeCheck(key, v) | ||||
| } | ||||
| 
 | ||||
| // MustGetInt parses the expanded value as an int if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the function panics. | ||||
| // If the value does not fit into an int the function panics with | ||||
| // an out of range error. | ||||
| func (p *Properties) MustGetInt(key string) int { | ||||
| 	v, err := p.getInt64(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return intRangeCheck(key, v) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetInt64 parses the expanded value as an int64 if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. | ||||
| func (p *Properties) GetInt64(key string, def int64) int64 { | ||||
| 	v, err := p.getInt64(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // MustGetInt64 parses the expanded value as an int if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the function panics. | ||||
| func (p *Properties) MustGetInt64(key string) int64 { | ||||
| 	v, err := p.getInt64(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| func (p *Properties) getInt64(key string) (value int64, err error) { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		value, err = strconv.ParseInt(v, 10, 64) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		return value, nil | ||||
| 	} | ||||
| 	return 0, invalidKeyError(key) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetUint parses the expanded value as an uint if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. If the value does not fit into an int the | ||||
| // function panics with an out of range error. | ||||
| func (p *Properties) GetUint(key string, def uint) uint { | ||||
| 	v, err := p.getUint64(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return uintRangeCheck(key, v) | ||||
| } | ||||
| 
 | ||||
| // MustGetUint parses the expanded value as an int if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the function panics. | ||||
| // If the value does not fit into an int the function panics with | ||||
| // an out of range error. | ||||
| func (p *Properties) MustGetUint(key string) uint { | ||||
| 	v, err := p.getUint64(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return uintRangeCheck(key, v) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetUint64 parses the expanded value as an uint64 if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the default | ||||
| // value is returned. | ||||
| func (p *Properties) GetUint64(key string, def uint64) uint64 { | ||||
| 	v, err := p.getUint64(key) | ||||
| 	if err != nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // MustGetUint64 parses the expanded value as an int if the key exists. | ||||
| // If key does not exist or the value cannot be parsed the function panics. | ||||
| func (p *Properties) MustGetUint64(key string) uint64 { | ||||
| 	v, err := p.getUint64(key) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| func (p *Properties) getUint64(key string) (value uint64, err error) { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		value, err = strconv.ParseUint(v, 10, 64) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		return value, nil | ||||
| 	} | ||||
| 	return 0, invalidKeyError(key) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // GetString returns the expanded value for the given key if exists or | ||||
| // the default value otherwise. | ||||
| func (p *Properties) GetString(key, def string) string { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		return v | ||||
| 	} | ||||
| 	return def | ||||
| } | ||||
| 
 | ||||
| // MustGetString returns the expanded value for the given key if exists or | ||||
| // panics otherwise. | ||||
| func (p *Properties) MustGetString(key string) string { | ||||
| 	if v, ok := p.Get(key); ok { | ||||
| 		return v | ||||
| 	} | ||||
| 	ErrorHandler(invalidKeyError(key)) | ||||
| 	panic("ErrorHandler should exit") | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // Filter returns a new properties object which contains all properties | ||||
| // for which the key matches the pattern. | ||||
| func (p *Properties) Filter(pattern string) (*Properties, error) { | ||||
| 	re, err := regexp.Compile(pattern) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return p.FilterRegexp(re), nil | ||||
| } | ||||
| 
 | ||||
| // FilterRegexp returns a new properties object which contains all properties | ||||
| // for which the key matches the regular expression. | ||||
| func (p *Properties) FilterRegexp(re *regexp.Regexp) *Properties { | ||||
| 	pp := NewProperties() | ||||
| 	for _, k := range p.k { | ||||
| 		if re.MatchString(k) { | ||||
| 			// TODO(fs): we are ignoring the error which flags a circular reference. | ||||
| 			// TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed) | ||||
| 			pp.Set(k, p.m[k]) | ||||
| 		} | ||||
| 	} | ||||
| 	return pp | ||||
| } | ||||
| 
 | ||||
| // FilterPrefix returns a new properties object with a subset of all keys | ||||
| // with the given prefix. | ||||
| func (p *Properties) FilterPrefix(prefix string) *Properties { | ||||
| 	pp := NewProperties() | ||||
| 	for _, k := range p.k { | ||||
| 		if strings.HasPrefix(k, prefix) { | ||||
| 			// TODO(fs): we are ignoring the error which flags a circular reference. | ||||
| 			// TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed) | ||||
| 			pp.Set(k, p.m[k]) | ||||
| 		} | ||||
| 	} | ||||
| 	return pp | ||||
| } | ||||
| 
 | ||||
| // FilterStripPrefix returns a new properties object with a subset of all keys | ||||
| // with the given prefix and the prefix removed from the keys. | ||||
| func (p *Properties) FilterStripPrefix(prefix string) *Properties { | ||||
| 	pp := NewProperties() | ||||
| 	n := len(prefix) | ||||
| 	for _, k := range p.k { | ||||
| 		if len(k) > len(prefix) && strings.HasPrefix(k, prefix) { | ||||
| 			// TODO(fs): we are ignoring the error which flags a circular reference. | ||||
| 			// TODO(fs): since we are modifying keys I am not entirely sure whether we can create a circular reference | ||||
| 			// TODO(fs): this function should probably return an error but the signature is fixed | ||||
| 			pp.Set(k[n:], p.m[k]) | ||||
| 		} | ||||
| 	} | ||||
| 	return pp | ||||
| } | ||||
| 
 | ||||
| // Len returns the number of keys. | ||||
| func (p *Properties) Len() int { | ||||
| 	return len(p.m) | ||||
| } | ||||
| 
 | ||||
| // Keys returns all keys in the same order as in the input. | ||||
| func (p *Properties) Keys() []string { | ||||
| 	keys := make([]string, len(p.k)) | ||||
| 	copy(keys, p.k) | ||||
| 	return keys | ||||
| } | ||||
| 
 | ||||
| // Set sets the property key to the corresponding value. | ||||
| // If a value for key existed before then ok is true and prev | ||||
| // contains the previous value. If the value contains a | ||||
| // circular reference or a malformed expression then | ||||
| // an error is returned. | ||||
| // An empty key is silently ignored. | ||||
| func (p *Properties) Set(key, value string) (prev string, ok bool, err error) { | ||||
| 	if key == "" { | ||||
| 		return "", false, nil | ||||
| 	} | ||||
| 
 | ||||
| 	// if expansion is disabled we allow circular references | ||||
| 	if p.DisableExpansion { | ||||
| 		prev, ok = p.Get(key) | ||||
| 		p.m[key] = value | ||||
| 		if !ok { | ||||
| 			p.k = append(p.k, key) | ||||
| 		} | ||||
| 		return prev, ok, nil | ||||
| 	} | ||||
| 
 | ||||
| 	// to check for a circular reference we temporarily need | ||||
| 	// to set the new value. If there is an error then revert | ||||
| 	// to the previous state. Only if all tests are successful | ||||
| 	// then we add the key to the p.k list. | ||||
| 	prev, ok = p.Get(key) | ||||
| 	p.m[key] = value | ||||
| 
 | ||||
| 	// now check for a circular reference | ||||
| 	_, err = p.expand(key, value) | ||||
| 	if err != nil { | ||||
| 
 | ||||
| 		// revert to the previous state | ||||
| 		if ok { | ||||
| 			p.m[key] = prev | ||||
| 		} else { | ||||
| 			delete(p.m, key) | ||||
| 		} | ||||
| 
 | ||||
| 		return "", false, err | ||||
| 	} | ||||
| 
 | ||||
| 	if !ok { | ||||
| 		p.k = append(p.k, key) | ||||
| 	} | ||||
| 
 | ||||
| 	return prev, ok, nil | ||||
| } | ||||
| 
 | ||||
| // SetValue sets property key to the default string value | ||||
| // as defined by fmt.Sprintf("%v"). | ||||
| func (p *Properties) SetValue(key string, value interface{}) error { | ||||
| 	_, _, err := p.Set(key, fmt.Sprintf("%v", value)) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // MustSet sets the property key to the corresponding value. | ||||
| // If a value for key existed before then ok is true and prev | ||||
| // contains the previous value. An empty key is silently ignored. | ||||
| func (p *Properties) MustSet(key, value string) (prev string, ok bool) { | ||||
| 	prev, ok, err := p.Set(key, value) | ||||
| 	if err != nil { | ||||
| 		ErrorHandler(err) | ||||
| 	} | ||||
| 	return prev, ok | ||||
| } | ||||
| 
 | ||||
| // String returns a string of all expanded 'key = value' pairs. | ||||
| func (p *Properties) String() string { | ||||
| 	var s string | ||||
| 	for _, key := range p.k { | ||||
| 		value, _ := p.Get(key) | ||||
| 		s = fmt.Sprintf("%s%s = %s\n", s, key, value) | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // Sort sorts the properties keys in alphabetical order. | ||||
| // This is helpfully before writing the properties. | ||||
| func (p *Properties) Sort() { | ||||
| 	sort.Strings(p.k) | ||||
| } | ||||
| 
 | ||||
| // Write writes all unexpanded 'key = value' pairs to the given writer. | ||||
| // Write returns the number of bytes written and any write error encountered. | ||||
| func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) { | ||||
| 	return p.WriteComment(w, "", enc) | ||||
| } | ||||
| 
 | ||||
| // WriteComment writes all unexpanced 'key = value' pairs to the given writer. | ||||
| // If prefix is not empty then comments are written with a blank line and the | ||||
| // given prefix. The prefix should be either "# " or "! " to be compatible with | ||||
| // the properties file format. Otherwise, the properties parser will not be | ||||
| // able to read the file back in. It returns the number of bytes written and | ||||
| // any write error encountered. | ||||
| func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n int, err error) { | ||||
| 	var x int | ||||
| 
 | ||||
| 	for _, key := range p.k { | ||||
| 		value := p.m[key] | ||||
| 
 | ||||
| 		if prefix != "" { | ||||
| 			if comments, ok := p.c[key]; ok { | ||||
| 				// don't print comments if they are all empty | ||||
| 				allEmpty := true | ||||
| 				for _, c := range comments { | ||||
| 					if c != "" { | ||||
| 						allEmpty = false | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if !allEmpty { | ||||
| 					// add a blank line between entries but not at the top | ||||
| 					if len(comments) > 0 && n > 0 { | ||||
| 						x, err = fmt.Fprintln(w) | ||||
| 						if err != nil { | ||||
| 							return | ||||
| 						} | ||||
| 						n += x | ||||
| 					} | ||||
| 
 | ||||
| 					for _, c := range comments { | ||||
| 						x, err = fmt.Fprintf(w, "%s%s\n", prefix, c) | ||||
| 						if err != nil { | ||||
| 							return | ||||
| 						} | ||||
| 						n += x | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		sep := " = " | ||||
| 		if p.WriteSeparator != "" { | ||||
| 			sep = p.WriteSeparator | ||||
| 		} | ||||
| 		x, err = fmt.Fprintf(w, "%s%s%s\n", encode(key, " :", enc), sep, encode(value, "", enc)) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		n += x | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Map returns a copy of the properties as a map. | ||||
| func (p *Properties) Map() map[string]string { | ||||
| 	m := make(map[string]string) | ||||
| 	for k, v := range p.m { | ||||
| 		m[k] = v | ||||
| 	} | ||||
| 	return m | ||||
| } | ||||
| 
 | ||||
| // FilterFunc returns a copy of the properties which includes the values which passed all filters. | ||||
| func (p *Properties) FilterFunc(filters ...func(k, v string) bool) *Properties { | ||||
| 	pp := NewProperties() | ||||
| outer: | ||||
| 	for k, v := range p.m { | ||||
| 		for _, f := range filters { | ||||
| 			if !f(k, v) { | ||||
| 				continue outer | ||||
| 			} | ||||
| 			pp.Set(k, v) | ||||
| 		} | ||||
| 	} | ||||
| 	return pp | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // Delete removes the key and its comments. | ||||
| func (p *Properties) Delete(key string) { | ||||
| 	delete(p.m, key) | ||||
| 	delete(p.c, key) | ||||
| 	newKeys := []string{} | ||||
| 	for _, k := range p.k { | ||||
| 		if k != key { | ||||
| 			newKeys = append(newKeys, k) | ||||
| 		} | ||||
| 	} | ||||
| 	p.k = newKeys | ||||
| } | ||||
| 
 | ||||
| // Merge merges properties, comments and keys from other *Properties into p | ||||
| func (p *Properties) Merge(other *Properties) { | ||||
| 	for _, k := range other.k { | ||||
| 		if _, ok := p.m[k]; !ok { | ||||
| 			p.k = append(p.k, k) | ||||
| 		} | ||||
| 	} | ||||
| 	for k, v := range other.m { | ||||
| 		p.m[k] = v | ||||
| 	} | ||||
| 	for k, v := range other.c { | ||||
| 		p.c[k] = v | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| // check expands all values and returns an error if a circular reference or | ||||
| // a malformed expression was found. | ||||
| func (p *Properties) check() error { | ||||
| 	for key, value := range p.m { | ||||
| 		if _, err := p.expand(key, value); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *Properties) expand(key, input string) (string, error) { | ||||
| 	// no pre/postfix -> nothing to expand | ||||
| 	if p.Prefix == "" && p.Postfix == "" { | ||||
| 		return input, nil | ||||
| 	} | ||||
| 
 | ||||
| 	return expand(input, []string{key}, p.Prefix, p.Postfix, p.m) | ||||
| } | ||||
| 
 | ||||
| // expand recursively expands expressions of '(prefix)key(postfix)' to their corresponding values. | ||||
| // The function keeps track of the keys that were already expanded and stops if it | ||||
| // detects a circular reference or a malformed expression of the form '(prefix)key'. | ||||
| func expand(s string, keys []string, prefix, postfix string, values map[string]string) (string, error) { | ||||
| 	if len(keys) > maxExpansionDepth { | ||||
| 		return "", fmt.Errorf("expansion too deep") | ||||
| 	} | ||||
| 
 | ||||
| 	for { | ||||
| 		start := strings.Index(s, prefix) | ||||
| 		if start == -1 { | ||||
| 			return s, nil | ||||
| 		} | ||||
| 
 | ||||
| 		keyStart := start + len(prefix) | ||||
| 		keyLen := strings.Index(s[keyStart:], postfix) | ||||
| 		if keyLen == -1 { | ||||
| 			return "", fmt.Errorf("malformed expression") | ||||
| 		} | ||||
| 
 | ||||
| 		end := keyStart + keyLen + len(postfix) - 1 | ||||
| 		key := s[keyStart : keyStart+keyLen] | ||||
| 
 | ||||
| 		// fmt.Printf("s:%q pp:%q start:%d end:%d keyStart:%d keyLen:%d key:%q\n", s, prefix + "..." + postfix, start, end, keyStart, keyLen, key) | ||||
| 
 | ||||
| 		for _, k := range keys { | ||||
| 			if key == k { | ||||
| 				var b bytes.Buffer | ||||
| 				b.WriteString("circular reference in:\n") | ||||
| 				for _, k1 := range keys { | ||||
| 					fmt.Fprintf(&b, "%s=%s\n", k1, values[k1]) | ||||
| 				} | ||||
| 				return "", fmt.Errorf(b.String()) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		val, ok := values[key] | ||||
| 		if !ok { | ||||
| 			val = os.Getenv(key) | ||||
| 		} | ||||
| 		new_val, err := expand(val, append(keys, key), prefix, postfix, values) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		s = s[:start] + new_val + s[end+1:] | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // encode encodes a UTF-8 string to ISO-8859-1 and escapes some characters. | ||||
| func encode(s string, special string, enc Encoding) string { | ||||
| 	switch enc { | ||||
| 	case UTF8: | ||||
| 		return encodeUtf8(s, special) | ||||
| 	case ISO_8859_1: | ||||
| 		return encodeIso(s, special) | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unsupported encoding %v", enc)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func encodeUtf8(s string, special string) string { | ||||
| 	v := "" | ||||
| 	for pos := 0; pos < len(s); { | ||||
| 		r, w := utf8.DecodeRuneInString(s[pos:]) | ||||
| 		pos += w | ||||
| 		v += escape(r, special) | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| func encodeIso(s string, special string) string { | ||||
| 	var r rune | ||||
| 	var w int | ||||
| 	var v string | ||||
| 	for pos := 0; pos < len(s); { | ||||
| 		switch r, w = utf8.DecodeRuneInString(s[pos:]); { | ||||
| 		case r < 1<<8: // single byte rune -> escape special chars only | ||||
| 			v += escape(r, special) | ||||
| 		case r < 1<<16: // two byte rune -> unicode literal | ||||
| 			v += fmt.Sprintf("\\u%04x", r) | ||||
| 		default: // more than two bytes per rune -> can't encode | ||||
| 			v += "?" | ||||
| 		} | ||||
| 		pos += w | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| func escape(r rune, special string) string { | ||||
| 	switch r { | ||||
| 	case '\f': | ||||
| 		return "\\f" | ||||
| 	case '\n': | ||||
| 		return "\\n" | ||||
| 	case '\r': | ||||
| 		return "\\r" | ||||
| 	case '\t': | ||||
| 		return "\\t" | ||||
| 	case '\\': | ||||
| 		return "\\\\" | ||||
| 	default: | ||||
| 		if strings.ContainsRune(special, r) { | ||||
| 			return "\\" + string(r) | ||||
| 		} | ||||
| 		return string(r) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func invalidKeyError(key string) error { | ||||
| 	return fmt.Errorf("unknown property: %s", key) | ||||
| } | ||||
							
								
								
									
										31
									
								
								vendor/github.com/magiconair/properties/rangecheck.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/magiconair/properties/rangecheck.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,31 +0,0 @@ | |||
| // Copyright 2013-2022 Frank Schroeder. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package properties | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| ) | ||||
| 
 | ||||
| // make this a var to overwrite it in a test | ||||
| var is32Bit = ^uint(0) == math.MaxUint32 | ||||
| 
 | ||||
| // intRangeCheck checks if the value fits into the int type and | ||||
| // panics if it does not. | ||||
| func intRangeCheck(key string, v int64) int { | ||||
| 	if is32Bit && (v < math.MinInt32 || v > math.MaxInt32) { | ||||
| 		panic(fmt.Sprintf("Value %d for key %s out of range", v, key)) | ||||
| 	} | ||||
| 	return int(v) | ||||
| } | ||||
| 
 | ||||
| // uintRangeCheck checks if the value fits into the uint type and | ||||
| // panics if it does not. | ||||
| func uintRangeCheck(key string, v uint64) uint { | ||||
| 	if is32Bit && v > math.MaxUint32 { | ||||
| 		panic(fmt.Sprintf("Value %d for key %s out of range", v, key)) | ||||
| 	} | ||||
| 	return uint(v) | ||||
| } | ||||
							
								
								
									
										6
									
								
								vendor/github.com/sagikazarmark/locafero/finder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/sagikazarmark/locafero/finder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -27,7 +27,7 @@ type Finder struct { | |||
| 	// It provides the capability to search for entries with depth, | ||||
| 	// meaning it can target deeper locations within the directory structure. | ||||
| 	// | ||||
| 	// It also supports glob syntax (as defined by [filepat.Match]), offering greater flexibility in search patterns. | ||||
| 	// It also supports glob syntax (as defined by [filepath.Match]), offering greater flexibility in search patterns. | ||||
| 	// | ||||
| 	// Examples: | ||||
| 	//   - config.yaml | ||||
|  | @ -63,7 +63,7 @@ func (f Finder) Find(fsys afero.Fs) ([]string, error) { | |||
| 
 | ||||
| 			// pool.Go(func() ([]string, error) { | ||||
| 			// 	// If the name contains any glob character, perform a glob match | ||||
| 			// 	if strings.ContainsAny(searchName, "*?[]\\^") { | ||||
| 			// 	if strings.ContainsAny(searchName, globMatch) { | ||||
| 			// 		return globWalkSearch(fsys, searchPath, searchName, f.Type) | ||||
| 			// 	} | ||||
| 			// | ||||
|  | @ -79,7 +79,7 @@ func (f Finder) Find(fsys afero.Fs) ([]string, error) { | |||
| 
 | ||||
| 	allResults, err := iter.MapErr(searchItems, func(item *searchItem) ([]string, error) { | ||||
| 		// If the name contains any glob character, perform a glob match | ||||
| 		if strings.ContainsAny(item.name, "*?[]\\^") { | ||||
| 		if strings.ContainsAny(item.name, globMatch) { | ||||
| 			return globWalkSearch(fsys, item.path, item.name, f.Type) | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										333
									
								
								vendor/github.com/sagikazarmark/locafero/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										333
									
								
								vendor/github.com/sagikazarmark/locafero/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,22 +1,84 @@ | |||
| { | ||||
|   "nodes": { | ||||
|     "devenv": { | ||||
|     "cachix": { | ||||
|       "inputs": { | ||||
|         "flake-compat": "flake-compat", | ||||
|         "nix": "nix", | ||||
|         "nixpkgs": "nixpkgs", | ||||
|         "pre-commit-hooks": "pre-commit-hooks" | ||||
|         "devenv": "devenv_2", | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "pre-commit-hooks": [ | ||||
|           "devenv", | ||||
|           "pre-commit-hooks" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1694097209, | ||||
|         "narHash": "sha256-gQmBjjxeSyySjbh0yQVBKApo2KWIFqqbRUvG+Fa+QpM=", | ||||
|         "lastModified": 1712055811, | ||||
|         "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "7a8e6a91510efe89d8dcb8e43233f93e86f6b189", | ||||
|         "repo": "cachix", | ||||
|         "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "cachix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "devenv": { | ||||
|       "inputs": { | ||||
|         "cachix": "cachix", | ||||
|         "flake-compat": "flake-compat_2", | ||||
|         "nix": "nix_2", | ||||
|         "nixpkgs": "nixpkgs_2", | ||||
|         "pre-commit-hooks": "pre-commit-hooks" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1725907707, | ||||
|         "narHash": "sha256-s3pbtzZmVPHzc86WQjK7MGZMNvvw6hWnFMljEkllAfM=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "2bbbbc468fc02257265a79652a8350651cca495a", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "devenv_2": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nix": "nix", | ||||
|         "nixpkgs": "nixpkgs", | ||||
|         "poetry2nix": "poetry2nix", | ||||
|         "pre-commit-hooks": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "pre-commit-hooks" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1708704632, | ||||
|         "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "ref": "python-rewrite", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|  | @ -37,16 +99,32 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-compat_2": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1696426674, | ||||
|         "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-parts": { | ||||
|       "inputs": { | ||||
|         "nixpkgs-lib": "nixpkgs-lib" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1693611461, | ||||
|         "narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=", | ||||
|         "lastModified": 1725234343, | ||||
|         "narHash": "sha256-+ebgonl3NbiKD2UD0x4BszCZQ6sTfL4xioaM49o5B3Y=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "flake-parts", | ||||
|         "rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca", | ||||
|         "rev": "567b938d64d4b4112ee253b9274472dc3a346eb6", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -60,11 +138,29 @@ | |||
|         "systems": "systems" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1685518550, | ||||
|         "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", | ||||
|         "lastModified": 1689068808, | ||||
|         "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", | ||||
|         "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-utils_2": { | ||||
|       "inputs": { | ||||
|         "systems": "systems_2" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1710146030, | ||||
|         "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -82,11 +178,11 @@ | |||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1660459072, | ||||
|         "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", | ||||
|         "lastModified": 1709087332, | ||||
|         "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "gitignore.nix", | ||||
|         "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", | ||||
|         "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -95,53 +191,90 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "lowdown-src": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1633514407, | ||||
|         "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", | ||||
|         "owner": "kristapsdz", | ||||
|         "repo": "lowdown", | ||||
|         "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "kristapsdz", | ||||
|         "repo": "lowdown", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix": { | ||||
|       "inputs": { | ||||
|         "lowdown-src": "lowdown-src", | ||||
|         "flake-compat": "flake-compat", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1676545802, | ||||
|         "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", | ||||
|         "lastModified": 1712911606, | ||||
|         "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", | ||||
|         "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "relaxed-flakes", | ||||
|         "ref": "devenv-2.21", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix-github-actions": { | ||||
|       "inputs": { | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "poetry2nix", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1688870561, | ||||
|         "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "nix-github-actions", | ||||
|         "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-community", | ||||
|         "repo": "nix-github-actions", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix_2": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression_2" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1712911606, | ||||
|         "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "devenv-2.21", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs": { | ||||
|       "locked": { | ||||
|         "lastModified": 1678875422, | ||||
|         "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", | ||||
|         "lastModified": 1692808169, | ||||
|         "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", | ||||
|         "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -153,20 +286,14 @@ | |||
|     }, | ||||
|     "nixpkgs-lib": { | ||||
|       "locked": { | ||||
|         "dir": "lib", | ||||
|         "lastModified": 1693471703, | ||||
|         "narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85", | ||||
|         "type": "github" | ||||
|         "lastModified": 1725233747, | ||||
|         "narHash": "sha256-Ss8QWLXdr2JCBPcYChJhz4xJm+h/xjl4G0c0XlP6a74=", | ||||
|         "type": "tarball", | ||||
|         "url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz" | ||||
|       }, | ||||
|       "original": { | ||||
|         "dir": "lib", | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-unstable", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|         "type": "tarball", | ||||
|         "url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-regression": { | ||||
|  | @ -185,29 +312,61 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-stable": { | ||||
|     "nixpkgs-regression_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1685801374, | ||||
|         "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", | ||||
|         "lastModified": 1643052045, | ||||
|         "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-23.05", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-stable": { | ||||
|       "locked": { | ||||
|         "lastModified": 1710695816, | ||||
|         "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "614b4613980a522ba49f0d194531beddbb7220d3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-23.11", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1694343207, | ||||
|         "narHash": "sha256-jWi7OwFxU5Owi4k2JmiL1sa/OuBCQtpaAesuj5LXC8w=", | ||||
|         "lastModified": 1713361204, | ||||
|         "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv-nixpkgs", | ||||
|         "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "ref": "rolling", | ||||
|         "repo": "devenv-nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_3": { | ||||
|       "locked": { | ||||
|         "lastModified": 1725910328, | ||||
|         "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "78058d810644f5ed276804ce7ea9e82d92bee293", | ||||
|         "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -217,13 +376,38 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "poetry2nix": { | ||||
|       "inputs": { | ||||
|         "flake-utils": "flake-utils", | ||||
|         "nix-github-actions": "nix-github-actions", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1692876271, | ||||
|         "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "poetry2nix", | ||||
|         "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-community", | ||||
|         "repo": "poetry2nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "pre-commit-hooks": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "flake-utils": "flake-utils", | ||||
|         "flake-utils": "flake-utils_2", | ||||
|         "gitignore": "gitignore", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|  | @ -232,11 +416,11 @@ | |||
|         "nixpkgs-stable": "nixpkgs-stable" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1688056373, | ||||
|         "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=", | ||||
|         "lastModified": 1713775815, | ||||
|         "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "pre-commit-hooks.nix", | ||||
|         "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7", | ||||
|         "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -249,7 +433,7 @@ | |||
|       "inputs": { | ||||
|         "devenv": "devenv", | ||||
|         "flake-parts": "flake-parts", | ||||
|         "nixpkgs": "nixpkgs_2" | ||||
|         "nixpkgs": "nixpkgs_3" | ||||
|       } | ||||
|     }, | ||||
|     "systems": { | ||||
|  | @ -266,6 +450,21 @@ | |||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "systems_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1681028828, | ||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "root": "root", | ||||
|  |  | |||
							
								
								
									
										21
									
								
								vendor/github.com/sagikazarmark/locafero/flake.nix
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/sagikazarmark/locafero/flake.nix
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -20,6 +20,7 @@ | |||
|           default = { | ||||
|             languages = { | ||||
|               go.enable = true; | ||||
|               go.package = pkgs.lib.mkDefault pkgs.go_1_23; | ||||
|             }; | ||||
| 
 | ||||
|             packages = with pkgs; [ | ||||
|  | @ -34,11 +35,27 @@ | |||
| 
 | ||||
|           ci = devenv.shells.default; | ||||
| 
 | ||||
|           ci_1_20 = { | ||||
|           ci_1_21 = { | ||||
|             imports = [ devenv.shells.ci ]; | ||||
| 
 | ||||
|             languages = { | ||||
|               go.package = pkgs.go_1_20; | ||||
|               go.package = pkgs.go_1_21; | ||||
|             }; | ||||
|           }; | ||||
| 
 | ||||
|           ci_1_22 = { | ||||
|             imports = [ devenv.shells.ci ]; | ||||
| 
 | ||||
|             languages = { | ||||
|               go.package = pkgs.go_1_22; | ||||
|             }; | ||||
|           }; | ||||
| 
 | ||||
|           ci_1_23 = { | ||||
|             imports = [ devenv.shells.ci ]; | ||||
| 
 | ||||
|             languages = { | ||||
|               go.package = pkgs.go_1_23; | ||||
|             }; | ||||
|           }; | ||||
|         }; | ||||
|  |  | |||
							
								
								
									
										5
									
								
								vendor/github.com/sagikazarmark/locafero/glob.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/sagikazarmark/locafero/glob.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| //go:build !windows | ||||
| 
 | ||||
| package locafero | ||||
| 
 | ||||
| const globMatch = "*?[]\\^" | ||||
							
								
								
									
										8
									
								
								vendor/github.com/sagikazarmark/locafero/glob_windows.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/sagikazarmark/locafero/glob_windows.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| //go:build windows | ||||
| 
 | ||||
| package locafero | ||||
| 
 | ||||
| // See [filepath.Match]: | ||||
| // | ||||
| //	On Windows, escaping is disabled. Instead, '\\' is treated as path separator. | ||||
| const globMatch = "*?[]^" | ||||
							
								
								
									
										4
									
								
								vendor/github.com/sagikazarmark/slog-shim/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/sagikazarmark/slog-shim/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,4 +0,0 @@ | |||
| /.devenv/ | ||||
| /.direnv/ | ||||
| /.task/ | ||||
| /build/ | ||||
							
								
								
									
										27
									
								
								vendor/github.com/sagikazarmark/slog-shim/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/sagikazarmark/slog-shim/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,27 +0,0 @@ | |||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										81
									
								
								vendor/github.com/sagikazarmark/slog-shim/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/sagikazarmark/slog-shim/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,81 +0,0 @@ | |||
| # [slog](https://pkg.go.dev/log/slog) shim | ||||
| 
 | ||||
| [](https://github.com/sagikazarmark/slog-shim/actions/workflows/ci.yaml) | ||||
| [](https://pkg.go.dev/mod/github.com/sagikazarmark/slog-shim) | ||||
|  | ||||
| [](https://builtwithnix.org) | ||||
| 
 | ||||
| Go 1.21 introduced a [new structured logging package](https://golang.org/doc/go1.21#slog), `log/slog`, to the standard library. | ||||
| Although it's been eagerly anticipated by many, widespread adoption isn't expected to occur immediately, | ||||
| especially since updating to Go 1.21 is a decision that most libraries won't make overnight. | ||||
| 
 | ||||
| Before this package was added to the standard library, there was an _experimental_ version available at [golang.org/x/exp/slog](https://pkg.go.dev/golang.org/x/exp/slog). | ||||
| While it's generally advised against using experimental packages in production, | ||||
| this one served as a sort of backport package for the last few years, | ||||
| incorporating new features before they were added to the standard library (like `slices`, `maps` or `errors`). | ||||
| 
 | ||||
| This package serves as a bridge, helping libraries integrate slog in a backward-compatible way without having to immediately update their Go version requirement to 1.21. On Go 1.21 (and above), it acts as a drop-in replacement for `log/slog`, while below 1.21 it falls back to `golang.org/x/exp/slog`. | ||||
| 
 | ||||
| **How does it achieve backwards compatibility?** | ||||
| 
 | ||||
| Although there's no consensus on whether dropping support for older Go versions is considered backward compatible, a majority seems to believe it is. | ||||
| (I don't have scientific proof for this, but it's based on conversations with various individuals across different channels.) | ||||
| 
 | ||||
| This package adheres to that interpretation of backward compatibility. On Go 1.21, the shim uses type aliases to offer the same API as `slog/log`. | ||||
| Once a library upgrades its version requirement to Go 1.21, it should be able to discard this shim and use `log/slog` directly. | ||||
| 
 | ||||
| For older Go versions, the library might become unstable after removing the shim. | ||||
| However, since those older versions are no longer supported, the promise of backward compatibility remains intact. | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| ```shell | ||||
| go get github.com/sagikazarmark/slog-shim | ||||
| ``` | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| Import this package into your library and use it in your public API: | ||||
| 
 | ||||
| ```go | ||||
| package mylib | ||||
| 
 | ||||
| import slog "github.com/sagikazarmark/slog-shim" | ||||
| 
 | ||||
| func New(logger *slog.Logger) MyLib { | ||||
|     // ... | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| When using the library, clients can either use `log/slog` (when on Go 1.21) or `golang.org/x/exp/slog` (below Go 1.21): | ||||
| 
 | ||||
| ```go | ||||
| package main | ||||
| 
 | ||||
| import "log/slog" | ||||
| 
 | ||||
| // OR | ||||
| 
 | ||||
| import "golang.org/x/exp/slog" | ||||
| 
 | ||||
| mylib.New(slog.Default()) | ||||
| ``` | ||||
| 
 | ||||
| **Make sure consumers are aware that your API behaves differently on different Go versions.** | ||||
| 
 | ||||
| Once you bump your Go version requirement to Go 1.21, you can drop the shim entirely from your code: | ||||
| 
 | ||||
| ```diff | ||||
| package mylib | ||||
| 
 | ||||
| - import slog "github.com/sagikazarmark/slog-shim" | ||||
| + import "log/slog" | ||||
| 
 | ||||
| func New(logger *slog.Logger) MyLib { | ||||
|     // ... | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| The project is licensed under a [BSD-style license](LICENSE). | ||||
							
								
								
									
										74
									
								
								vendor/github.com/sagikazarmark/slog-shim/attr.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/sagikazarmark/slog-shim/attr.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,74 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"log/slog" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // An Attr is a key-value pair. | ||||
| type Attr = slog.Attr | ||||
| 
 | ||||
| // String returns an Attr for a string value. | ||||
| func String(key, value string) Attr { | ||||
| 	return slog.String(key, value) | ||||
| } | ||||
| 
 | ||||
| // Int64 returns an Attr for an int64. | ||||
| func Int64(key string, value int64) Attr { | ||||
| 	return slog.Int64(key, value) | ||||
| } | ||||
| 
 | ||||
| // Int converts an int to an int64 and returns | ||||
| // an Attr with that value. | ||||
| func Int(key string, value int) Attr { | ||||
| 	return slog.Int(key, value) | ||||
| } | ||||
| 
 | ||||
| // Uint64 returns an Attr for a uint64. | ||||
| func Uint64(key string, v uint64) Attr { | ||||
| 	return slog.Uint64(key, v) | ||||
| } | ||||
| 
 | ||||
| // Float64 returns an Attr for a floating-point number. | ||||
| func Float64(key string, v float64) Attr { | ||||
| 	return slog.Float64(key, v) | ||||
| } | ||||
| 
 | ||||
| // Bool returns an Attr for a bool. | ||||
| func Bool(key string, v bool) Attr { | ||||
| 	return slog.Bool(key, v) | ||||
| } | ||||
| 
 | ||||
| // Time returns an Attr for a time.Time. | ||||
| // It discards the monotonic portion. | ||||
| func Time(key string, v time.Time) Attr { | ||||
| 	return slog.Time(key, v) | ||||
| } | ||||
| 
 | ||||
| // Duration returns an Attr for a time.Duration. | ||||
| func Duration(key string, v time.Duration) Attr { | ||||
| 	return slog.Duration(key, v) | ||||
| } | ||||
| 
 | ||||
| // Group returns an Attr for a Group Value. | ||||
| // The first argument is the key; the remaining arguments | ||||
| // are converted to Attrs as in [Logger.Log]. | ||||
| // | ||||
| // Use Group to collect several key-value pairs under a single | ||||
| // key on a log line, or as the result of LogValue | ||||
| // in order to log a single value as multiple Attrs. | ||||
| func Group(key string, args ...any) Attr { | ||||
| 	return slog.Group(key, args...) | ||||
| } | ||||
| 
 | ||||
| // Any returns an Attr for the supplied value. | ||||
| // See [Value.AnyValue] for how values are treated. | ||||
| func Any(key string, value any) Attr { | ||||
| 	return slog.Any(key, value) | ||||
| } | ||||
							
								
								
									
										75
									
								
								vendor/github.com/sagikazarmark/slog-shim/attr_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/github.com/sagikazarmark/slog-shim/attr_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,75 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // An Attr is a key-value pair. | ||||
| type Attr = slog.Attr | ||||
| 
 | ||||
| // String returns an Attr for a string value. | ||||
| func String(key, value string) Attr { | ||||
| 	return slog.String(key, value) | ||||
| } | ||||
| 
 | ||||
| // Int64 returns an Attr for an int64. | ||||
| func Int64(key string, value int64) Attr { | ||||
| 	return slog.Int64(key, value) | ||||
| } | ||||
| 
 | ||||
| // Int converts an int to an int64 and returns | ||||
| // an Attr with that value. | ||||
| func Int(key string, value int) Attr { | ||||
| 	return slog.Int(key, value) | ||||
| } | ||||
| 
 | ||||
| // Uint64 returns an Attr for a uint64. | ||||
| func Uint64(key string, v uint64) Attr { | ||||
| 	return slog.Uint64(key, v) | ||||
| } | ||||
| 
 | ||||
| // Float64 returns an Attr for a floating-point number. | ||||
| func Float64(key string, v float64) Attr { | ||||
| 	return slog.Float64(key, v) | ||||
| } | ||||
| 
 | ||||
| // Bool returns an Attr for a bool. | ||||
| func Bool(key string, v bool) Attr { | ||||
| 	return slog.Bool(key, v) | ||||
| } | ||||
| 
 | ||||
| // Time returns an Attr for a time.Time. | ||||
| // It discards the monotonic portion. | ||||
| func Time(key string, v time.Time) Attr { | ||||
| 	return slog.Time(key, v) | ||||
| } | ||||
| 
 | ||||
| // Duration returns an Attr for a time.Duration. | ||||
| func Duration(key string, v time.Duration) Attr { | ||||
| 	return slog.Duration(key, v) | ||||
| } | ||||
| 
 | ||||
| // Group returns an Attr for a Group Value. | ||||
| // The first argument is the key; the remaining arguments | ||||
| // are converted to Attrs as in [Logger.Log]. | ||||
| // | ||||
| // Use Group to collect several key-value pairs under a single | ||||
| // key on a log line, or as the result of LogValue | ||||
| // in order to log a single value as multiple Attrs. | ||||
| func Group(key string, args ...any) Attr { | ||||
| 	return slog.Group(key, args...) | ||||
| } | ||||
| 
 | ||||
| // Any returns an Attr for the supplied value. | ||||
| // See [Value.AnyValue] for how values are treated. | ||||
| func Any(key string, value any) Attr { | ||||
| 	return slog.Any(key, value) | ||||
| } | ||||
							
								
								
									
										273
									
								
								vendor/github.com/sagikazarmark/slog-shim/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										273
									
								
								vendor/github.com/sagikazarmark/slog-shim/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,273 +0,0 @@ | |||
| { | ||||
|   "nodes": { | ||||
|     "devenv": { | ||||
|       "inputs": { | ||||
|         "flake-compat": "flake-compat", | ||||
|         "nix": "nix", | ||||
|         "nixpkgs": "nixpkgs", | ||||
|         "pre-commit-hooks": "pre-commit-hooks" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1694097209, | ||||
|         "narHash": "sha256-gQmBjjxeSyySjbh0yQVBKApo2KWIFqqbRUvG+Fa+QpM=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "7a8e6a91510efe89d8dcb8e43233f93e86f6b189", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-compat": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1673956053, | ||||
|         "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-parts": { | ||||
|       "inputs": { | ||||
|         "nixpkgs-lib": "nixpkgs-lib" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1693611461, | ||||
|         "narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "flake-parts", | ||||
|         "rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "flake-parts", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-utils": { | ||||
|       "inputs": { | ||||
|         "systems": "systems" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1685518550, | ||||
|         "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "gitignore": { | ||||
|       "inputs": { | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "pre-commit-hooks", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1660459072, | ||||
|         "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "gitignore.nix", | ||||
|         "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "gitignore.nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "lowdown-src": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1633514407, | ||||
|         "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", | ||||
|         "owner": "kristapsdz", | ||||
|         "repo": "lowdown", | ||||
|         "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "kristapsdz", | ||||
|         "repo": "lowdown", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix": { | ||||
|       "inputs": { | ||||
|         "lowdown-src": "lowdown-src", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1676545802, | ||||
|         "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "relaxed-flakes", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs": { | ||||
|       "locked": { | ||||
|         "lastModified": 1678875422, | ||||
|         "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixpkgs-unstable", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-lib": { | ||||
|       "locked": { | ||||
|         "dir": "lib", | ||||
|         "lastModified": 1693471703, | ||||
|         "narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "dir": "lib", | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-unstable", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-regression": { | ||||
|       "locked": { | ||||
|         "lastModified": 1643052045, | ||||
|         "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-stable": { | ||||
|       "locked": { | ||||
|         "lastModified": 1685801374, | ||||
|         "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-23.05", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1694345580, | ||||
|         "narHash": "sha256-BbG0NUxQTz1dN/Y87yPWZc/0Kp/coJ0vM3+7sNa5kUM=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "f002de6834fdde9c864f33c1ec51da7df19cd832", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "master", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "pre-commit-hooks": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "flake-utils": "flake-utils", | ||||
|         "gitignore": "gitignore", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-stable": "nixpkgs-stable" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1688056373, | ||||
|         "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "pre-commit-hooks.nix", | ||||
|         "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "pre-commit-hooks.nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "root": { | ||||
|       "inputs": { | ||||
|         "devenv": "devenv", | ||||
|         "flake-parts": "flake-parts", | ||||
|         "nixpkgs": "nixpkgs_2" | ||||
|       } | ||||
|     }, | ||||
|     "systems": { | ||||
|       "locked": { | ||||
|         "lastModified": 1681028828, | ||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "root": "root", | ||||
|   "version": 7 | ||||
| } | ||||
							
								
								
									
										45
									
								
								vendor/github.com/sagikazarmark/slog-shim/handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/sagikazarmark/slog-shim/handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,45 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"log/slog" | ||||
| ) | ||||
| 
 | ||||
| // A Handler handles log records produced by a Logger.. | ||||
| // | ||||
| // A typical handler may print log records to standard error, | ||||
| // or write them to a file or database, or perhaps augment them | ||||
| // with additional attributes and pass them on to another handler. | ||||
| // | ||||
| // Any of the Handler's methods may be called concurrently with itself | ||||
| // or with other methods. It is the responsibility of the Handler to | ||||
| // manage this concurrency. | ||||
| // | ||||
| // Users of the slog package should not invoke Handler methods directly. | ||||
| // They should use the methods of [Logger] instead. | ||||
| type Handler = slog.Handler | ||||
| 
 | ||||
| // HandlerOptions are options for a TextHandler or JSONHandler. | ||||
| // A zero HandlerOptions consists entirely of default values. | ||||
| type HandlerOptions = slog.HandlerOptions | ||||
| 
 | ||||
| // Keys for "built-in" attributes. | ||||
| const ( | ||||
| 	// TimeKey is the key used by the built-in handlers for the time | ||||
| 	// when the log method is called. The associated Value is a [time.Time]. | ||||
| 	TimeKey = slog.TimeKey | ||||
| 	// LevelKey is the key used by the built-in handlers for the level | ||||
| 	// of the log call. The associated value is a [Level]. | ||||
| 	LevelKey = slog.LevelKey | ||||
| 	// MessageKey is the key used by the built-in handlers for the | ||||
| 	// message of the log call. The associated value is a string. | ||||
| 	MessageKey = slog.MessageKey | ||||
| 	// SourceKey is the key used by the built-in handlers for the source file | ||||
| 	// and line of the log call. The associated value is a string. | ||||
| 	SourceKey = slog.SourceKey | ||||
| ) | ||||
							
								
								
									
										45
									
								
								vendor/github.com/sagikazarmark/slog-shim/handler_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/sagikazarmark/slog-shim/handler_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,45 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // A Handler handles log records produced by a Logger.. | ||||
| // | ||||
| // A typical handler may print log records to standard error, | ||||
| // or write them to a file or database, or perhaps augment them | ||||
| // with additional attributes and pass them on to another handler. | ||||
| // | ||||
| // Any of the Handler's methods may be called concurrently with itself | ||||
| // or with other methods. It is the responsibility of the Handler to | ||||
| // manage this concurrency. | ||||
| // | ||||
| // Users of the slog package should not invoke Handler methods directly. | ||||
| // They should use the methods of [Logger] instead. | ||||
| type Handler = slog.Handler | ||||
| 
 | ||||
| // HandlerOptions are options for a TextHandler or JSONHandler. | ||||
| // A zero HandlerOptions consists entirely of default values. | ||||
| type HandlerOptions = slog.HandlerOptions | ||||
| 
 | ||||
| // Keys for "built-in" attributes. | ||||
| const ( | ||||
| 	// TimeKey is the key used by the built-in handlers for the time | ||||
| 	// when the log method is called. The associated Value is a [time.Time]. | ||||
| 	TimeKey = slog.TimeKey | ||||
| 	// LevelKey is the key used by the built-in handlers for the level | ||||
| 	// of the log call. The associated value is a [Level]. | ||||
| 	LevelKey = slog.LevelKey | ||||
| 	// MessageKey is the key used by the built-in handlers for the | ||||
| 	// message of the log call. The associated value is a string. | ||||
| 	MessageKey = slog.MessageKey | ||||
| 	// SourceKey is the key used by the built-in handlers for the source file | ||||
| 	// and line of the log call. The associated value is a string. | ||||
| 	SourceKey = slog.SourceKey | ||||
| ) | ||||
							
								
								
									
										23
									
								
								vendor/github.com/sagikazarmark/slog-shim/json_handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/sagikazarmark/slog-shim/json_handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,23 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 	"log/slog" | ||||
| ) | ||||
| 
 | ||||
| // JSONHandler is a Handler that writes Records to an io.Writer as | ||||
| // line-delimited JSON objects. | ||||
| type JSONHandler = slog.JSONHandler | ||||
| 
 | ||||
| // NewJSONHandler creates a JSONHandler that writes to w, | ||||
| // using the given options. | ||||
| // If opts is nil, the default options are used. | ||||
| func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler { | ||||
| 	return slog.NewJSONHandler(w, opts) | ||||
| } | ||||
							
								
								
									
										24
									
								
								vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,24 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 
 | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // JSONHandler is a Handler that writes Records to an io.Writer as | ||||
| // line-delimited JSON objects. | ||||
| type JSONHandler = slog.JSONHandler | ||||
| 
 | ||||
| // NewJSONHandler creates a JSONHandler that writes to w, | ||||
| // using the given options. | ||||
| // If opts is nil, the default options are used. | ||||
| func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler { | ||||
| 	return slog.NewJSONHandler(w, opts) | ||||
| } | ||||
							
								
								
									
										61
									
								
								vendor/github.com/sagikazarmark/slog-shim/level.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/sagikazarmark/slog-shim/level.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,61 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"log/slog" | ||||
| ) | ||||
| 
 | ||||
| // A Level is the importance or severity of a log event. | ||||
| // The higher the level, the more important or severe the event. | ||||
| type Level = slog.Level | ||||
| 
 | ||||
| // Level numbers are inherently arbitrary, | ||||
| // but we picked them to satisfy three constraints. | ||||
| // Any system can map them to another numbering scheme if it wishes. | ||||
| // | ||||
| // First, we wanted the default level to be Info, Since Levels are ints, Info is | ||||
| // the default value for int, zero. | ||||
| // | ||||
| // Second, we wanted to make it easy to use levels to specify logger verbosity. | ||||
| // Since a larger level means a more severe event, a logger that accepts events | ||||
| // with smaller (or more negative) level means a more verbose logger. Logger | ||||
| // verbosity is thus the negation of event severity, and the default verbosity | ||||
| // of 0 accepts all events at least as severe as INFO. | ||||
| // | ||||
| // Third, we wanted some room between levels to accommodate schemes with named | ||||
| // levels between ours. For example, Google Cloud Logging defines a Notice level | ||||
| // between Info and Warn. Since there are only a few of these intermediate | ||||
| // levels, the gap between the numbers need not be large. Our gap of 4 matches | ||||
| // OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the | ||||
| // DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog | ||||
| // Level range. OpenTelemetry also has the names TRACE and FATAL, which slog | ||||
| // does not. But those OpenTelemetry levels can still be represented as slog | ||||
| // Levels by using the appropriate integers. | ||||
| // | ||||
| // Names for common levels. | ||||
| const ( | ||||
| 	LevelDebug Level = slog.LevelDebug | ||||
| 	LevelInfo  Level = slog.LevelInfo | ||||
| 	LevelWarn  Level = slog.LevelWarn | ||||
| 	LevelError Level = slog.LevelError | ||||
| ) | ||||
| 
 | ||||
| // A LevelVar is a Level variable, to allow a Handler level to change | ||||
| // dynamically. | ||||
| // It implements Leveler as well as a Set method, | ||||
| // and it is safe for use by multiple goroutines. | ||||
| // The zero LevelVar corresponds to LevelInfo. | ||||
| type LevelVar = slog.LevelVar | ||||
| 
 | ||||
| // A Leveler provides a Level value. | ||||
| // | ||||
| // As Level itself implements Leveler, clients typically supply | ||||
| // a Level value wherever a Leveler is needed, such as in HandlerOptions. | ||||
| // Clients who need to vary the level dynamically can provide a more complex | ||||
| // Leveler implementation such as *LevelVar. | ||||
| type Leveler = slog.Leveler | ||||
							
								
								
									
										61
									
								
								vendor/github.com/sagikazarmark/slog-shim/level_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/sagikazarmark/slog-shim/level_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,61 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // A Level is the importance or severity of a log event. | ||||
| // The higher the level, the more important or severe the event. | ||||
| type Level = slog.Level | ||||
| 
 | ||||
| // Level numbers are inherently arbitrary, | ||||
| // but we picked them to satisfy three constraints. | ||||
| // Any system can map them to another numbering scheme if it wishes. | ||||
| // | ||||
| // First, we wanted the default level to be Info, Since Levels are ints, Info is | ||||
| // the default value for int, zero. | ||||
| // | ||||
| // Second, we wanted to make it easy to use levels to specify logger verbosity. | ||||
| // Since a larger level means a more severe event, a logger that accepts events | ||||
| // with smaller (or more negative) level means a more verbose logger. Logger | ||||
| // verbosity is thus the negation of event severity, and the default verbosity | ||||
| // of 0 accepts all events at least as severe as INFO. | ||||
| // | ||||
| // Third, we wanted some room between levels to accommodate schemes with named | ||||
| // levels between ours. For example, Google Cloud Logging defines a Notice level | ||||
| // between Info and Warn. Since there are only a few of these intermediate | ||||
| // levels, the gap between the numbers need not be large. Our gap of 4 matches | ||||
| // OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the | ||||
| // DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog | ||||
| // Level range. OpenTelemetry also has the names TRACE and FATAL, which slog | ||||
| // does not. But those OpenTelemetry levels can still be represented as slog | ||||
| // Levels by using the appropriate integers. | ||||
| // | ||||
| // Names for common levels. | ||||
| const ( | ||||
| 	LevelDebug Level = slog.LevelDebug | ||||
| 	LevelInfo  Level = slog.LevelInfo | ||||
| 	LevelWarn  Level = slog.LevelWarn | ||||
| 	LevelError Level = slog.LevelError | ||||
| ) | ||||
| 
 | ||||
| // A LevelVar is a Level variable, to allow a Handler level to change | ||||
| // dynamically. | ||||
| // It implements Leveler as well as a Set method, | ||||
| // and it is safe for use by multiple goroutines. | ||||
| // The zero LevelVar corresponds to LevelInfo. | ||||
| type LevelVar = slog.LevelVar | ||||
| 
 | ||||
| // A Leveler provides a Level value. | ||||
| // | ||||
| // As Level itself implements Leveler, clients typically supply | ||||
| // a Level value wherever a Leveler is needed, such as in HandlerOptions. | ||||
| // Clients who need to vary the level dynamically can provide a more complex | ||||
| // Leveler implementation such as *LevelVar. | ||||
| type Leveler = slog.Leveler | ||||
							
								
								
									
										98
									
								
								vendor/github.com/sagikazarmark/slog-shim/logger.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/sagikazarmark/slog-shim/logger.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,98 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"log" | ||||
| 	"log/slog" | ||||
| ) | ||||
| 
 | ||||
| // Default returns the default Logger. | ||||
| func Default() *Logger { return slog.Default() } | ||||
| 
 | ||||
| // SetDefault makes l the default Logger. | ||||
| // After this call, output from the log package's default Logger | ||||
| // (as with [log.Print], etc.) will be logged at LevelInfo using l's Handler. | ||||
| func SetDefault(l *Logger) { | ||||
| 	slog.SetDefault(l) | ||||
| } | ||||
| 
 | ||||
| // A Logger records structured information about each call to its | ||||
| // Log, Debug, Info, Warn, and Error methods. | ||||
| // For each call, it creates a Record and passes it to a Handler. | ||||
| // | ||||
| // To create a new Logger, call [New] or a Logger method | ||||
| // that begins "With". | ||||
| type Logger = slog.Logger | ||||
| 
 | ||||
| // New creates a new Logger with the given non-nil Handler. | ||||
| func New(h Handler) *Logger { | ||||
| 	return slog.New(h) | ||||
| } | ||||
| 
 | ||||
| // With calls Logger.With on the default logger. | ||||
| func With(args ...any) *Logger { | ||||
| 	return slog.With(args...) | ||||
| } | ||||
| 
 | ||||
| // NewLogLogger returns a new log.Logger such that each call to its Output method | ||||
| // dispatches a Record to the specified handler. The logger acts as a bridge from | ||||
| // the older log API to newer structured logging handlers. | ||||
| func NewLogLogger(h Handler, level Level) *log.Logger { | ||||
| 	return slog.NewLogLogger(h, level) | ||||
| } | ||||
| 
 | ||||
| // Debug calls Logger.Debug on the default logger. | ||||
| func Debug(msg string, args ...any) { | ||||
| 	slog.Debug(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // DebugContext calls Logger.DebugContext on the default logger. | ||||
| func DebugContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.DebugContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Info calls Logger.Info on the default logger. | ||||
| func Info(msg string, args ...any) { | ||||
| 	slog.Info(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // InfoContext calls Logger.InfoContext on the default logger. | ||||
| func InfoContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.InfoContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Warn calls Logger.Warn on the default logger. | ||||
| func Warn(msg string, args ...any) { | ||||
| 	slog.Warn(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // WarnContext calls Logger.WarnContext on the default logger. | ||||
| func WarnContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.WarnContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Error calls Logger.Error on the default logger. | ||||
| func Error(msg string, args ...any) { | ||||
| 	slog.Error(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // ErrorContext calls Logger.ErrorContext on the default logger. | ||||
| func ErrorContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.ErrorContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Log calls Logger.Log on the default logger. | ||||
| func Log(ctx context.Context, level Level, msg string, args ...any) { | ||||
| 	slog.Log(ctx, level, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // LogAttrs calls Logger.LogAttrs on the default logger. | ||||
| func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) { | ||||
| 	slog.LogAttrs(ctx, level, msg, attrs...) | ||||
| } | ||||
							
								
								
									
										99
									
								
								vendor/github.com/sagikazarmark/slog-shim/logger_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										99
									
								
								vendor/github.com/sagikazarmark/slog-shim/logger_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,99 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"log" | ||||
| 
 | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // Default returns the default Logger. | ||||
| func Default() *Logger { return slog.Default() } | ||||
| 
 | ||||
| // SetDefault makes l the default Logger. | ||||
| // After this call, output from the log package's default Logger | ||||
| // (as with [log.Print], etc.) will be logged at LevelInfo using l's Handler. | ||||
| func SetDefault(l *Logger) { | ||||
| 	slog.SetDefault(l) | ||||
| } | ||||
| 
 | ||||
| // A Logger records structured information about each call to its | ||||
| // Log, Debug, Info, Warn, and Error methods. | ||||
| // For each call, it creates a Record and passes it to a Handler. | ||||
| // | ||||
| // To create a new Logger, call [New] or a Logger method | ||||
| // that begins "With". | ||||
| type Logger = slog.Logger | ||||
| 
 | ||||
| // New creates a new Logger with the given non-nil Handler. | ||||
| func New(h Handler) *Logger { | ||||
| 	return slog.New(h) | ||||
| } | ||||
| 
 | ||||
| // With calls Logger.With on the default logger. | ||||
| func With(args ...any) *Logger { | ||||
| 	return slog.With(args...) | ||||
| } | ||||
| 
 | ||||
| // NewLogLogger returns a new log.Logger such that each call to its Output method | ||||
| // dispatches a Record to the specified handler. The logger acts as a bridge from | ||||
| // the older log API to newer structured logging handlers. | ||||
| func NewLogLogger(h Handler, level Level) *log.Logger { | ||||
| 	return slog.NewLogLogger(h, level) | ||||
| } | ||||
| 
 | ||||
| // Debug calls Logger.Debug on the default logger. | ||||
| func Debug(msg string, args ...any) { | ||||
| 	slog.Debug(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // DebugContext calls Logger.DebugContext on the default logger. | ||||
| func DebugContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.DebugContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Info calls Logger.Info on the default logger. | ||||
| func Info(msg string, args ...any) { | ||||
| 	slog.Info(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // InfoContext calls Logger.InfoContext on the default logger. | ||||
| func InfoContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.InfoContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Warn calls Logger.Warn on the default logger. | ||||
| func Warn(msg string, args ...any) { | ||||
| 	slog.Warn(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // WarnContext calls Logger.WarnContext on the default logger. | ||||
| func WarnContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.WarnContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Error calls Logger.Error on the default logger. | ||||
| func Error(msg string, args ...any) { | ||||
| 	slog.Error(msg, args...) | ||||
| } | ||||
| 
 | ||||
| // ErrorContext calls Logger.ErrorContext on the default logger. | ||||
| func ErrorContext(ctx context.Context, msg string, args ...any) { | ||||
| 	slog.ErrorContext(ctx, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // Log calls Logger.Log on the default logger. | ||||
| func Log(ctx context.Context, level Level, msg string, args ...any) { | ||||
| 	slog.Log(ctx, level, msg, args...) | ||||
| } | ||||
| 
 | ||||
| // LogAttrs calls Logger.LogAttrs on the default logger. | ||||
| func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) { | ||||
| 	slog.LogAttrs(ctx, level, msg, attrs...) | ||||
| } | ||||
							
								
								
									
										31
									
								
								vendor/github.com/sagikazarmark/slog-shim/record.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/sagikazarmark/slog-shim/record.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,31 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"log/slog" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // A Record holds information about a log event. | ||||
| // Copies of a Record share state. | ||||
| // Do not modify a Record after handing out a copy to it. | ||||
| // Call [NewRecord] to create a new Record. | ||||
| // Use [Record.Clone] to create a copy with no shared state. | ||||
| type Record = slog.Record | ||||
| 
 | ||||
| // NewRecord creates a Record from the given arguments. | ||||
| // Use [Record.AddAttrs] to add attributes to the Record. | ||||
| // | ||||
| // NewRecord is intended for logging APIs that want to support a [Handler] as | ||||
| // a backend. | ||||
| func NewRecord(t time.Time, level Level, msg string, pc uintptr) Record { | ||||
| 	return slog.NewRecord(t, level, msg, pc) | ||||
| } | ||||
| 
 | ||||
| // Source describes the location of a line of source code. | ||||
| type Source = slog.Source | ||||
							
								
								
									
										32
									
								
								vendor/github.com/sagikazarmark/slog-shim/record_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/sagikazarmark/slog-shim/record_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,32 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // A Record holds information about a log event. | ||||
| // Copies of a Record share state. | ||||
| // Do not modify a Record after handing out a copy to it. | ||||
| // Call [NewRecord] to create a new Record. | ||||
| // Use [Record.Clone] to create a copy with no shared state. | ||||
| type Record = slog.Record | ||||
| 
 | ||||
| // NewRecord creates a Record from the given arguments. | ||||
| // Use [Record.AddAttrs] to add attributes to the Record. | ||||
| // | ||||
| // NewRecord is intended for logging APIs that want to support a [Handler] as | ||||
| // a backend. | ||||
| func NewRecord(t time.Time, level Level, msg string, pc uintptr) Record { | ||||
| 	return slog.NewRecord(t, level, msg, pc) | ||||
| } | ||||
| 
 | ||||
| // Source describes the location of a line of source code. | ||||
| type Source = slog.Source | ||||
							
								
								
									
										23
									
								
								vendor/github.com/sagikazarmark/slog-shim/text_handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/sagikazarmark/slog-shim/text_handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,23 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 	"log/slog" | ||||
| ) | ||||
| 
 | ||||
| // TextHandler is a Handler that writes Records to an io.Writer as a | ||||
| // sequence of key=value pairs separated by spaces and followed by a newline. | ||||
| type TextHandler = slog.TextHandler | ||||
| 
 | ||||
| // NewTextHandler creates a TextHandler that writes to w, | ||||
| // using the given options. | ||||
| // If opts is nil, the default options are used. | ||||
| func NewTextHandler(w io.Writer, opts *HandlerOptions) *TextHandler { | ||||
| 	return slog.NewTextHandler(w, opts) | ||||
| } | ||||
							
								
								
									
										24
									
								
								vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,24 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 
 | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // TextHandler is a Handler that writes Records to an io.Writer as a | ||||
| // sequence of key=value pairs separated by spaces and followed by a newline. | ||||
| type TextHandler = slog.TextHandler | ||||
| 
 | ||||
| // NewTextHandler creates a TextHandler that writes to w, | ||||
| // using the given options. | ||||
| // If opts is nil, the default options are used. | ||||
| func NewTextHandler(w io.Writer, opts *HandlerOptions) *TextHandler { | ||||
| 	return slog.NewTextHandler(w, opts) | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/github.com/sagikazarmark/slog-shim/value.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/sagikazarmark/slog-shim/value.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,109 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"log/slog" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // A Value can represent any Go value, but unlike type any, | ||||
| // it can represent most small values without an allocation. | ||||
| // The zero Value corresponds to nil. | ||||
| type Value = slog.Value | ||||
| 
 | ||||
| // Kind is the kind of a Value. | ||||
| type Kind = slog.Kind | ||||
| 
 | ||||
| // The following list is sorted alphabetically, but it's also important that | ||||
| // KindAny is 0 so that a zero Value represents nil. | ||||
| const ( | ||||
| 	KindAny       = slog.KindAny | ||||
| 	KindBool      = slog.KindBool | ||||
| 	KindDuration  = slog.KindDuration | ||||
| 	KindFloat64   = slog.KindFloat64 | ||||
| 	KindInt64     = slog.KindInt64 | ||||
| 	KindString    = slog.KindString | ||||
| 	KindTime      = slog.KindTime | ||||
| 	KindUint64    = slog.KindUint64 | ||||
| 	KindGroup     = slog.KindGroup | ||||
| 	KindLogValuer = slog.KindLogValuer | ||||
| ) | ||||
| 
 | ||||
| //////////////// Constructors | ||||
| 
 | ||||
| // StringValue returns a new Value for a string. | ||||
| func StringValue(value string) Value { | ||||
| 	return slog.StringValue(value) | ||||
| } | ||||
| 
 | ||||
| // IntValue returns a Value for an int. | ||||
| func IntValue(v int) Value { | ||||
| 	return slog.IntValue(v) | ||||
| } | ||||
| 
 | ||||
| // Int64Value returns a Value for an int64. | ||||
| func Int64Value(v int64) Value { | ||||
| 	return slog.Int64Value(v) | ||||
| } | ||||
| 
 | ||||
| // Uint64Value returns a Value for a uint64. | ||||
| func Uint64Value(v uint64) Value { | ||||
| 	return slog.Uint64Value(v) | ||||
| } | ||||
| 
 | ||||
| // Float64Value returns a Value for a floating-point number. | ||||
| func Float64Value(v float64) Value { | ||||
| 	return slog.Float64Value(v) | ||||
| } | ||||
| 
 | ||||
| // BoolValue returns a Value for a bool. | ||||
| func BoolValue(v bool) Value { | ||||
| 	return slog.BoolValue(v) | ||||
| } | ||||
| 
 | ||||
| // TimeValue returns a Value for a time.Time. | ||||
| // It discards the monotonic portion. | ||||
| func TimeValue(v time.Time) Value { | ||||
| 	return slog.TimeValue(v) | ||||
| } | ||||
| 
 | ||||
| // DurationValue returns a Value for a time.Duration. | ||||
| func DurationValue(v time.Duration) Value { | ||||
| 	return slog.DurationValue(v) | ||||
| } | ||||
| 
 | ||||
| // GroupValue returns a new Value for a list of Attrs. | ||||
| // The caller must not subsequently mutate the argument slice. | ||||
| func GroupValue(as ...Attr) Value { | ||||
| 	return slog.GroupValue(as...) | ||||
| } | ||||
| 
 | ||||
| // AnyValue returns a Value for the supplied value. | ||||
| // | ||||
| // If the supplied value is of type Value, it is returned | ||||
| // unmodified. | ||||
| // | ||||
| // Given a value of one of Go's predeclared string, bool, or | ||||
| // (non-complex) numeric types, AnyValue returns a Value of kind | ||||
| // String, Bool, Uint64, Int64, or Float64. The width of the | ||||
| // original numeric type is not preserved. | ||||
| // | ||||
| // Given a time.Time or time.Duration value, AnyValue returns a Value of kind | ||||
| // KindTime or KindDuration. The monotonic time is not preserved. | ||||
| // | ||||
| // For nil, or values of all other types, including named types whose | ||||
| // underlying type is numeric, AnyValue returns a value of kind KindAny. | ||||
| func AnyValue(v any) Value { | ||||
| 	return slog.AnyValue(v) | ||||
| } | ||||
| 
 | ||||
| // A LogValuer is any Go value that can convert itself into a Value for logging. | ||||
| // | ||||
| // This mechanism may be used to defer expensive operations until they are | ||||
| // needed, or to expand a single value into a sequence of components. | ||||
| type LogValuer = slog.LogValuer | ||||
							
								
								
									
										110
									
								
								vendor/github.com/sagikazarmark/slog-shim/value_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/sagikazarmark/slog-shim/value_120.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,110 +0,0 @@ | |||
| // Copyright 2022 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !go1.21 | ||||
| 
 | ||||
| package slog | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"golang.org/x/exp/slog" | ||||
| ) | ||||
| 
 | ||||
| // A Value can represent any Go value, but unlike type any, | ||||
| // it can represent most small values without an allocation. | ||||
| // The zero Value corresponds to nil. | ||||
| type Value = slog.Value | ||||
| 
 | ||||
| // Kind is the kind of a Value. | ||||
| type Kind = slog.Kind | ||||
| 
 | ||||
| // The following list is sorted alphabetically, but it's also important that | ||||
| // KindAny is 0 so that a zero Value represents nil. | ||||
| const ( | ||||
| 	KindAny       = slog.KindAny | ||||
| 	KindBool      = slog.KindBool | ||||
| 	KindDuration  = slog.KindDuration | ||||
| 	KindFloat64   = slog.KindFloat64 | ||||
| 	KindInt64     = slog.KindInt64 | ||||
| 	KindString    = slog.KindString | ||||
| 	KindTime      = slog.KindTime | ||||
| 	KindUint64    = slog.KindUint64 | ||||
| 	KindGroup     = slog.KindGroup | ||||
| 	KindLogValuer = slog.KindLogValuer | ||||
| ) | ||||
| 
 | ||||
| //////////////// Constructors | ||||
| 
 | ||||
| // StringValue returns a new Value for a string. | ||||
| func StringValue(value string) Value { | ||||
| 	return slog.StringValue(value) | ||||
| } | ||||
| 
 | ||||
| // IntValue returns a Value for an int. | ||||
| func IntValue(v int) Value { | ||||
| 	return slog.IntValue(v) | ||||
| } | ||||
| 
 | ||||
| // Int64Value returns a Value for an int64. | ||||
| func Int64Value(v int64) Value { | ||||
| 	return slog.Int64Value(v) | ||||
| } | ||||
| 
 | ||||
| // Uint64Value returns a Value for a uint64. | ||||
| func Uint64Value(v uint64) Value { | ||||
| 	return slog.Uint64Value(v) | ||||
| } | ||||
| 
 | ||||
| // Float64Value returns a Value for a floating-point number. | ||||
| func Float64Value(v float64) Value { | ||||
| 	return slog.Float64Value(v) | ||||
| } | ||||
| 
 | ||||
| // BoolValue returns a Value for a bool. | ||||
| func BoolValue(v bool) Value { | ||||
| 	return slog.BoolValue(v) | ||||
| } | ||||
| 
 | ||||
| // TimeValue returns a Value for a time.Time. | ||||
| // It discards the monotonic portion. | ||||
| func TimeValue(v time.Time) Value { | ||||
| 	return slog.TimeValue(v) | ||||
| } | ||||
| 
 | ||||
| // DurationValue returns a Value for a time.Duration. | ||||
| func DurationValue(v time.Duration) Value { | ||||
| 	return slog.DurationValue(v) | ||||
| } | ||||
| 
 | ||||
| // GroupValue returns a new Value for a list of Attrs. | ||||
| // The caller must not subsequently mutate the argument slice. | ||||
| func GroupValue(as ...Attr) Value { | ||||
| 	return slog.GroupValue(as...) | ||||
| } | ||||
| 
 | ||||
| // AnyValue returns a Value for the supplied value. | ||||
| // | ||||
| // If the supplied value is of type Value, it is returned | ||||
| // unmodified. | ||||
| // | ||||
| // Given a value of one of Go's predeclared string, bool, or | ||||
| // (non-complex) numeric types, AnyValue returns a Value of kind | ||||
| // String, Bool, Uint64, Int64, or Float64. The width of the | ||||
| // original numeric type is not preserved. | ||||
| // | ||||
| // Given a time.Time or time.Duration value, AnyValue returns a Value of kind | ||||
| // KindTime or KindDuration. The monotonic time is not preserved. | ||||
| // | ||||
| // For nil, or values of all other types, including named types whose | ||||
| // underlying type is numeric, AnyValue returns a value of kind KindAny. | ||||
| func AnyValue(v any) Value { | ||||
| 	return slog.AnyValue(v) | ||||
| } | ||||
| 
 | ||||
| // A LogValuer is any Go value that can convert itself into a Value for logging. | ||||
| // | ||||
| // This mechanism may be used to defer expensive operations until they are | ||||
| // needed, or to expand a single value into a sequence of components. | ||||
| type LogValuer = slog.LogValuer | ||||
							
								
								
									
										8
									
								
								vendor/gopkg.in/ini.v1/.editorconfig → vendor/github.com/spf13/afero/.editorconfig
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/gopkg.in/ini.v1/.editorconfig → vendor/github.com/spf13/afero/.editorconfig
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,12 +1,12 @@ | |||
| # http://editorconfig.org | ||||
| 
 | ||||
| root = true | ||||
| 
 | ||||
| [*] | ||||
| charset = utf-8 | ||||
| end_of_line = lf | ||||
| indent_size = 4 | ||||
| indent_style = space | ||||
| insert_final_newline = true | ||||
| trim_trailing_whitespace = true | ||||
| 
 | ||||
| [*_test.go] | ||||
| trim_trailing_whitespace = false | ||||
| [*.go] | ||||
| indent_style = tab | ||||
							
								
								
									
										18
									
								
								vendor/github.com/spf13/afero/.golangci.yaml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/spf13/afero/.golangci.yaml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| linters-settings: | ||||
|     gci: | ||||
|         sections: | ||||
|             - standard | ||||
|             - default | ||||
|             - prefix(github.com/spf13/afero) | ||||
| 
 | ||||
| linters: | ||||
|     disable-all: true | ||||
|     enable: | ||||
|         - gci | ||||
|         - gofmt | ||||
|         - gofumpt | ||||
|         - staticcheck | ||||
| 
 | ||||
| issues: | ||||
|     exclude-dirs: | ||||
|         - gcsfs/internal/stiface | ||||
							
								
								
									
										2
									
								
								vendor/github.com/spf13/afero/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/spf13/afero/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -12,7 +12,7 @@ types and methods. Afero has an exceptionally clean interface and simple design | |||
| without needless constructors or initialization methods. | ||||
| 
 | ||||
| Afero is also a library providing a base set of interoperable backend | ||||
| filesystems that make it easy to work with afero while retaining all the power | ||||
| filesystems that make it easy to work with, while retaining all the power | ||||
| and benefit of the os and ioutil packages. | ||||
| 
 | ||||
| Afero provides significant improvements over using the os package alone, most | ||||
|  |  | |||
							
								
								
									
										1
									
								
								vendor/github.com/spf13/afero/iofs.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/spf13/afero/iofs.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -255,7 +255,6 @@ func (f fromIOFSFile) Readdir(count int) ([]os.FileInfo, error) { | |||
| 	ret := make([]os.FileInfo, len(entries)) | ||||
| 	for i := range entries { | ||||
| 		ret[i], err = entries[i].Info() | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										2
									
								
								vendor/github.com/spf13/afero/memmap.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/spf13/afero/memmap.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -16,11 +16,9 @@ package afero | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 
 | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 
 | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  |  | |||
							
								
								
									
										2
									
								
								vendor/github.com/spf13/cast/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/spf13/cast/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,6 @@ | |||
| # cast | ||||
| 
 | ||||
| [](https://github.com/spf13/cast/actions/workflows/ci.yaml) | ||||
| [](https://github.com/spf13/cast/actions/workflows/test.yaml) | ||||
| [](https://pkg.go.dev/mod/github.com/spf13/cast) | ||||
|  | ||||
| [](https://goreportcard.com/report/github.com/spf13/cast) | ||||
|  |  | |||
							
								
								
									
										98
									
								
								vendor/github.com/spf13/cast/caste.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/spf13/cast/caste.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -18,6 +18,14 @@ import ( | |||
| 
 | ||||
| var errNegativeNotAllowed = errors.New("unable to cast negative value") | ||||
| 
 | ||||
| type float64EProvider interface { | ||||
| 	Float64() (float64, error) | ||||
| } | ||||
| 
 | ||||
| type float64Provider interface { | ||||
| 	Float64() float64 | ||||
| } | ||||
| 
 | ||||
| // ToTimeE casts an interface to a time.Time type. | ||||
| func ToTimeE(i interface{}) (tim time.Time, err error) { | ||||
| 	return ToTimeInDefaultLocationE(i, time.UTC) | ||||
|  | @ -77,11 +85,14 @@ func ToDurationE(i interface{}) (d time.Duration, err error) { | |||
| 			d, err = time.ParseDuration(s + "ns") | ||||
| 		} | ||||
| 		return | ||||
| 	case json.Number: | ||||
| 	case float64EProvider: | ||||
| 		var v float64 | ||||
| 		v, err = s.Float64() | ||||
| 		d = time.Duration(v) | ||||
| 		return | ||||
| 	case float64Provider: | ||||
| 		d = time.Duration(s.Float64()) | ||||
| 		return | ||||
| 	default: | ||||
| 		err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i) | ||||
| 		return | ||||
|  | @ -174,12 +185,14 @@ func ToFloat64E(i interface{}) (float64, error) { | |||
| 			return v, nil | ||||
| 		} | ||||
| 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) | ||||
| 	case json.Number: | ||||
| 	case float64EProvider: | ||||
| 		v, err := s.Float64() | ||||
| 		if err == nil { | ||||
| 			return v, nil | ||||
| 		} | ||||
| 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) | ||||
| 	case float64Provider: | ||||
| 		return s.Float64(), nil | ||||
| 	case bool: | ||||
| 		if s { | ||||
| 			return 1, nil | ||||
|  | @ -230,12 +243,14 @@ func ToFloat32E(i interface{}) (float32, error) { | |||
| 			return float32(v), nil | ||||
| 		} | ||||
| 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i) | ||||
| 	case json.Number: | ||||
| 	case float64EProvider: | ||||
| 		v, err := s.Float64() | ||||
| 		if err == nil { | ||||
| 			return float32(v), nil | ||||
| 		} | ||||
| 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i) | ||||
| 	case float64Provider: | ||||
| 		return float32(s.Float64()), nil | ||||
| 	case bool: | ||||
| 		if s { | ||||
| 			return 1, nil | ||||
|  | @ -598,12 +613,12 @@ func ToUint64E(i interface{}) (uint64, error) { | |||
| 
 | ||||
| 	switch s := i.(type) { | ||||
| 	case string: | ||||
| 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0) | ||||
| 		v, err := strconv.ParseUint(trimZeroDecimal(s), 0, 0) | ||||
| 		if err == nil { | ||||
| 			if v < 0 { | ||||
| 				return 0, errNegativeNotAllowed | ||||
| 			} | ||||
| 			return uint64(v), nil | ||||
| 			return v, nil | ||||
| 		} | ||||
| 		return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i) | ||||
| 	case json.Number: | ||||
|  | @ -917,8 +932,8 @@ func indirectToStringerOrError(a interface{}) interface{} { | |||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var errorType = reflect.TypeOf((*error)(nil)).Elem() | ||||
| 	var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() | ||||
| 	errorType := reflect.TypeOf((*error)(nil)).Elem() | ||||
| 	fmtStringerType := reflect.TypeOf((*fmt.Stringer)(nil)).Elem() | ||||
| 
 | ||||
| 	v := reflect.ValueOf(a) | ||||
| 	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() { | ||||
|  | @ -987,7 +1002,7 @@ func ToStringE(i interface{}) (string, error) { | |||
| 
 | ||||
| // ToStringMapStringE casts an interface to a map[string]string type. | ||||
| func ToStringMapStringE(i interface{}) (map[string]string, error) { | ||||
| 	var m = map[string]string{} | ||||
| 	m := map[string]string{} | ||||
| 
 | ||||
| 	switch v := i.(type) { | ||||
| 	case map[string]string: | ||||
|  | @ -1017,7 +1032,7 @@ func ToStringMapStringE(i interface{}) (map[string]string, error) { | |||
| 
 | ||||
| // ToStringMapStringSliceE casts an interface to a map[string][]string type. | ||||
| func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { | ||||
| 	var m = map[string][]string{} | ||||
| 	m := map[string][]string{} | ||||
| 
 | ||||
| 	switch v := i.(type) { | ||||
| 	case map[string][]string: | ||||
|  | @ -1081,7 +1096,7 @@ func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { | |||
| 
 | ||||
| // ToStringMapBoolE casts an interface to a map[string]bool type. | ||||
| func ToStringMapBoolE(i interface{}) (map[string]bool, error) { | ||||
| 	var m = map[string]bool{} | ||||
| 	m := map[string]bool{} | ||||
| 
 | ||||
| 	switch v := i.(type) { | ||||
| 	case map[interface{}]interface{}: | ||||
|  | @ -1106,7 +1121,7 @@ func ToStringMapBoolE(i interface{}) (map[string]bool, error) { | |||
| 
 | ||||
| // ToStringMapE casts an interface to a map[string]interface{} type. | ||||
| func ToStringMapE(i interface{}) (map[string]interface{}, error) { | ||||
| 	var m = map[string]interface{}{} | ||||
| 	m := map[string]interface{}{} | ||||
| 
 | ||||
| 	switch v := i.(type) { | ||||
| 	case map[interface{}]interface{}: | ||||
|  | @ -1126,7 +1141,7 @@ func ToStringMapE(i interface{}) (map[string]interface{}, error) { | |||
| 
 | ||||
| // ToStringMapIntE casts an interface to a map[string]int{} type. | ||||
| func ToStringMapIntE(i interface{}) (map[string]int, error) { | ||||
| 	var m = map[string]int{} | ||||
| 	m := map[string]int{} | ||||
| 	if i == nil { | ||||
| 		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i) | ||||
| 	} | ||||
|  | @ -1167,7 +1182,7 @@ func ToStringMapIntE(i interface{}) (map[string]int, error) { | |||
| 
 | ||||
| // ToStringMapInt64E casts an interface to a map[string]int64{} type. | ||||
| func ToStringMapInt64E(i interface{}) (map[string]int64, error) { | ||||
| 	var m = map[string]int64{} | ||||
| 	m := map[string]int64{} | ||||
| 	if i == nil { | ||||
| 		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i) | ||||
| 	} | ||||
|  | @ -1404,38 +1419,35 @@ func (f timeFormat) hasTimezone() bool { | |||
| 	return f.typ >= timeFormatNumericTimezone && f.typ <= timeFormatNumericAndNamedTimezone | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	timeFormats = []timeFormat{ | ||||
| 		// Keep common formats at the top. | ||||
| 		{"2006-01-02", timeFormatNoTimezone}, | ||||
| 		{time.RFC3339, timeFormatNumericTimezone}, | ||||
| 		{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone | ||||
| 		{time.RFC1123Z, timeFormatNumericTimezone}, | ||||
| 		{time.RFC1123, timeFormatNamedTimezone}, | ||||
| 		{time.RFC822Z, timeFormatNumericTimezone}, | ||||
| 		{time.RFC822, timeFormatNamedTimezone}, | ||||
| 		{time.RFC850, timeFormatNamedTimezone}, | ||||
| 		{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String() | ||||
| 		{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone},                        // RFC3339 without timezone hh:mm colon | ||||
| 		{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone},                        // RFC3339 without T or timezone hh:mm colon | ||||
| 		{"2006-01-02 15:04:05", timeFormatNoTimezone}, | ||||
| 		{time.ANSIC, timeFormatNoTimezone}, | ||||
| 		{time.UnixDate, timeFormatNamedTimezone}, | ||||
| 		{time.RubyDate, timeFormatNumericTimezone}, | ||||
| 		{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone}, | ||||
| 		{"02 Jan 2006", timeFormatNoTimezone}, | ||||
| 		{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone}, | ||||
| 		{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone}, | ||||
| 		{time.Kitchen, timeFormatTimeOnly}, | ||||
| 		{time.Stamp, timeFormatTimeOnly}, | ||||
| 		{time.StampMilli, timeFormatTimeOnly}, | ||||
| 		{time.StampMicro, timeFormatTimeOnly}, | ||||
| 		{time.StampNano, timeFormatTimeOnly}, | ||||
| 	} | ||||
| ) | ||||
| var timeFormats = []timeFormat{ | ||||
| 	// Keep common formats at the top. | ||||
| 	{"2006-01-02", timeFormatNoTimezone}, | ||||
| 	{time.RFC3339, timeFormatNumericTimezone}, | ||||
| 	{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone | ||||
| 	{time.RFC1123Z, timeFormatNumericTimezone}, | ||||
| 	{time.RFC1123, timeFormatNamedTimezone}, | ||||
| 	{time.RFC822Z, timeFormatNumericTimezone}, | ||||
| 	{time.RFC822, timeFormatNamedTimezone}, | ||||
| 	{time.RFC850, timeFormatNamedTimezone}, | ||||
| 	{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String() | ||||
| 	{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone},                        // RFC3339 without timezone hh:mm colon | ||||
| 	{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone},                        // RFC3339 without T or timezone hh:mm colon | ||||
| 	{"2006-01-02 15:04:05", timeFormatNoTimezone}, | ||||
| 	{time.ANSIC, timeFormatNoTimezone}, | ||||
| 	{time.UnixDate, timeFormatNamedTimezone}, | ||||
| 	{time.RubyDate, timeFormatNumericTimezone}, | ||||
| 	{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone}, | ||||
| 	{"02 Jan 2006", timeFormatNoTimezone}, | ||||
| 	{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone}, | ||||
| 	{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone}, | ||||
| 	{time.Kitchen, timeFormatTimeOnly}, | ||||
| 	{time.Stamp, timeFormatTimeOnly}, | ||||
| 	{time.StampMilli, timeFormatTimeOnly}, | ||||
| 	{time.StampMicro, timeFormatTimeOnly}, | ||||
| 	{time.StampNano, timeFormatTimeOnly}, | ||||
| } | ||||
| 
 | ||||
| func parseDateWith(s string, location *time.Location, formats []timeFormat) (d time.Time, e error) { | ||||
| 
 | ||||
| 	for _, format := range formats { | ||||
| 		if d, e = time.Parse(format.format, s); e == nil { | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								vendor/github.com/spf13/viper/.golangci.yaml
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/spf13/viper/.golangci.yaml
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -17,8 +17,6 @@ linters-settings: | |||
|         disabled-checks: | ||||
|             - importShadow | ||||
|             - unnamedResult | ||||
|     golint: | ||||
|         min-confidence: 0 | ||||
|     goimports: | ||||
|         local-prefixes: github.com/spf13/viper | ||||
| 
 | ||||
|  | @ -30,7 +28,6 @@ linters: | |||
|         - dupl | ||||
|         - durationcheck | ||||
|         - exhaustive | ||||
|         - exportloopref | ||||
|         - gci | ||||
|         - gocritic | ||||
|         - godot | ||||
|  |  | |||
							
								
								
									
										21
									
								
								vendor/github.com/spf13/viper/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/spf13/viper/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -3,7 +3,8 @@ | |||
| > | ||||
| > **Thank you!** | ||||
| 
 | ||||
|  | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| [](https://github.com/avelino/awesome-go#configuration) | ||||
| [](https://repl.it/@sagikazarmark/Viper-example#main.go) | ||||
|  | @ -11,7 +12,7 @@ | |||
| [](https://github.com/spf13/viper/actions?query=workflow%3ACI) | ||||
| [](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | ||||
| [](https://goreportcard.com/report/github.com/spf13/viper) | ||||
|  | ||||
|  | ||||
| [](https://pkg.go.dev/mod/github.com/spf13/viper) | ||||
| 
 | ||||
| **Go configuration with fangs!** | ||||
|  | @ -802,7 +803,7 @@ if err != nil { | |||
| } | ||||
| ``` | ||||
| 
 | ||||
| Viper uses [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) under the hood for unmarshaling values which uses `mapstructure` tags by default. | ||||
| Viper uses [github.com/go-viper/mapstructure](https://github.com/go-viper/mapstructure) under the hood for unmarshaling values which uses `mapstructure` tags by default. | ||||
| 
 | ||||
| ### Decoding custom formats | ||||
| 
 | ||||
|  | @ -836,13 +837,15 @@ func yamlStringSettings() string { | |||
| 
 | ||||
| ## Viper or Vipers? | ||||
| 
 | ||||
| Viper comes ready to use out of the box. There is no configuration or | ||||
| initialization needed to begin using Viper. Since most applications will want | ||||
| to use a single central repository for their configuration, the viper package | ||||
| provides this. It is similar to a singleton. | ||||
| Viper comes with a global instance (singleton) out of the box. | ||||
| 
 | ||||
| In all of the examples above, they demonstrate using viper in its singleton | ||||
| style approach. | ||||
| Although it makes setting up configuration easy, | ||||
| using it is generally discouraged as it makes testing harder and can lead to unexpected behavior. | ||||
| 
 | ||||
| The best practice is to initialize a Viper instance and pass that around when necessary. | ||||
| 
 | ||||
| The global instance _MAY_ be deprecated in the future. | ||||
| See [#1855](https://github.com/spf13/viper/issues/1855) for more details. | ||||
| 
 | ||||
| ### Working with multiple vipers | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										126
									
								
								vendor/github.com/spf13/viper/UPDATES.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								vendor/github.com/spf13/viper/UPDATES.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,126 @@ | |||
| # Update Log | ||||
| 
 | ||||
| **This document details any major updates required to use new features or improvements in Viper.** | ||||
| 
 | ||||
| ## v1.20.x | ||||
| 
 | ||||
| ### New file searching API | ||||
| 
 | ||||
| Viper now includes a new file searching API that allows users to customize how Viper looks for config files. | ||||
| 
 | ||||
| Viper accepts a custom [`Finder`](https://pkg.go.dev/github.com/spf13/viper#Finder) interface implementation: | ||||
| 
 | ||||
| ```go | ||||
| // Finder looks for files and directories in an [afero.Fs] filesystem. | ||||
| type Finder interface { | ||||
| 	Find(fsys afero.Fs) ([]string, error) | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| It is supposed to return a list of paths to config files. | ||||
| 
 | ||||
| The default implementation uses [github.com/sagikazarmark/locafero](https://github.com/sagikazarmark/locafero) under the hood. | ||||
| 
 | ||||
| You can supply your own implementation using `WithFinder`: | ||||
| 
 | ||||
| ```go | ||||
| v := viper.NewWithOptions( | ||||
|     viper.WithFinder(&MyFinder{}), | ||||
| ) | ||||
| ``` | ||||
| 
 | ||||
| For more information, check out the [Finder examples](https://pkg.go.dev/github.com/spf13/viper#Finder) | ||||
| and the [documentation](https://pkg.go.dev/github.com/sagikazarmark/locafero) for the locafero package. | ||||
| 
 | ||||
| ### New encoding API | ||||
| 
 | ||||
| Viper now allows customizing the encoding layer by providing an API for encoding and decoding configuration data: | ||||
| 
 | ||||
| ```go | ||||
| // Encoder encodes Viper's internal data structures into a byte representation. | ||||
| // It's primarily used for encoding a map[string]any into a file format. | ||||
| type Encoder interface { | ||||
| 	Encode(v map[string]any) ([]byte, error) | ||||
| } | ||||
| 
 | ||||
| // Decoder decodes the contents of a byte slice into Viper's internal data structures. | ||||
| // It's primarily used for decoding contents of a file into a map[string]any. | ||||
| type Decoder interface { | ||||
| 	Decode(b []byte, v map[string]any) error | ||||
| } | ||||
| 
 | ||||
| // Codec combines [Encoder] and [Decoder] interfaces. | ||||
| type Codec interface { | ||||
| 	Encoder | ||||
| 	Decoder | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| By default, Viper includes the following codecs: | ||||
| 
 | ||||
| - JSON | ||||
| - TOML | ||||
| - YAML | ||||
| - Dotenv | ||||
| 
 | ||||
| The rest of the codecs are moved to [github.com/go-viper/encoding](https://github.com/go-viper/encoding) | ||||
| 
 | ||||
| Customizing the encoding layer is possible by providing a custom registry of codecs: | ||||
| 
 | ||||
| - [Encoder](https://pkg.go.dev/github.com/spf13/viper#Encoder) -> [EncoderRegistry](https://pkg.go.dev/github.com/spf13/viper#EncoderRegistry) | ||||
| - [Decoder](https://pkg.go.dev/github.com/spf13/viper#Decoder) -> [DecoderRegistry](https://pkg.go.dev/github.com/spf13/viper#DecoderRegistry) | ||||
| - [Codec](https://pkg.go.dev/github.com/spf13/viper#Codec) -> [CodecRegistry](https://pkg.go.dev/github.com/spf13/viper#CodecRegistry) | ||||
| 
 | ||||
| You can supply the registry of codecs to Viper using the appropriate `With*Registry` function: | ||||
| 
 | ||||
| ```go | ||||
| codecRegistry := viper.NewCodecRegistry() | ||||
| 
 | ||||
| codecRegistry.RegisterCodec("myformat", &MyCodec{}) | ||||
| 
 | ||||
| v := viper.NewWithOptions( | ||||
|     viper.WithCodecRegistry(codecRegistry), | ||||
| ) | ||||
| ``` | ||||
| 
 | ||||
| ### BREAKING: HCL, Java properties, INI removed from core | ||||
| 
 | ||||
| In order to reduce third-party dependencies, Viper dropped support for the following formats from the core: | ||||
| 
 | ||||
| - HCL | ||||
| - Java properties | ||||
| - INI | ||||
| 
 | ||||
| You can still use these formats though by importing them from [github.com/go-viper/encoding](https://github.com/go-viper/encoding): | ||||
| 
 | ||||
| ```go | ||||
| import ( | ||||
|     "github.com/go-viper/encoding/hcl" | ||||
|     "github.com/go-viper/encoding/javaproperties" | ||||
|     "github.com/go-viper/encoding/ini" | ||||
| ) | ||||
| 
 | ||||
| codecRegistry := viper.NewCodecRegistry() | ||||
| 
 | ||||
| { | ||||
|     codec := hcl.Codec{} | ||||
| 
 | ||||
|     codecRegistry.RegisterCodec("hcl", codec) | ||||
|     codecRegistry.RegisterCodec("tfvars", codec) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     codec := &javaproperties.Codec{} | ||||
| 
 | ||||
|     codecRegistry.RegisterCodec("properties", codec) | ||||
|     codecRegistry.RegisterCodec("props", codec) | ||||
|     codecRegistry.RegisterCodec("prop", codec) | ||||
| } | ||||
| 
 | ||||
| codecRegistry.RegisterCodec("ini", ini.Codec{}) | ||||
| 
 | ||||
| v := viper.NewWithOptions( | ||||
|     viper.WithCodecRegistry(codecRegistry), | ||||
| ) | ||||
| ``` | ||||
							
								
								
									
										181
									
								
								vendor/github.com/spf13/viper/encoding.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								vendor/github.com/spf13/viper/encoding.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,181 @@ | |||
| package viper | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/spf13/viper/internal/encoding/dotenv" | ||||
| 	"github.com/spf13/viper/internal/encoding/json" | ||||
| 	"github.com/spf13/viper/internal/encoding/toml" | ||||
| 	"github.com/spf13/viper/internal/encoding/yaml" | ||||
| ) | ||||
| 
 | ||||
| // Encoder encodes Viper's internal data structures into a byte representation. | ||||
| // It's primarily used for encoding a map[string]any into a file format. | ||||
| type Encoder interface { | ||||
| 	Encode(v map[string]any) ([]byte, error) | ||||
| } | ||||
| 
 | ||||
| // Decoder decodes the contents of a byte slice into Viper's internal data structures. | ||||
| // It's primarily used for decoding contents of a file into a map[string]any. | ||||
| type Decoder interface { | ||||
| 	Decode(b []byte, v map[string]any) error | ||||
| } | ||||
| 
 | ||||
| // Codec combines [Encoder] and [Decoder] interfaces. | ||||
| type Codec interface { | ||||
| 	Encoder | ||||
| 	Decoder | ||||
| } | ||||
| 
 | ||||
| // TODO: consider adding specific errors for not found scenarios | ||||
| 
 | ||||
| // EncoderRegistry returns an [Encoder] for a given format. | ||||
| // | ||||
| // Format is case-insensitive. | ||||
| // | ||||
| // [EncoderRegistry] returns an error if no [Encoder] is registered for the format. | ||||
| type EncoderRegistry interface { | ||||
| 	Encoder(format string) (Encoder, error) | ||||
| } | ||||
| 
 | ||||
| // DecoderRegistry returns an [Decoder] for a given format. | ||||
| // | ||||
| // Format is case-insensitive. | ||||
| // | ||||
| // [DecoderRegistry] returns an error if no [Decoder] is registered for the format. | ||||
| type DecoderRegistry interface { | ||||
| 	Decoder(format string) (Decoder, error) | ||||
| } | ||||
| 
 | ||||
| // [CodecRegistry] combines [EncoderRegistry] and [DecoderRegistry] interfaces. | ||||
| type CodecRegistry interface { | ||||
| 	EncoderRegistry | ||||
| 	DecoderRegistry | ||||
| } | ||||
| 
 | ||||
| // WithEncoderRegistry sets a custom [EncoderRegistry]. | ||||
| func WithEncoderRegistry(r EncoderRegistry) Option { | ||||
| 	return optionFunc(func(v *Viper) { | ||||
| 		if r == nil { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		v.encoderRegistry = r | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // WithDecoderRegistry sets a custom [DecoderRegistry]. | ||||
| func WithDecoderRegistry(r DecoderRegistry) Option { | ||||
| 	return optionFunc(func(v *Viper) { | ||||
| 		if r == nil { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		v.decoderRegistry = r | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // WithCodecRegistry sets a custom [EncoderRegistry] and [DecoderRegistry]. | ||||
| func WithCodecRegistry(r CodecRegistry) Option { | ||||
| 	return optionFunc(func(v *Viper) { | ||||
| 		if r == nil { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		v.encoderRegistry = r | ||||
| 		v.decoderRegistry = r | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // DefaultCodecRegistry is a simple implementation of [CodecRegistry] that allows registering custom [Codec]s. | ||||
| type DefaultCodecRegistry struct { | ||||
| 	codecs map[string]Codec | ||||
| 
 | ||||
| 	mu   sync.RWMutex | ||||
| 	once sync.Once | ||||
| } | ||||
| 
 | ||||
| // NewCodecRegistry returns a new [CodecRegistry], ready to accept custom [Codec]s. | ||||
| func NewCodecRegistry() *DefaultCodecRegistry { | ||||
| 	r := &DefaultCodecRegistry{} | ||||
| 
 | ||||
| 	r.init() | ||||
| 
 | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (r *DefaultCodecRegistry) init() { | ||||
| 	r.once.Do(func() { | ||||
| 		r.codecs = map[string]Codec{} | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // RegisterCodec registers a custom [Codec]. | ||||
| // | ||||
| // Format is case-insensitive. | ||||
| func (r *DefaultCodecRegistry) RegisterCodec(format string, codec Codec) error { | ||||
| 	r.init() | ||||
| 
 | ||||
| 	r.mu.Lock() | ||||
| 	defer r.mu.Unlock() | ||||
| 
 | ||||
| 	r.codecs[strings.ToLower(format)] = codec | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Encoder implements the [EncoderRegistry] interface. | ||||
| // | ||||
| // Format is case-insensitive. | ||||
| func (r *DefaultCodecRegistry) Encoder(format string) (Encoder, error) { | ||||
| 	encoder, ok := r.codec(format) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("encoder not found for this format") | ||||
| 	} | ||||
| 
 | ||||
| 	return encoder, nil | ||||
| } | ||||
| 
 | ||||
| // Decoder implements the [DecoderRegistry] interface. | ||||
| // | ||||
| // Format is case-insensitive. | ||||
| func (r *DefaultCodecRegistry) Decoder(format string) (Decoder, error) { | ||||
| 	decoder, ok := r.codec(format) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("decoder not found for this format") | ||||
| 	} | ||||
| 
 | ||||
| 	return decoder, nil | ||||
| } | ||||
| 
 | ||||
| func (r *DefaultCodecRegistry) codec(format string) (Codec, bool) { | ||||
| 	r.mu.Lock() | ||||
| 	defer r.mu.Unlock() | ||||
| 
 | ||||
| 	format = strings.ToLower(format) | ||||
| 
 | ||||
| 	if r.codecs != nil { | ||||
| 		codec, ok := r.codecs[format] | ||||
| 		if ok { | ||||
| 			return codec, true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	switch format { | ||||
| 	case "yaml", "yml": | ||||
| 		return yaml.Codec{}, true | ||||
| 
 | ||||
| 	case "json": | ||||
| 		return json.Codec{}, true | ||||
| 
 | ||||
| 	case "toml": | ||||
| 		return toml.Codec{}, true | ||||
| 
 | ||||
| 	case "dotenv", "env": | ||||
| 		return &dotenv.Codec{}, true | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, false | ||||
| } | ||||
							
								
								
									
										8
									
								
								vendor/github.com/spf13/viper/experimental.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/spf13/viper/experimental.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| package viper | ||||
| 
 | ||||
| // ExperimentalBindStruct tells Viper to use the new bind struct feature. | ||||
| func ExperimentalBindStruct() Option { | ||||
| 	return optionFunc(func(v *Viper) { | ||||
| 		v.experimentalBindStruct = true | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										54
									
								
								vendor/github.com/spf13/viper/file.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/spf13/viper/file.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,5 +1,3 @@ | |||
| //go:build !finder | ||||
| 
 | ||||
| package viper | ||||
| 
 | ||||
| import ( | ||||
|  | @ -7,12 +5,62 @@ import ( | |||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 
 | ||||
| 	"github.com/sagikazarmark/locafero" | ||||
| 	"github.com/spf13/afero" | ||||
| ) | ||||
| 
 | ||||
| // ExperimentalFinder tells Viper to use the new Finder interface for finding configuration files. | ||||
| func ExperimentalFinder() Option { | ||||
| 	return optionFunc(func(v *Viper) { | ||||
| 		v.experimentalFinder = true | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Search for a config file. | ||||
| func (v *Viper) findConfigFile() (string, error) { | ||||
| 	finder := v.finder | ||||
| 
 | ||||
| 	if finder == nil && v.experimentalFinder { | ||||
| 		var names []string | ||||
| 
 | ||||
| 		if v.configType != "" { | ||||
| 			names = locafero.NameWithOptionalExtensions(v.configName, SupportedExts...) | ||||
| 		} else { | ||||
| 			names = locafero.NameWithExtensions(v.configName, SupportedExts...) | ||||
| 		} | ||||
| 
 | ||||
| 		finder = locafero.Finder{ | ||||
| 			Paths: v.configPaths, | ||||
| 			Names: names, | ||||
| 			Type:  locafero.FileTypeFile, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if finder != nil { | ||||
| 		return v.findConfigFileWithFinder(finder) | ||||
| 	} | ||||
| 
 | ||||
| 	return v.findConfigFileOld() | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) findConfigFileWithFinder(finder Finder) (string, error) { | ||||
| 	results, err := finder.Find(v.fs) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	if len(results) == 0 { | ||||
| 		return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} | ||||
| 	} | ||||
| 
 | ||||
| 	// We call clean on the final result to ensure that the path is in its canonical form. | ||||
| 	// This is mostly for consistent path handling and to make sure tests pass. | ||||
| 	return results[0], nil | ||||
| } | ||||
| 
 | ||||
| // Search all configPaths for any config file. | ||||
| // Returns the first path that exists (and is a config file). | ||||
| func (v *Viper) findConfigFile() (string, error) { | ||||
| func (v *Viper) findConfigFileOld() (string, error) { | ||||
| 	v.logger.Info("searching for config in paths", "paths", v.configPaths) | ||||
| 
 | ||||
| 	for _, cp := range v.configPaths { | ||||
|  |  | |||
							
								
								
									
										38
									
								
								vendor/github.com/spf13/viper/file_finder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/spf13/viper/file_finder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,38 +0,0 @@ | |||
| //go:build finder | ||||
| 
 | ||||
| package viper | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/sagikazarmark/locafero" | ||||
| ) | ||||
| 
 | ||||
| // Search all configPaths for any config file. | ||||
| // Returns the first path that exists (and is a config file). | ||||
| func (v *Viper) findConfigFile() (string, error) { | ||||
| 	var names []string | ||||
| 
 | ||||
| 	if v.configType != "" { | ||||
| 		names = locafero.NameWithOptionalExtensions(v.configName, SupportedExts...) | ||||
| 	} else { | ||||
| 		names = locafero.NameWithExtensions(v.configName, SupportedExts...) | ||||
| 	} | ||||
| 
 | ||||
| 	finder := locafero.Finder{ | ||||
| 		Paths: v.configPaths, | ||||
| 		Names: names, | ||||
| 		Type:  locafero.FileTypeFile, | ||||
| 	} | ||||
| 
 | ||||
| 	results, err := finder.Find(v.fs) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	if len(results) == 0 { | ||||
| 		return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} | ||||
| 	} | ||||
| 
 | ||||
| 	return results[0], nil | ||||
| } | ||||
							
								
								
									
										55
									
								
								vendor/github.com/spf13/viper/finder.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/spf13/viper/finder.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,55 @@ | |||
| package viper | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 
 | ||||
| 	"github.com/spf13/afero" | ||||
| ) | ||||
| 
 | ||||
| // WithFinder sets a custom [Finder]. | ||||
| func WithFinder(f Finder) Option { | ||||
| 	return optionFunc(func(v *Viper) { | ||||
| 		if f == nil { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		v.finder = f | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Finder looks for files and directories in an [afero.Fs] filesystem. | ||||
| type Finder interface { | ||||
| 	Find(fsys afero.Fs) ([]string, error) | ||||
| } | ||||
| 
 | ||||
| // Finders combines multiple finders into one. | ||||
| func Finders(finders ...Finder) Finder { | ||||
| 	return &combinedFinder{finders: finders} | ||||
| } | ||||
| 
 | ||||
| // combinedFinder is a Finder that combines multiple finders. | ||||
| type combinedFinder struct { | ||||
| 	finders []Finder | ||||
| } | ||||
| 
 | ||||
| // Find implements the [Finder] interface. | ||||
| func (c *combinedFinder) Find(fsys afero.Fs) ([]string, error) { | ||||
| 	var results []string | ||||
| 	var errs []error | ||||
| 
 | ||||
| 	for _, finder := range c.finders { | ||||
| 		if finder == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		r, err := finder.Find(fsys) | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		results = append(results, r...) | ||||
| 	} | ||||
| 
 | ||||
| 	return results, errors.Join(errs...) | ||||
| } | ||||
							
								
								
									
										333
									
								
								vendor/github.com/spf13/viper/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										333
									
								
								vendor/github.com/spf13/viper/flake.lock
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,22 +1,84 @@ | |||
| { | ||||
|   "nodes": { | ||||
|     "devenv": { | ||||
|     "cachix": { | ||||
|       "inputs": { | ||||
|         "flake-compat": "flake-compat", | ||||
|         "nix": "nix", | ||||
|         "nixpkgs": "nixpkgs", | ||||
|         "pre-commit-hooks": "pre-commit-hooks" | ||||
|         "devenv": "devenv_2", | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "pre-commit-hooks": [ | ||||
|           "devenv", | ||||
|           "pre-commit-hooks" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1707817777, | ||||
|         "narHash": "sha256-vHyIs1OULQ3/91wD6xOiuayfI71JXALGA5KLnDKAcy0=", | ||||
|         "lastModified": 1712055811, | ||||
|         "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "5a30b9e5ac7c6167e61b1f4193d5130bb9f8defa", | ||||
|         "repo": "cachix", | ||||
|         "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "cachix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "devenv": { | ||||
|       "inputs": { | ||||
|         "cachix": "cachix", | ||||
|         "flake-compat": "flake-compat_2", | ||||
|         "nix": "nix_2", | ||||
|         "nixpkgs": "nixpkgs_2", | ||||
|         "pre-commit-hooks": "pre-commit-hooks" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1724763216, | ||||
|         "narHash": "sha256-oW2bwCrJpIzibCNK6zfIDaIQw765yMAuMSG2gyZfGv0=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "1e4ef61205b9aa20fe04bf1c468b6a316281c4f1", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "devenv_2": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nix": "nix", | ||||
|         "nixpkgs": "nixpkgs", | ||||
|         "poetry2nix": "poetry2nix", | ||||
|         "pre-commit-hooks": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "pre-commit-hooks" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1708704632, | ||||
|         "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv", | ||||
|         "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "ref": "python-rewrite", | ||||
|         "repo": "devenv", | ||||
|         "type": "github" | ||||
|       } | ||||
|  | @ -37,16 +99,32 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-compat_2": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1696426674, | ||||
|         "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "edolstra", | ||||
|         "repo": "flake-compat", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-parts": { | ||||
|       "inputs": { | ||||
|         "nixpkgs-lib": "nixpkgs-lib" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1706830856, | ||||
|         "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", | ||||
|         "lastModified": 1722555600, | ||||
|         "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "flake-parts", | ||||
|         "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", | ||||
|         "rev": "8471fe90ad337a8074e957b69ca4d0089218391d", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -60,11 +138,29 @@ | |||
|         "systems": "systems" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1685518550, | ||||
|         "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", | ||||
|         "lastModified": 1689068808, | ||||
|         "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", | ||||
|         "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "flake-utils_2": { | ||||
|       "inputs": { | ||||
|         "systems": "systems_2" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1710146030, | ||||
|         "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", | ||||
|         "owner": "numtide", | ||||
|         "repo": "flake-utils", | ||||
|         "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -82,11 +178,11 @@ | |||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1660459072, | ||||
|         "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", | ||||
|         "lastModified": 1709087332, | ||||
|         "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", | ||||
|         "owner": "hercules-ci", | ||||
|         "repo": "gitignore.nix", | ||||
|         "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", | ||||
|         "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -95,53 +191,90 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "lowdown-src": { | ||||
|       "flake": false, | ||||
|       "locked": { | ||||
|         "lastModified": 1633514407, | ||||
|         "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", | ||||
|         "owner": "kristapsdz", | ||||
|         "repo": "lowdown", | ||||
|         "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "kristapsdz", | ||||
|         "repo": "lowdown", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix": { | ||||
|       "inputs": { | ||||
|         "lowdown-src": "lowdown-src", | ||||
|         "flake-compat": "flake-compat", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1676545802, | ||||
|         "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", | ||||
|         "lastModified": 1712911606, | ||||
|         "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", | ||||
|         "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "relaxed-flakes", | ||||
|         "ref": "devenv-2.21", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix-github-actions": { | ||||
|       "inputs": { | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "poetry2nix", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1688870561, | ||||
|         "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "nix-github-actions", | ||||
|         "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-community", | ||||
|         "repo": "nix-github-actions", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nix_2": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ], | ||||
|         "nixpkgs-regression": "nixpkgs-regression_2" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1712911606, | ||||
|         "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", | ||||
|         "owner": "domenkozar", | ||||
|         "repo": "nix", | ||||
|         "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "domenkozar", | ||||
|         "ref": "devenv-2.21", | ||||
|         "repo": "nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs": { | ||||
|       "locked": { | ||||
|         "lastModified": 1678875422, | ||||
|         "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", | ||||
|         "lastModified": 1692808169, | ||||
|         "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", | ||||
|         "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -153,20 +286,14 @@ | |||
|     }, | ||||
|     "nixpkgs-lib": { | ||||
|       "locked": { | ||||
|         "dir": "lib", | ||||
|         "lastModified": 1706550542, | ||||
|         "narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "97b17f32362e475016f942bbdfda4a4a72a8a652", | ||||
|         "type": "github" | ||||
|         "lastModified": 1722555339, | ||||
|         "narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=", | ||||
|         "type": "tarball", | ||||
|         "url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz" | ||||
|       }, | ||||
|       "original": { | ||||
|         "dir": "lib", | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-unstable", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|         "type": "tarball", | ||||
|         "url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-regression": { | ||||
|  | @ -185,29 +312,61 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-stable": { | ||||
|     "nixpkgs-regression_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1685801374, | ||||
|         "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", | ||||
|         "lastModified": 1643052045, | ||||
|         "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-23.05", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs-stable": { | ||||
|       "locked": { | ||||
|         "lastModified": 1710695816, | ||||
|         "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "614b4613980a522ba49f0d194531beddbb7220d3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "NixOS", | ||||
|         "ref": "nixos-23.11", | ||||
|         "repo": "nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1707939175, | ||||
|         "narHash": "sha256-D1xan0lgxbmXDyzVqXTiSYHLmAMrMRdD+alKzEO/p3w=", | ||||
|         "lastModified": 1713361204, | ||||
|         "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "devenv-nixpkgs", | ||||
|         "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "cachix", | ||||
|         "ref": "rolling", | ||||
|         "repo": "devenv-nixpkgs", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "nixpkgs_3": { | ||||
|       "locked": { | ||||
|         "lastModified": 1724748588, | ||||
|         "narHash": "sha256-NlpGA4+AIf1dKNq76ps90rxowlFXUsV9x7vK/mN37JM=", | ||||
|         "owner": "NixOS", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "f7e8132daca31b1e3859ac0fb49741754375ac3d", | ||||
|         "rev": "a6292e34000dc93d43bccf78338770c1c5ec8a99", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -217,13 +376,38 @@ | |||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "poetry2nix": { | ||||
|       "inputs": { | ||||
|         "flake-utils": "flake-utils", | ||||
|         "nix-github-actions": "nix-github-actions", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|           "cachix", | ||||
|           "devenv", | ||||
|           "nixpkgs" | ||||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1692876271, | ||||
|         "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "poetry2nix", | ||||
|         "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-community", | ||||
|         "repo": "poetry2nix", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "pre-commit-hooks": { | ||||
|       "inputs": { | ||||
|         "flake-compat": [ | ||||
|           "devenv", | ||||
|           "flake-compat" | ||||
|         ], | ||||
|         "flake-utils": "flake-utils", | ||||
|         "flake-utils": "flake-utils_2", | ||||
|         "gitignore": "gitignore", | ||||
|         "nixpkgs": [ | ||||
|           "devenv", | ||||
|  | @ -232,11 +416,11 @@ | |||
|         "nixpkgs-stable": "nixpkgs-stable" | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1704725188, | ||||
|         "narHash": "sha256-qq8NbkhRZF1vVYQFt1s8Mbgo8knj+83+QlL5LBnYGpI=", | ||||
|         "lastModified": 1713775815, | ||||
|         "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", | ||||
|         "owner": "cachix", | ||||
|         "repo": "pre-commit-hooks.nix", | ||||
|         "rev": "ea96f0c05924341c551a797aaba8126334c505d2", | ||||
|         "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -249,7 +433,7 @@ | |||
|       "inputs": { | ||||
|         "devenv": "devenv", | ||||
|         "flake-parts": "flake-parts", | ||||
|         "nixpkgs": "nixpkgs_2" | ||||
|         "nixpkgs": "nixpkgs_3" | ||||
|       } | ||||
|     }, | ||||
|     "systems": { | ||||
|  | @ -266,6 +450,21 @@ | |||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     }, | ||||
|     "systems_2": { | ||||
|       "locked": { | ||||
|         "lastModified": 1681028828, | ||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|         "owner": "nix-systems", | ||||
|         "repo": "default", | ||||
|         "type": "github" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "root": "root", | ||||
|  |  | |||
							
								
								
									
										2
									
								
								vendor/github.com/spf13/viper/flake.nix
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/spf13/viper/flake.nix
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -20,7 +20,7 @@ | |||
|           default = { | ||||
|             languages = { | ||||
|               go.enable = true; | ||||
|               go.package = pkgs.go_1_22; | ||||
|               go.package = pkgs.go_1_23; | ||||
|             }; | ||||
| 
 | ||||
|             pre-commit.hooks = { | ||||
|  |  | |||
							
								
								
									
										61
									
								
								vendor/github.com/spf13/viper/internal/encoding/decoder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/spf13/viper/internal/encoding/decoder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,61 +0,0 @@ | |||
| package encoding | ||||
| 
 | ||||
| import ( | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| // Decoder decodes the contents of b into v. | ||||
| // It's primarily used for decoding contents of a file into a map[string]any. | ||||
| type Decoder interface { | ||||
| 	Decode(b []byte, v map[string]any) error | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	// ErrDecoderNotFound is returned when there is no decoder registered for a format. | ||||
| 	ErrDecoderNotFound = encodingError("decoder not found for this format") | ||||
| 
 | ||||
| 	// ErrDecoderFormatAlreadyRegistered is returned when an decoder is already registered for a format. | ||||
| 	ErrDecoderFormatAlreadyRegistered = encodingError("decoder already registered for this format") | ||||
| ) | ||||
| 
 | ||||
| // DecoderRegistry can choose an appropriate Decoder based on the provided format. | ||||
| type DecoderRegistry struct { | ||||
| 	decoders map[string]Decoder | ||||
| 
 | ||||
| 	mu sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // NewDecoderRegistry returns a new, initialized DecoderRegistry. | ||||
| func NewDecoderRegistry() *DecoderRegistry { | ||||
| 	return &DecoderRegistry{ | ||||
| 		decoders: make(map[string]Decoder), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterDecoder registers a Decoder for a format. | ||||
| // Registering a Decoder for an already existing format is not supported. | ||||
| func (e *DecoderRegistry) RegisterDecoder(format string, enc Decoder) error { | ||||
| 	e.mu.Lock() | ||||
| 	defer e.mu.Unlock() | ||||
| 
 | ||||
| 	if _, ok := e.decoders[format]; ok { | ||||
| 		return ErrDecoderFormatAlreadyRegistered | ||||
| 	} | ||||
| 
 | ||||
| 	e.decoders[format] = enc | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Decode calls the underlying Decoder based on the format. | ||||
| func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]any) error { | ||||
| 	e.mu.RLock() | ||||
| 	decoder, ok := e.decoders[format] | ||||
| 	e.mu.RUnlock() | ||||
| 
 | ||||
| 	if !ok { | ||||
| 		return ErrDecoderNotFound | ||||
| 	} | ||||
| 
 | ||||
| 	return decoder.Decode(b, v) | ||||
| } | ||||
							
								
								
									
										60
									
								
								vendor/github.com/spf13/viper/internal/encoding/encoder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/spf13/viper/internal/encoding/encoder.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,60 +0,0 @@ | |||
| package encoding | ||||
| 
 | ||||
| import ( | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| // Encoder encodes the contents of v into a byte representation. | ||||
| // It's primarily used for encoding a map[string]any into a file format. | ||||
| type Encoder interface { | ||||
| 	Encode(v map[string]any) ([]byte, error) | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	// ErrEncoderNotFound is returned when there is no encoder registered for a format. | ||||
| 	ErrEncoderNotFound = encodingError("encoder not found for this format") | ||||
| 
 | ||||
| 	// ErrEncoderFormatAlreadyRegistered is returned when an encoder is already registered for a format. | ||||
| 	ErrEncoderFormatAlreadyRegistered = encodingError("encoder already registered for this format") | ||||
| ) | ||||
| 
 | ||||
| // EncoderRegistry can choose an appropriate Encoder based on the provided format. | ||||
| type EncoderRegistry struct { | ||||
| 	encoders map[string]Encoder | ||||
| 
 | ||||
| 	mu sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // NewEncoderRegistry returns a new, initialized EncoderRegistry. | ||||
| func NewEncoderRegistry() *EncoderRegistry { | ||||
| 	return &EncoderRegistry{ | ||||
| 		encoders: make(map[string]Encoder), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterEncoder registers an Encoder for a format. | ||||
| // Registering a Encoder for an already existing format is not supported. | ||||
| func (e *EncoderRegistry) RegisterEncoder(format string, enc Encoder) error { | ||||
| 	e.mu.Lock() | ||||
| 	defer e.mu.Unlock() | ||||
| 
 | ||||
| 	if _, ok := e.encoders[format]; ok { | ||||
| 		return ErrEncoderFormatAlreadyRegistered | ||||
| 	} | ||||
| 
 | ||||
| 	e.encoders[format] = enc | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (e *EncoderRegistry) Encode(format string, v map[string]any) ([]byte, error) { | ||||
| 	e.mu.RLock() | ||||
| 	encoder, ok := e.encoders[format] | ||||
| 	e.mu.RUnlock() | ||||
| 
 | ||||
| 	if !ok { | ||||
| 		return nil, ErrEncoderNotFound | ||||
| 	} | ||||
| 
 | ||||
| 	return encoder.Encode(v) | ||||
| } | ||||
							
								
								
									
										7
									
								
								vendor/github.com/spf13/viper/internal/encoding/error.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/spf13/viper/internal/encoding/error.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,7 +0,0 @@ | |||
| package encoding | ||||
| 
 | ||||
| type encodingError string | ||||
| 
 | ||||
| func (e encodingError) Error() string { | ||||
| 	return string(e) | ||||
| } | ||||
							
								
								
									
										40
									
								
								vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,40 +0,0 @@ | |||
| package hcl | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 
 | ||||
| 	"github.com/hashicorp/hcl" | ||||
| 	"github.com/hashicorp/hcl/hcl/printer" | ||||
| ) | ||||
| 
 | ||||
| // Codec implements the encoding.Encoder and encoding.Decoder interfaces for HCL encoding. | ||||
| // TODO: add printer config to the codec? | ||||
| type Codec struct{} | ||||
| 
 | ||||
| func (Codec) Encode(v map[string]any) ([]byte, error) { | ||||
| 	b, err := json.Marshal(v) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: use printer.Format? Is the trailing newline an issue? | ||||
| 
 | ||||
| 	ast, err := hcl.Parse(string(b)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	var buf bytes.Buffer | ||||
| 
 | ||||
| 	err = printer.Fprint(&buf, ast.Node) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return buf.Bytes(), nil | ||||
| } | ||||
| 
 | ||||
| func (Codec) Decode(b []byte, v map[string]any) error { | ||||
| 	return hcl.Unmarshal(b, &v) | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue