mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-23 22:29:59 -05:00
build(deps): bump github.com/onsi/ginkgo/v2 from 2.25.3 to 2.26.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.25.3 to 2.26.0. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.25.3...v2.26.0) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-version: 2.26.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
4e06b0c376
commit
4c00db867c
5
go.mod
5
go.mod
@@ -60,7 +60,7 @@ require (
|
||||
github.com/oklog/run v1.2.0
|
||||
github.com/olekukonko/tablewriter v1.1.0
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.25.3
|
||||
github.com/onsi/ginkgo/v2 v2.26.0
|
||||
github.com/onsi/gomega v1.38.2
|
||||
github.com/open-policy-agent/opa v1.9.0
|
||||
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
|
||||
@@ -228,7 +228,7 @@ require (
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.2.1 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.12.0 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
@@ -378,7 +378,6 @@ require (
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/time v0.13.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
|
||||
22
go.sum
22
go.sum
@@ -357,6 +357,12 @@ github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s
|
||||
github.com/ggwhite/go-masker v1.1.0 h1:kN/KIvktu2U+hd3KWrSlLj7xBGD1iBfc9/xdbVgFbRc=
|
||||
github.com/ggwhite/go-masker v1.1.0/go.mod h1:xnTRHwrIU9FtBADwEjUC5Dy/BVedvoTxyOE7/d3CNwY=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
|
||||
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||
github.com/gkampitakis/go-snaps v0.5.14 h1:3fAqdB6BCPKHDMHAKRwtPUwYexKtGrNuw8HX/T/4neo=
|
||||
github.com/gkampitakis/go-snaps v0.5.14/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/go-acme/lego/v4 v4.4.0 h1:uHhU5LpOYQOdp3aDU+XY2bajseu8fuExphTL1Ss6/Fc=
|
||||
@@ -471,8 +477,8 @@ github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk=
|
||||
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM=
|
||||
github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
|
||||
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
|
||||
@@ -687,6 +693,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
|
||||
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
|
||||
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
|
||||
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
@@ -780,6 +788,8 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
|
||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
|
||||
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
|
||||
@@ -817,6 +827,8 @@ github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b h1:Q53idHrTuQD
|
||||
github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b/go.mod h1:KirJrATYGbTyUwVR26xIkaipRqRcMRXBf8N5dacvGus=
|
||||
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZyWckaLfucYG6KYOXLWo4co8pZYNY=
|
||||
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103/go.mod h1:o9YPB5aGP8ob35Vy6+vyq3P3bWe7NQWzf+JLiXCiMaE=
|
||||
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
||||
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
|
||||
@@ -919,8 +931,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
|
||||
github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
|
||||
github.com/onsi/ginkgo/v2 v2.26.0 h1:1J4Wut1IlYZNEAWIV3ALrT9NfiaGW2cDCJQSFQMs/gE=
|
||||
github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az2oavUzw=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
@@ -1641,8 +1653,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
|
||||
3
vendor/github.com/goccy/go-yaml/.gitignore
generated
vendored
Normal file
3
vendor/github.com/goccy/go-yaml/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
bin/
|
||||
.idea/
|
||||
cover.out
|
||||
65
vendor/github.com/goccy/go-yaml/.golangci.yml
generated
vendored
Normal file
65
vendor/github.com/goccy/go-yaml/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
version: "2"
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- errcheck
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- perfsprint
|
||||
- staticcheck
|
||||
- unused
|
||||
settings:
|
||||
errcheck:
|
||||
without_tests: true
|
||||
govet:
|
||||
disable:
|
||||
- tests
|
||||
misspell:
|
||||
locale: US
|
||||
perfsprint:
|
||||
int-conversion: false
|
||||
err-error: false
|
||||
errorf: true
|
||||
sprintf1: false
|
||||
strconcat: false
|
||||
staticcheck:
|
||||
checks:
|
||||
- -ST1000
|
||||
- -ST1005
|
||||
- all
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- linters:
|
||||
- staticcheck
|
||||
path: _test\.go
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofmt
|
||||
settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(github.com/goccy/go-yaml)
|
||||
- blank
|
||||
- dot
|
||||
gofmt:
|
||||
simplify: true
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
42
vendor/github.com/goccy/go-yaml/Makefile
generated
vendored
42
vendor/github.com/goccy/go-yaml/Makefile
generated
vendored
@@ -1,19 +1,55 @@
|
||||
## Location to install dependencies to
|
||||
LOCALBIN ?= $(shell pwd)/bin
|
||||
TESTMOD := testdata/go_test.mod
|
||||
|
||||
$(LOCALBIN):
|
||||
mkdir -p $(LOCALBIN)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v -race ./...
|
||||
go test -v -race ./testdata -modfile=$(TESTMOD)
|
||||
|
||||
.PHONY: simple-test
|
||||
simple-test:
|
||||
go test -v ./...
|
||||
go test -v ./testdata -modfile=$(TESTMOD)
|
||||
|
||||
.PHONY: fuzz
|
||||
fuzz:
|
||||
go test -fuzz=Fuzz -fuzztime 60s
|
||||
|
||||
.PHONY: cover
|
||||
cover:
|
||||
go test -coverprofile=cover.out ./...
|
||||
go test -coverpkg=.,./ast,./lexer,./parser,./printer,./scanner,./token -coverprofile=cover.out -modfile=$(TESTMOD) ./... ./testdata
|
||||
|
||||
.PHONY: cover-html
|
||||
cover-html: cover
|
||||
go tool cover -html=cover.out
|
||||
|
||||
.PHONY: ycat/build
|
||||
ycat/build:
|
||||
go build -o ycat ./cmd/ycat
|
||||
ycat/build: $(LOCALBIN)
|
||||
cd ./cmd/ycat && go build -o $(LOCALBIN)/ycat .
|
||||
|
||||
.PHONY: lint
|
||||
lint: golangci-lint ## Run golangci-lint
|
||||
@$(GOLANGCI_LINT) run
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: golangci-lint ## Ensure consistent code style
|
||||
@go mod tidy
|
||||
@go fmt ./...
|
||||
@$(GOLANGCI_LINT) run --fix
|
||||
|
||||
## Tool Binaries
|
||||
GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint
|
||||
|
||||
## Tool Versions
|
||||
GOLANGCI_VERSION := 2.1.2
|
||||
|
||||
.PHONY: golangci-lint
|
||||
.PHONY: $(GOLANGCI_LINT)
|
||||
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
|
||||
$(GOLANGCI_LINT): $(LOCALBIN)
|
||||
@test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint version --short | grep -q $(GOLANGCI_VERSION) || \
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LOCALBIN) v$(GOLANGCI_VERSION)
|
||||
|
||||
84
vendor/github.com/goccy/go-yaml/README.md
generated
vendored
84
vendor/github.com/goccy/go-yaml/README.md
generated
vendored
@@ -7,27 +7,71 @@
|
||||
|
||||
<img width="300px" src="https://user-images.githubusercontent.com/209884/67159116-64d94b80-f37b-11e9-9b28-f8379636a43c.png"></img>
|
||||
|
||||
## This library has **NO** relation to the go-yaml/yaml library
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This library is developed from scratch to replace [`go-yaml/yaml`](https://github.com/go-yaml/yaml).
|
||||
> If you're looking for a better YAML library, this one should be helpful.
|
||||
|
||||
# Why a new library?
|
||||
|
||||
As of this writing, there already exists a de facto standard library for YAML processing for Go: [https://github.com/go-yaml/yaml](https://github.com/go-yaml/yaml). However we feel that some features are lacking, namely:
|
||||
As of this writing, there already exists a de facto standard library for YAML processing for Go: [https://github.com/go-yaml/yaml](https://github.com/go-yaml/yaml). However, we believe that a new YAML library is necessary for the following reasons:
|
||||
|
||||
- Pretty format for error notifications
|
||||
- Direct manipulation of YAML abstract syntax tree
|
||||
- Support for `Anchor` and `Alias` when marshaling
|
||||
- Allow referencing elements declared in another file via anchors
|
||||
- Not actively maintained
|
||||
- `go-yaml/yaml` has ported the libyaml written in C to Go, so the source code is not written in Go style
|
||||
- There is a lot of content that cannot be parsed
|
||||
- YAML is often used for configuration, and it is common to include validation along with it. However, the errors in `go-yaml/yaml` are not intuitive, and it is difficult to provide meaningful validation errors
|
||||
- When creating tools that use YAML, there are cases where reversible transformation of YAML is required. However, to perform reversible transformations of content that includes Comments or Anchors/Aliases, manipulating the AST is the only option
|
||||
- Non-intuitive [Marshaler](https://pkg.go.dev/gopkg.in/yaml.v3#Marshaler) / [Unmarshaler](https://pkg.go.dev/gopkg.in/yaml.v3#Unmarshaler)
|
||||
|
||||
By the way, libraries such as [ghodss/yaml](https://github.com/ghodss/yaml) and [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml) also depend on go-yaml/yaml, so if you are using these libraries, the same issues apply: they cannot parse things that go-yaml/yaml cannot parse, and they inherit many of the problems that go-yaml/yaml has.
|
||||
|
||||
# Features
|
||||
|
||||
- No dependencies
|
||||
- A better parser than `go-yaml/yaml`.
|
||||
- [Support recursive processing](https://github.com/apple/device-management/blob/release/docs/schema.yaml)
|
||||
- Higher coverage in the [YAML Test Suite](https://github.com/yaml/yaml-test-suite?tab=readme-ov-file)
|
||||
- YAML Test Suite consists of 402 cases in total, of which `gopkg.in/yaml.v3` passes `295`. In addition to passing all those test cases, `goccy/go-yaml` successfully passes nearly 60 additional test cases ( 2024/12/15 )
|
||||
- The test code is [here](https://github.com/goccy/go-yaml/blob/master/yaml_test_suite_test.go#L77)
|
||||
- Ease and sustainability of maintenance
|
||||
- The main maintainer is [@goccy](https://github.com/goccy), but we are also building a system to develop as a team with trusted developers
|
||||
- Since it is written from scratch, the code is easy to read for Gophers
|
||||
- An API structure that allows the use of not only `Encoder`/`Decoder` but also `Tokenizer` and `Parser` functionalities.
|
||||
- [lexer.Tokenize](https://pkg.go.dev/github.com/goccy/go-yaml@v1.15.4/lexer#Tokenize)
|
||||
- [parser.Parse](https://pkg.go.dev/github.com/goccy/go-yaml@v1.15.4/parser#Parse)
|
||||
- Filtering, replacing, and merging YAML content using YAML Path
|
||||
- Reversible transformation without using the AST for YAML that includes Anchors, Aliases, and Comments
|
||||
- Customize the Marshal/Unmarshal behavior for primitive types and third-party library types ([RegisterCustomMarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#RegisterCustomMarshaler), [RegisterCustomUnmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#RegisterCustomUnmarshaler))
|
||||
- Respects `encoding/json` behavior
|
||||
- Accept the `json` tag. Note that not all options from the `json` tag will have significance when parsing YAML documents. If both tags exist, `yaml` tag will take precedence.
|
||||
- [json.Marshaler](https://pkg.go.dev/encoding/json#Marshaler) style [marshaler](https://pkg.go.dev/github.com/goccy/go-yaml#BytesMarshaler)
|
||||
- [json.Unmarshaler](https://pkg.go.dev/encoding/json#Unmarshaler) style [unmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#BytesUnmarshaler)
|
||||
- Options for using `MarshalJSON` and `UnmarshalJSON` ([UseJSONMarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#UseJSONMarshaler), [UseJSONUnmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#UseJSONUnmarshaler))
|
||||
- Pretty format for error notifications
|
||||
- Supports `Scanner` or `Lexer` or `Parser` as public API
|
||||
- Supports `Anchor` and `Alias` to Marshaler
|
||||
- Smart validation processing combined with [go-playground/validator](https://github.com/go-playground/validator)
|
||||
- [example test code is here](https://github.com/goccy/go-yaml/blob/45889c98b0a0967240eb595a1bd6896e2f575106/testdata/validate_test.go#L12)
|
||||
- Allow referencing elements declared in another file via anchors
|
||||
- Extract value or AST by YAMLPath ( YAMLPath is like a JSONPath )
|
||||
|
||||
# Users
|
||||
|
||||
The repositories that use goccy/go-yaml are listed here.
|
||||
|
||||
- https://github.com/goccy/go-yaml/wiki/Users
|
||||
|
||||
The source data is [here](https://github.com/goccy/go-yaml/network/dependents).
|
||||
It is already being used in many repositories. Now it's your turn 😄
|
||||
|
||||
# Playground
|
||||
|
||||
The Playground visualizes how go-yaml processes YAML text. Use it to assist with your debugging or issue reporting.
|
||||
|
||||
https://goccy.github.io/go-yaml
|
||||
|
||||
# Installation
|
||||
|
||||
```sh
|
||||
go get -u github.com/goccy/go-yaml
|
||||
go get github.com/goccy/go-yaml
|
||||
```
|
||||
|
||||
# Synopsis
|
||||
@@ -148,7 +192,9 @@ fmt.Printf("%+v\n", v) // {A:{B:1 C:hello}}
|
||||
|
||||
### 3.1. Explicitly declared `Anchor` name and `Alias` name
|
||||
|
||||
If you want to use `anchor` or `alias`, you can define it as a struct tag.
|
||||
If you want to use `anchor`, you can define it as a struct tag.
|
||||
If the value specified for an anchor is a pointer type and the same address as the pointer is found, the value is automatically set to alias.
|
||||
If an explicit alias name is specified, an error is raised if its value is different from the value specified in the anchor.
|
||||
|
||||
```go
|
||||
type T struct {
|
||||
@@ -178,10 +224,7 @@ d: *x
|
||||
|
||||
If you do not explicitly declare the anchor name, the default behavior is to
|
||||
use the equivalent of `strings.ToLower($FieldName)` as the name of the anchor.
|
||||
|
||||
If you do not explicitly declare the alias name AND the value is a pointer
|
||||
to another element, we look up the anchor name by finding out which anchor
|
||||
field the value is assigned to by looking up its pointer address.
|
||||
If the value specified for an anchor is a pointer type and the same address as the pointer is found, the value is automatically set to alias.
|
||||
|
||||
```go
|
||||
type T struct {
|
||||
@@ -191,8 +234,8 @@ type T struct {
|
||||
var v struct {
|
||||
A *T `yaml:"a,anchor"`
|
||||
B *T `yaml:"b,anchor"`
|
||||
C *T `yaml:"c,alias"`
|
||||
D *T `yaml:"d,alias"`
|
||||
C *T `yaml:"c"`
|
||||
D *T `yaml:"d"`
|
||||
}
|
||||
v.A = &T{I: 1, S: "hello"}
|
||||
v.B = &T{I: 2, S: "world"}
|
||||
@@ -358,9 +401,16 @@ print yaml file with color
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
go install github.com/goccy/go-yaml/cmd/ycat@latest
|
||||
git clone https://github.com/goccy/go-yaml.git
|
||||
cd go-yaml/cmd/ycat && go install .
|
||||
```
|
||||
|
||||
|
||||
# For Developers
|
||||
|
||||
> [!NOTE]
|
||||
> In this project, we manage such test code under the `testdata` directory to avoid adding dependencies on libraries that are only needed for testing to the top `go.mod` file. Therefore, if you want to add test cases that use 3rd party libraries, please add the test code to the `testdata` directory.
|
||||
|
||||
# Looking for Sponsors
|
||||
|
||||
I'm looking for sponsors this library. This library is being developed as a personal project in my spare time. If you want a quick response or problem resolution when using this library in your project, please register as a [sponsor](https://github.com/sponsors/goccy). I will cooperate as much as possible. Of course, this library is developed as an MIT license, so you can use it freely for free.
|
||||
|
||||
509
vendor/github.com/goccy/go-yaml/ast/ast.go
generated
vendored
509
vendor/github.com/goccy/go-yaml/ast/ast.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -8,13 +9,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goccy/go-yaml/token"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidTokenType = xerrors.New("invalid token type")
|
||||
ErrInvalidAnchorName = xerrors.New("invalid anchor name")
|
||||
ErrInvalidAliasName = xerrors.New("invalid alias name")
|
||||
ErrInvalidTokenType = errors.New("invalid token type")
|
||||
ErrInvalidAnchorName = errors.New("invalid anchor name")
|
||||
ErrInvalidAliasName = errors.New("invalid alias name")
|
||||
)
|
||||
|
||||
// NodeType type identifier of node
|
||||
@@ -51,6 +51,8 @@ const (
|
||||
MappingValueType
|
||||
// SequenceType type identifier for sequence node
|
||||
SequenceType
|
||||
// SequenceEntryType type identifier for sequence entry node
|
||||
SequenceEntryType
|
||||
// AnchorType type identifier for anchor node
|
||||
AnchorType
|
||||
// AliasType type identifier for alias node
|
||||
@@ -98,6 +100,8 @@ func (t NodeType) String() string {
|
||||
return "MappingValue"
|
||||
case SequenceType:
|
||||
return "Sequence"
|
||||
case SequenceEntryType:
|
||||
return "SequenceEntry"
|
||||
case AnchorType:
|
||||
return "Anchor"
|
||||
case AliasType:
|
||||
@@ -148,6 +152,8 @@ func (t NodeType) YAMLName() string {
|
||||
return "value"
|
||||
case SequenceType:
|
||||
return "sequence"
|
||||
case SequenceEntryType:
|
||||
return "value"
|
||||
case AnchorType:
|
||||
return "anchor"
|
||||
case AliasType:
|
||||
@@ -196,6 +202,7 @@ type Node interface {
|
||||
// MapKeyNode type for map key node
|
||||
type MapKeyNode interface {
|
||||
Node
|
||||
IsMergeKey() bool
|
||||
// String node to text without comment
|
||||
stringWithoutComment() string
|
||||
}
|
||||
@@ -278,6 +285,49 @@ func readNode(p []byte, node Node) (int, error) {
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func checkLineBreak(t *token.Token) bool {
|
||||
if t.Prev != nil {
|
||||
lbc := "\n"
|
||||
prev := t.Prev
|
||||
var adjustment int
|
||||
// if the previous type is sequence entry use the previous type for that
|
||||
if prev.Type == token.SequenceEntryType {
|
||||
// as well as switching to previous type count any new lines in origin to account for:
|
||||
// -
|
||||
// b: c
|
||||
adjustment = strings.Count(strings.TrimRight(t.Origin, lbc), lbc)
|
||||
if prev.Prev != nil {
|
||||
prev = prev.Prev
|
||||
}
|
||||
}
|
||||
lineDiff := t.Position.Line - prev.Position.Line - 1
|
||||
if lineDiff > 0 {
|
||||
if prev.Type == token.StringType {
|
||||
// Remove any line breaks included in multiline string
|
||||
adjustment += strings.Count(strings.TrimRight(strings.TrimSpace(prev.Origin), lbc), lbc)
|
||||
}
|
||||
// Due to the way that comment parsing works its assumed that when a null value does not have new line in origin
|
||||
// it was squashed therefore difference is ignored.
|
||||
// foo:
|
||||
// bar:
|
||||
// # comment
|
||||
// baz: 1
|
||||
// becomes
|
||||
// foo:
|
||||
// bar: null # comment
|
||||
//
|
||||
// baz: 1
|
||||
if prev.Type == token.NullType || prev.Type == token.ImplicitNullType {
|
||||
return strings.Count(prev.Origin, lbc) > 0
|
||||
}
|
||||
if lineDiff-adjustment > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Null create node for null value
|
||||
func Null(tk *token.Token) *NullNode {
|
||||
return &NullNode{
|
||||
@@ -298,105 +348,30 @@ func Bool(tk *token.Token) *BoolNode {
|
||||
|
||||
// Integer create node for integer value
|
||||
func Integer(tk *token.Token) *IntegerNode {
|
||||
value := removeUnderScoreFromNumber(tk.Value)
|
||||
switch tk.Type {
|
||||
case token.BinaryIntegerType:
|
||||
// skip two characters because binary token starts with '0b'
|
||||
skipCharacterNum := 2
|
||||
negativePrefix := ""
|
||||
if value[0] == '-' {
|
||||
skipCharacterNum++
|
||||
negativePrefix = "-"
|
||||
}
|
||||
if len(negativePrefix) > 0 {
|
||||
i, _ := strconv.ParseInt(negativePrefix+value[skipCharacterNum:], 2, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
}
|
||||
i, _ := strconv.ParseUint(negativePrefix+value[skipCharacterNum:], 2, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
case token.OctetIntegerType:
|
||||
// octet token starts with '0o' or '-0o' or '0' or '-0'
|
||||
skipCharacterNum := 1
|
||||
negativePrefix := ""
|
||||
if value[0] == '-' {
|
||||
skipCharacterNum++
|
||||
if len(value) > 2 && value[2] == 'o' {
|
||||
skipCharacterNum++
|
||||
}
|
||||
negativePrefix = "-"
|
||||
} else {
|
||||
if value[1] == 'o' {
|
||||
skipCharacterNum++
|
||||
}
|
||||
}
|
||||
if len(negativePrefix) > 0 {
|
||||
i, _ := strconv.ParseInt(negativePrefix+value[skipCharacterNum:], 8, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
}
|
||||
i, _ := strconv.ParseUint(value[skipCharacterNum:], 8, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
case token.HexIntegerType:
|
||||
// hex token starts with '0x' or '-0x'
|
||||
skipCharacterNum := 2
|
||||
negativePrefix := ""
|
||||
if value[0] == '-' {
|
||||
skipCharacterNum++
|
||||
negativePrefix = "-"
|
||||
}
|
||||
if len(negativePrefix) > 0 {
|
||||
i, _ := strconv.ParseInt(negativePrefix+value[skipCharacterNum:], 16, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
}
|
||||
i, _ := strconv.ParseUint(value[skipCharacterNum:], 16, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
var v any
|
||||
if num := token.ToNumber(tk.Value); num != nil {
|
||||
v = num.Value
|
||||
}
|
||||
if value[0] == '-' || value[0] == '+' {
|
||||
i, _ := strconv.ParseInt(value, 10, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
}
|
||||
}
|
||||
i, _ := strconv.ParseUint(value, 10, 64)
|
||||
return &IntegerNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: i,
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
|
||||
// Float create node for float value
|
||||
func Float(tk *token.Token) *FloatNode {
|
||||
f, _ := strconv.ParseFloat(removeUnderScoreFromNumber(tk.Value), 64)
|
||||
var v float64
|
||||
if num := token.ToNumber(tk.Value); num != nil && num.Type == token.NumberTypeFloat {
|
||||
value, ok := num.Value.(float64)
|
||||
if ok {
|
||||
v = value
|
||||
}
|
||||
}
|
||||
return &FloatNode{
|
||||
BaseNode: &BaseNode{},
|
||||
Token: tk,
|
||||
Value: f,
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,7 +582,9 @@ func (d *DocumentNode) String() string {
|
||||
if d.Start != nil {
|
||||
doc = append(doc, d.Start.Value)
|
||||
}
|
||||
doc = append(doc, d.Body.String())
|
||||
if d.Body != nil {
|
||||
doc = append(doc, d.Body.String())
|
||||
}
|
||||
if d.End != nil {
|
||||
doc = append(doc, d.End.Value)
|
||||
}
|
||||
@@ -619,10 +596,6 @@ func (d *DocumentNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(d.String()), nil
|
||||
}
|
||||
|
||||
func removeUnderScoreFromNumber(num string) string {
|
||||
return strings.ReplaceAll(num, "_", "")
|
||||
}
|
||||
|
||||
// NullNode type of null node
|
||||
type NullNode struct {
|
||||
*BaseNode
|
||||
@@ -654,6 +627,12 @@ func (n *NullNode) GetValue() interface{} {
|
||||
|
||||
// String returns `null` text
|
||||
func (n *NullNode) String() string {
|
||||
if n.Token.Type == token.ImplicitNullType {
|
||||
if n.Comment != nil {
|
||||
return n.Comment.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
if n.Comment != nil {
|
||||
return addCommentString("null", n.Comment)
|
||||
}
|
||||
@@ -669,6 +648,11 @@ func (n *NullNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *NullNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IntegerNode type of integer node
|
||||
type IntegerNode struct {
|
||||
*BaseNode
|
||||
@@ -716,6 +700,11 @@ func (n *IntegerNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *IntegerNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// FloatNode type of float node
|
||||
type FloatNode struct {
|
||||
*BaseNode
|
||||
@@ -764,6 +753,11 @@ func (n *FloatNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *FloatNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// StringNode type of string node
|
||||
type StringNode struct {
|
||||
*BaseNode
|
||||
@@ -794,6 +788,11 @@ func (n *StringNode) GetValue() interface{} {
|
||||
return n.Value
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *StringNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// escapeSingleQuote escapes s to a single quoted scalar.
|
||||
// https://yaml.org/spec/1.2.2/#732-single-quoted-style
|
||||
func escapeSingleQuote(s string) string {
|
||||
@@ -831,11 +830,12 @@ func (n *StringNode) String() string {
|
||||
// It works mostly, but inconsistencies occur if line break characters are mixed.
|
||||
header := token.LiteralBlockHeader(n.Value)
|
||||
space := strings.Repeat(" ", n.Token.Position.Column-1)
|
||||
indent := strings.Repeat(" ", n.Token.Position.IndentNum)
|
||||
values := []string{}
|
||||
for _, v := range strings.Split(n.Value, lbc) {
|
||||
values = append(values, fmt.Sprintf("%s %s", space, v))
|
||||
values = append(values, fmt.Sprintf("%s%s%s", space, indent, v))
|
||||
}
|
||||
block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s %s", lbc, space)), fmt.Sprintf(" %s", space))
|
||||
block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s%s%s", lbc, indent, space)), fmt.Sprintf("%s%s", indent, space))
|
||||
return fmt.Sprintf("%s%s%s", header, lbc, block)
|
||||
} else if len(n.Value) > 0 && (n.Value[0] == '{' || n.Value[0] == '[') {
|
||||
return fmt.Sprintf(`'%s'`, n.Value)
|
||||
@@ -862,11 +862,12 @@ func (n *StringNode) stringWithoutComment() string {
|
||||
// It works mostly, but inconsistencies occur if line break characters are mixed.
|
||||
header := token.LiteralBlockHeader(n.Value)
|
||||
space := strings.Repeat(" ", n.Token.Position.Column-1)
|
||||
indent := strings.Repeat(" ", n.Token.Position.IndentNum)
|
||||
values := []string{}
|
||||
for _, v := range strings.Split(n.Value, lbc) {
|
||||
values = append(values, fmt.Sprintf("%s %s", space, v))
|
||||
values = append(values, fmt.Sprintf("%s%s%s", space, indent, v))
|
||||
}
|
||||
block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s %s", lbc, space)), fmt.Sprintf(" %s", space))
|
||||
block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s%s%s", lbc, indent, space)), fmt.Sprintf(" %s", space))
|
||||
return fmt.Sprintf("%s%s%s", header, lbc, block)
|
||||
} else if len(n.Value) > 0 && (n.Value[0] == '{' || n.Value[0] == '[') {
|
||||
return fmt.Sprintf(`'%s'`, n.Value)
|
||||
@@ -931,6 +932,11 @@ func (n *LiteralNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *LiteralNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MergeKeyNode type of merge key node
|
||||
type MergeKeyNode struct {
|
||||
*BaseNode
|
||||
@@ -974,6 +980,11 @@ func (n *MergeKeyNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *MergeKeyNode) IsMergeKey() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// BoolNode type of boolean node
|
||||
type BoolNode struct {
|
||||
*BaseNode
|
||||
@@ -1021,6 +1032,11 @@ func (n *BoolNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *BoolNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// InfinityNode type of infinity node
|
||||
type InfinityNode struct {
|
||||
*BaseNode
|
||||
@@ -1068,6 +1084,11 @@ func (n *InfinityNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *InfinityNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// NanNode type of nan node
|
||||
type NanNode struct {
|
||||
*BaseNode
|
||||
@@ -1114,6 +1135,11 @@ func (n *NanNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *NanNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MapNode interface of MappingValueNode / MappingNode
|
||||
type MapNode interface {
|
||||
MapRange() *MapNodeIter
|
||||
@@ -1147,6 +1173,11 @@ func (m *MapNodeIter) Value() Node {
|
||||
return m.values[m.idx].Value
|
||||
}
|
||||
|
||||
// KeyValue returns the MappingValueNode of the iterator's current map node entry.
|
||||
func (m *MapNodeIter) KeyValue() *MappingValueNode {
|
||||
return m.values[m.idx]
|
||||
}
|
||||
|
||||
// MappingNode type of mapping node
|
||||
type MappingNode struct {
|
||||
*BaseNode
|
||||
@@ -1317,13 +1348,27 @@ func (n *MappingKeyNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *MappingKeyNode) IsMergeKey() bool {
|
||||
if n.Value == nil {
|
||||
return false
|
||||
}
|
||||
key, ok := n.Value.(MapKeyNode)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return key.IsMergeKey()
|
||||
}
|
||||
|
||||
// MappingValueNode type of mapping value
|
||||
type MappingValueNode struct {
|
||||
*BaseNode
|
||||
Start *token.Token
|
||||
Key MapKeyNode
|
||||
Value Node
|
||||
FootComment *CommentGroupNode
|
||||
Start *token.Token // delimiter token ':'.
|
||||
CollectEntry *token.Token // collect entry token ','.
|
||||
Key MapKeyNode
|
||||
Value Node
|
||||
FootComment *CommentGroupNode
|
||||
IsFlowStyle bool
|
||||
}
|
||||
|
||||
// Replace replace value node.
|
||||
@@ -1360,6 +1405,7 @@ func (n *MappingValueNode) AddColumn(col int) {
|
||||
|
||||
// SetIsFlowStyle set value to IsFlowStyle field recursively.
|
||||
func (n *MappingValueNode) SetIsFlowStyle(isFlow bool) {
|
||||
n.IsFlowStyle = isFlow
|
||||
switch value := n.Value.(type) {
|
||||
case *MappingNode:
|
||||
value.SetIsFlowStyle(isFlow)
|
||||
@@ -1390,12 +1436,20 @@ func (n *MappingValueNode) String() string {
|
||||
|
||||
func (n *MappingValueNode) toString() string {
|
||||
space := strings.Repeat(" ", n.Key.GetToken().Position.Column-1)
|
||||
if checkLineBreak(n.Key.GetToken()) {
|
||||
space = fmt.Sprintf("%s%s", "\n", space)
|
||||
}
|
||||
keyIndentLevel := n.Key.GetToken().Position.IndentLevel
|
||||
valueIndentLevel := n.Value.GetToken().Position.IndentLevel
|
||||
keyComment := n.Key.GetComment()
|
||||
if _, ok := n.Value.(ScalarNode); ok {
|
||||
return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
|
||||
} else if keyIndentLevel < valueIndentLevel {
|
||||
value := n.Value.String()
|
||||
if value == "" {
|
||||
// implicit null value.
|
||||
return fmt.Sprintf("%s%s:", space, n.Key.String())
|
||||
}
|
||||
return fmt.Sprintf("%s%s: %s", space, n.Key.String(), value)
|
||||
} else if keyIndentLevel < valueIndentLevel && !n.IsFlowStyle {
|
||||
if keyComment != nil {
|
||||
return fmt.Sprintf(
|
||||
"%s%s: %s\n%s",
|
||||
@@ -1414,7 +1468,10 @@ func (n *MappingValueNode) toString() string {
|
||||
return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
|
||||
} else if _, ok := n.Value.(*AliasNode); ok {
|
||||
return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
|
||||
} else if _, ok := n.Value.(*TagNode); ok {
|
||||
return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
|
||||
}
|
||||
|
||||
if keyComment != nil {
|
||||
return fmt.Sprintf(
|
||||
"%s%s: %s\n%s",
|
||||
@@ -1485,13 +1542,14 @@ type SequenceNode struct {
|
||||
IsFlowStyle bool
|
||||
Values []Node
|
||||
ValueHeadComments []*CommentGroupNode
|
||||
Entries []*SequenceEntryNode
|
||||
FootComment *CommentGroupNode
|
||||
}
|
||||
|
||||
// Replace replace value node.
|
||||
func (n *SequenceNode) Replace(idx int, value Node) error {
|
||||
if len(n.Values) <= idx {
|
||||
return xerrors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"invalid index for sequence: sequence length is %d, but specified %d index",
|
||||
len(n.Values), idx,
|
||||
)
|
||||
@@ -1507,6 +1565,11 @@ func (n *SequenceNode) Merge(target *SequenceNode) {
|
||||
column := n.Start.Position.Column - target.Start.Position.Column
|
||||
target.AddColumn(column)
|
||||
n.Values = append(n.Values, target.Values...)
|
||||
if len(target.ValueHeadComments) == 0 {
|
||||
n.ValueHeadComments = append(n.ValueHeadComments, make([]*CommentGroupNode, len(target.Values))...)
|
||||
return
|
||||
}
|
||||
n.ValueHeadComments = append(n.ValueHeadComments, target.ValueHeadComments...)
|
||||
}
|
||||
|
||||
// SetIsFlowStyle set value to IsFlowStyle field recursively.
|
||||
@@ -1562,7 +1625,15 @@ func (n *SequenceNode) blockStyleString() string {
|
||||
}
|
||||
|
||||
for idx, value := range n.Values {
|
||||
if value == nil {
|
||||
continue
|
||||
}
|
||||
valueStr := value.String()
|
||||
newLinePrefix := ""
|
||||
if strings.HasPrefix(valueStr, "\n") {
|
||||
valueStr = valueStr[1:]
|
||||
newLinePrefix = "\n"
|
||||
}
|
||||
splittedValues := strings.Split(valueStr, "\n")
|
||||
trimmedFirstValue := strings.TrimLeft(splittedValues[0], " ")
|
||||
diffLength := len(splittedValues[0]) - len(trimmedFirstValue)
|
||||
@@ -1585,9 +1656,10 @@ func (n *SequenceNode) blockStyleString() string {
|
||||
}
|
||||
newValue := strings.Join(newValues, "\n")
|
||||
if len(n.ValueHeadComments) == len(n.Values) && n.ValueHeadComments[idx] != nil {
|
||||
values = append(values, n.ValueHeadComments[idx].StringWithSpace(n.Start.Position.Column-1))
|
||||
values = append(values, fmt.Sprintf("%s%s", newLinePrefix, n.ValueHeadComments[idx].StringWithSpace(n.Start.Position.Column-1)))
|
||||
newLinePrefix = ""
|
||||
}
|
||||
values = append(values, fmt.Sprintf("%s- %s", space, newValue))
|
||||
values = append(values, fmt.Sprintf("%s%s- %s", newLinePrefix, space, newValue))
|
||||
}
|
||||
if n.FootComment != nil {
|
||||
values = append(values, n.FootComment.StringWithSpace(n.Start.Position.Column-1))
|
||||
@@ -1616,6 +1688,87 @@ func (n *SequenceNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// SequenceEntryNode is the sequence entry.
|
||||
type SequenceEntryNode struct {
|
||||
*BaseNode
|
||||
HeadComment *CommentGroupNode // head comment.
|
||||
LineComment *CommentGroupNode // line comment e.g.) - # comment.
|
||||
Start *token.Token // entry token.
|
||||
Value Node // value node.
|
||||
}
|
||||
|
||||
// String node to text
|
||||
func (n *SequenceEntryNode) String() string {
|
||||
return "" // TODO
|
||||
}
|
||||
|
||||
// GetToken returns token instance
|
||||
func (n *SequenceEntryNode) GetToken() *token.Token {
|
||||
return n.Start
|
||||
}
|
||||
|
||||
// Type returns type of node
|
||||
func (n *SequenceEntryNode) Type() NodeType {
|
||||
return SequenceEntryType
|
||||
}
|
||||
|
||||
// AddColumn add column number to child nodes recursively
|
||||
func (n *SequenceEntryNode) AddColumn(col int) {
|
||||
n.Start.AddColumn(col)
|
||||
}
|
||||
|
||||
// SetComment set line comment.
|
||||
func (n *SequenceEntryNode) SetComment(cm *CommentGroupNode) error {
|
||||
n.LineComment = cm
|
||||
return nil
|
||||
}
|
||||
|
||||
// Comment returns comment token instance
|
||||
func (n *SequenceEntryNode) GetComment() *CommentGroupNode {
|
||||
return n.LineComment
|
||||
}
|
||||
|
||||
// MarshalYAML
|
||||
func (n *SequenceEntryNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
func (n *SequenceEntryNode) Read(p []byte) (int, error) {
|
||||
return readNode(p, n)
|
||||
}
|
||||
|
||||
// SequenceEntry creates SequenceEntryNode instance.
|
||||
func SequenceEntry(start *token.Token, value Node, headComment *CommentGroupNode) *SequenceEntryNode {
|
||||
return &SequenceEntryNode{
|
||||
BaseNode: &BaseNode{},
|
||||
HeadComment: headComment,
|
||||
Start: start,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceMergeValue creates SequenceMergeValueNode instance.
|
||||
func SequenceMergeValue(values ...MapNode) *SequenceMergeValueNode {
|
||||
return &SequenceMergeValueNode{
|
||||
values: values,
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceMergeValueNode is used to convert the Sequence node specified for the merge key into a MapNode format.
|
||||
type SequenceMergeValueNode struct {
|
||||
values []MapNode
|
||||
}
|
||||
|
||||
// MapRange returns MapNodeIter instance.
|
||||
func (n *SequenceMergeValueNode) MapRange() *MapNodeIter {
|
||||
ret := &MapNodeIter{idx: startRangeIndex}
|
||||
for _, value := range n.values {
|
||||
iter := value.MapRange()
|
||||
ret.values = append(ret.values, iter.values...)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// AnchorNode type of anchor node
|
||||
type AnchorNode struct {
|
||||
*BaseNode
|
||||
@@ -1624,6 +1777,10 @@ type AnchorNode struct {
|
||||
Value Node
|
||||
}
|
||||
|
||||
func (n *AnchorNode) stringWithoutComment() string {
|
||||
return n.Value.String()
|
||||
}
|
||||
|
||||
func (n *AnchorNode) SetName(name string) error {
|
||||
if n.Name == nil {
|
||||
return ErrInvalidAnchorName
|
||||
@@ -1649,6 +1806,10 @@ func (n *AnchorNode) GetToken() *token.Token {
|
||||
return n.Start
|
||||
}
|
||||
|
||||
func (n *AnchorNode) GetValue() any {
|
||||
return n.Value.GetToken().Value
|
||||
}
|
||||
|
||||
// AddColumn add column number to child nodes recursively
|
||||
func (n *AnchorNode) AddColumn(col int) {
|
||||
n.Start.AddColumn(col)
|
||||
@@ -1662,15 +1823,18 @@ func (n *AnchorNode) AddColumn(col int) {
|
||||
|
||||
// String anchor to text
|
||||
func (n *AnchorNode) String() string {
|
||||
anchor := "&" + n.Name.String()
|
||||
value := n.Value.String()
|
||||
if len(strings.Split(value, "\n")) > 1 {
|
||||
return fmt.Sprintf("&%s\n%s", n.Name.String(), value)
|
||||
} else if s, ok := n.Value.(*SequenceNode); ok && !s.IsFlowStyle {
|
||||
return fmt.Sprintf("&%s\n%s", n.Name.String(), value)
|
||||
if s, ok := n.Value.(*SequenceNode); ok && !s.IsFlowStyle {
|
||||
return fmt.Sprintf("%s\n%s", anchor, value)
|
||||
} else if m, ok := n.Value.(*MappingNode); ok && !m.IsFlowStyle {
|
||||
return fmt.Sprintf("&%s\n%s", n.Name.String(), value)
|
||||
return fmt.Sprintf("%s\n%s", anchor, value)
|
||||
}
|
||||
return fmt.Sprintf("&%s %s", n.Name.String(), value)
|
||||
if value == "" {
|
||||
// implicit null value.
|
||||
return anchor
|
||||
}
|
||||
return fmt.Sprintf("%s %s", anchor, value)
|
||||
}
|
||||
|
||||
// MarshalYAML encodes to a YAML text
|
||||
@@ -1678,6 +1842,18 @@ func (n *AnchorNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *AnchorNode) IsMergeKey() bool {
|
||||
if n.Value == nil {
|
||||
return false
|
||||
}
|
||||
key, ok := n.Value.(MapKeyNode)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return key.IsMergeKey()
|
||||
}
|
||||
|
||||
// AliasNode type of alias node
|
||||
type AliasNode struct {
|
||||
*BaseNode
|
||||
@@ -1685,6 +1861,10 @@ type AliasNode struct {
|
||||
Value Node
|
||||
}
|
||||
|
||||
func (n *AliasNode) stringWithoutComment() string {
|
||||
return n.Value.String()
|
||||
}
|
||||
|
||||
func (n *AliasNode) SetName(name string) error {
|
||||
if n.Value == nil {
|
||||
return ErrInvalidAliasName
|
||||
@@ -1710,6 +1890,10 @@ func (n *AliasNode) GetToken() *token.Token {
|
||||
return n.Start
|
||||
}
|
||||
|
||||
func (n *AliasNode) GetValue() any {
|
||||
return n.Value.GetToken().Value
|
||||
}
|
||||
|
||||
// AddColumn add column number to child nodes recursively
|
||||
func (n *AliasNode) AddColumn(col int) {
|
||||
n.Start.AddColumn(col)
|
||||
@@ -1728,11 +1912,20 @@ func (n *AliasNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *AliasNode) IsMergeKey() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// DirectiveNode type of directive node
|
||||
type DirectiveNode struct {
|
||||
*BaseNode
|
||||
// Start is '%' token.
|
||||
Start *token.Token
|
||||
Value Node
|
||||
// Name is directive name e.g.) "YAML" or "TAG".
|
||||
Name Node
|
||||
// Values is directive values e.g.) "1.2" or "!!" and "tag:clarkevans.com,2002:app/".
|
||||
Values []Node
|
||||
}
|
||||
|
||||
// Read implements (io.Reader).Read
|
||||
@@ -1750,14 +1943,21 @@ func (n *DirectiveNode) GetToken() *token.Token {
|
||||
|
||||
// AddColumn add column number to child nodes recursively
|
||||
func (n *DirectiveNode) AddColumn(col int) {
|
||||
if n.Value != nil {
|
||||
n.Value.AddColumn(col)
|
||||
if n.Name != nil {
|
||||
n.Name.AddColumn(col)
|
||||
}
|
||||
for _, value := range n.Values {
|
||||
value.AddColumn(col)
|
||||
}
|
||||
}
|
||||
|
||||
// String directive to text
|
||||
func (n *DirectiveNode) String() string {
|
||||
return fmt.Sprintf("%s%s", n.Start.Value, n.Value.String())
|
||||
values := make([]string, 0, len(n.Values))
|
||||
for _, val := range n.Values {
|
||||
values = append(values, val.String())
|
||||
}
|
||||
return strings.Join(append([]string{"%" + n.Name.String()}, values...), " ")
|
||||
}
|
||||
|
||||
// MarshalYAML encodes to a YAML text
|
||||
@@ -1768,8 +1968,21 @@ func (n *DirectiveNode) MarshalYAML() ([]byte, error) {
|
||||
// TagNode type of tag node
|
||||
type TagNode struct {
|
||||
*BaseNode
|
||||
Start *token.Token
|
||||
Value Node
|
||||
Directive *DirectiveNode
|
||||
Start *token.Token
|
||||
Value Node
|
||||
}
|
||||
|
||||
func (n *TagNode) GetValue() any {
|
||||
scalar, ok := n.Value.(ScalarNode)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return scalar.GetValue()
|
||||
}
|
||||
|
||||
func (n *TagNode) stringWithoutComment() string {
|
||||
return n.Value.String()
|
||||
}
|
||||
|
||||
// Read implements (io.Reader).Read
|
||||
@@ -1795,7 +2008,14 @@ func (n *TagNode) AddColumn(col int) {
|
||||
|
||||
// String tag to text
|
||||
func (n *TagNode) String() string {
|
||||
return fmt.Sprintf("%s %s", n.Start.Value, n.Value.String())
|
||||
value := n.Value.String()
|
||||
if s, ok := n.Value.(*SequenceNode); ok && !s.IsFlowStyle {
|
||||
return fmt.Sprintf("%s\n%s", n.Start.Value, value)
|
||||
} else if m, ok := n.Value.(*MappingNode); ok && !m.IsFlowStyle {
|
||||
return fmt.Sprintf("%s\n%s", n.Start.Value, value)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s", n.Start.Value, value)
|
||||
}
|
||||
|
||||
// MarshalYAML encodes to a YAML text
|
||||
@@ -1803,6 +2023,26 @@ func (n *TagNode) MarshalYAML() ([]byte, error) {
|
||||
return []byte(n.String()), nil
|
||||
}
|
||||
|
||||
// IsMergeKey returns whether it is a MergeKey node.
|
||||
func (n *TagNode) IsMergeKey() bool {
|
||||
if n.Value == nil {
|
||||
return false
|
||||
}
|
||||
key, ok := n.Value.(MapKeyNode)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return key.IsMergeKey()
|
||||
}
|
||||
|
||||
func (n *TagNode) ArrayRange() *ArrayNodeIter {
|
||||
arr, ok := n.Value.(ArrayNode)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return arr.ArrayRange()
|
||||
}
|
||||
|
||||
// CommentNode type of comment node
|
||||
type CommentNode struct {
|
||||
*BaseNode
|
||||
@@ -1880,10 +2120,13 @@ func (n *CommentGroupNode) StringWithSpace(col int) string {
|
||||
values := []string{}
|
||||
space := strings.Repeat(" ", col)
|
||||
for _, comment := range n.Comments {
|
||||
space := space
|
||||
if checkLineBreak(comment.Token) {
|
||||
space = fmt.Sprintf("%s%s", "\n", space)
|
||||
}
|
||||
values = append(values, space+comment.String())
|
||||
}
|
||||
return strings.Join(values, "\n")
|
||||
|
||||
}
|
||||
|
||||
// MarshalYAML encodes to a YAML text
|
||||
@@ -1930,7 +2173,10 @@ func Walk(v Visitor, node Node) {
|
||||
Walk(v, n.Value)
|
||||
case *DirectiveNode:
|
||||
walkComment(v, n.BaseNode)
|
||||
Walk(v, n.Value)
|
||||
Walk(v, n.Name)
|
||||
for _, value := range n.Values {
|
||||
Walk(v, value)
|
||||
}
|
||||
case *TagNode:
|
||||
walkComment(v, n.BaseNode)
|
||||
Walk(v, n.Value)
|
||||
@@ -2016,7 +2262,14 @@ func (f *parentFinder) walk(parent, node Node) Node {
|
||||
case *LiteralNode:
|
||||
return f.walk(node, n.Value)
|
||||
case *DirectiveNode:
|
||||
return f.walk(node, n.Value)
|
||||
if found := f.walk(node, n.Name); found != nil {
|
||||
return found
|
||||
}
|
||||
for _, value := range n.Values {
|
||||
if found := f.walk(node, value); found != nil {
|
||||
return found
|
||||
}
|
||||
}
|
||||
case *TagNode:
|
||||
return f.walk(node, n.Value)
|
||||
case *DocumentNode:
|
||||
@@ -2092,10 +2345,10 @@ func Merge(dst Node, src Node) error {
|
||||
err := &ErrInvalidMergeType{dst: dst, src: src}
|
||||
switch dst.Type() {
|
||||
case DocumentType:
|
||||
node := dst.(*DocumentNode)
|
||||
node, _ := dst.(*DocumentNode)
|
||||
return Merge(node.Body, src)
|
||||
case MappingType:
|
||||
node := dst.(*MappingNode)
|
||||
node, _ := dst.(*MappingNode)
|
||||
target, ok := src.(*MappingNode)
|
||||
if !ok {
|
||||
return err
|
||||
@@ -2103,7 +2356,7 @@ func Merge(dst Node, src Node) error {
|
||||
node.Merge(target)
|
||||
return nil
|
||||
case SequenceType:
|
||||
node := dst.(*SequenceNode)
|
||||
node, _ := dst.(*SequenceNode)
|
||||
target, ok := src.(*SequenceNode)
|
||||
if !ok {
|
||||
return err
|
||||
|
||||
37
vendor/github.com/goccy/go-yaml/context.go
generated
vendored
Normal file
37
vendor/github.com/goccy/go-yaml/context.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package yaml
|
||||
|
||||
import "context"
|
||||
|
||||
type (
|
||||
ctxMergeKey struct{}
|
||||
ctxAnchorKey struct{}
|
||||
)
|
||||
|
||||
func withMerge(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, ctxMergeKey{}, true)
|
||||
}
|
||||
|
||||
func isMerge(ctx context.Context) bool {
|
||||
v, ok := ctx.Value(ctxMergeKey{}).(bool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func withAnchor(ctx context.Context, name string) context.Context {
|
||||
anchorMap := getAnchorMap(ctx)
|
||||
if anchorMap == nil {
|
||||
anchorMap = make(map[string]struct{})
|
||||
}
|
||||
anchorMap[name] = struct{}{}
|
||||
return context.WithValue(ctx, ctxAnchorKey{}, anchorMap)
|
||||
}
|
||||
|
||||
func getAnchorMap(ctx context.Context) map[string]struct{} {
|
||||
v, ok := ctx.Value(ctxAnchorKey{}).(map[string]struct{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
1214
vendor/github.com/goccy/go-yaml/decode.go
generated
vendored
1214
vendor/github.com/goccy/go-yaml/decode.go
generated
vendored
File diff suppressed because it is too large
Load Diff
511
vendor/github.com/goccy/go-yaml/encode.go
generated
vendored
511
vendor/github.com/goccy/go-yaml/encode.go
generated
vendored
@@ -17,7 +17,6 @@ import (
|
||||
"github.com/goccy/go-yaml/parser"
|
||||
"github.com/goccy/go-yaml/printer"
|
||||
"github.com/goccy/go-yaml/token"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -29,24 +28,29 @@ const (
|
||||
type Encoder struct {
|
||||
writer io.Writer
|
||||
opts []EncodeOption
|
||||
indent int
|
||||
indentSequence bool
|
||||
singleQuote bool
|
||||
isFlowStyle bool
|
||||
isJSONStyle bool
|
||||
useJSONMarshaler bool
|
||||
enableSmartAnchor bool
|
||||
aliasRefToName map[uintptr]string
|
||||
anchorRefToName map[uintptr]string
|
||||
anchorNameMap map[string]struct{}
|
||||
anchorCallback func(*ast.AnchorNode, interface{}) error
|
||||
anchorPtrToNameMap map[uintptr]string
|
||||
customMarshalerMap map[reflect.Type]func(interface{}) ([]byte, error)
|
||||
customMarshalerMap map[reflect.Type]func(context.Context, interface{}) ([]byte, error)
|
||||
omitZero bool
|
||||
omitEmpty bool
|
||||
autoInt bool
|
||||
useLiteralStyleIfMultiline bool
|
||||
commentMap map[*Path][]*Comment
|
||||
written bool
|
||||
|
||||
line int
|
||||
column int
|
||||
offset int
|
||||
indentNum int
|
||||
indentLevel int
|
||||
line int
|
||||
column int
|
||||
offset int
|
||||
indentNum int
|
||||
indentLevel int
|
||||
indentSequence bool
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
@@ -55,12 +59,14 @@ func NewEncoder(w io.Writer, opts ...EncodeOption) *Encoder {
|
||||
return &Encoder{
|
||||
writer: w,
|
||||
opts: opts,
|
||||
indent: DefaultIndentSpaces,
|
||||
anchorPtrToNameMap: map[uintptr]string{},
|
||||
customMarshalerMap: map[reflect.Type]func(interface{}) ([]byte, error){},
|
||||
customMarshalerMap: map[reflect.Type]func(context.Context, interface{}) ([]byte, error){},
|
||||
line: 1,
|
||||
column: 1,
|
||||
offset: 0,
|
||||
indentNum: DefaultIndentSpaces,
|
||||
anchorRefToName: make(map[uintptr]string),
|
||||
anchorNameMap: make(map[string]struct{}),
|
||||
aliasRefToName: make(map[uintptr]string),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,19 +90,19 @@ func (e *Encoder) Encode(v interface{}) error {
|
||||
func (e *Encoder) EncodeContext(ctx context.Context, v interface{}) error {
|
||||
node, err := e.EncodeToNodeContext(ctx, v)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to encode to node")
|
||||
return err
|
||||
}
|
||||
if err := e.setCommentByCommentMap(node); err != nil {
|
||||
return errors.Wrapf(err, "failed to set comment by comment map")
|
||||
return err
|
||||
}
|
||||
if !e.written {
|
||||
e.written = true
|
||||
} else {
|
||||
// write document separator
|
||||
e.writer.Write([]byte("---\n"))
|
||||
_, _ = e.writer.Write([]byte("---\n"))
|
||||
}
|
||||
var p printer.Printer
|
||||
e.writer.Write(p.PrintNode(node))
|
||||
_, _ = e.writer.Write(p.PrintNode(node))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,12 +115,19 @@ func (e *Encoder) EncodeToNode(v interface{}) (ast.Node, error) {
|
||||
func (e *Encoder) EncodeToNodeContext(ctx context.Context, v interface{}) (ast.Node, error) {
|
||||
for _, opt := range e.opts {
|
||||
if err := opt(e); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to run option for encoder")
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if e.enableSmartAnchor {
|
||||
// during the first encoding, store all mappings between alias addresses and their names.
|
||||
if _, err := e.encodeValue(ctx, reflect.ValueOf(v), 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e.clearSmartAnchorRef()
|
||||
}
|
||||
node, err := e.encodeValue(ctx, reflect.ValueOf(v), 1)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode value")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -126,7 +139,7 @@ func (e *Encoder) setCommentByCommentMap(node ast.Node) error {
|
||||
for path, comments := range e.commentMap {
|
||||
n, err := path.FilterNode(node)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to filter node")
|
||||
return err
|
||||
}
|
||||
if n == nil {
|
||||
continue
|
||||
@@ -140,15 +153,15 @@ func (e *Encoder) setCommentByCommentMap(node ast.Node) error {
|
||||
switch comment.Position {
|
||||
case CommentHeadPosition:
|
||||
if err := e.setHeadComment(node, n, commentGroup); err != nil {
|
||||
return errors.Wrapf(err, "failed to set head comment")
|
||||
return err
|
||||
}
|
||||
case CommentLinePosition:
|
||||
if err := e.setLineComment(node, n, commentGroup); err != nil {
|
||||
return errors.Wrapf(err, "failed to set line comment")
|
||||
return err
|
||||
}
|
||||
case CommentFootPosition:
|
||||
if err := e.setFootComment(node, n, commentGroup); err != nil {
|
||||
return errors.Wrapf(err, "failed to set foot comment")
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return ErrUnknownCommentPositionType
|
||||
@@ -166,11 +179,11 @@ func (e *Encoder) setHeadComment(node ast.Node, filtered ast.Node, comment *ast.
|
||||
switch p := parent.(type) {
|
||||
case *ast.MappingValueNode:
|
||||
if err := p.SetComment(comment); err != nil {
|
||||
return errors.Wrapf(err, "failed to set comment")
|
||||
return err
|
||||
}
|
||||
case *ast.MappingNode:
|
||||
if err := p.SetComment(comment); err != nil {
|
||||
return errors.Wrapf(err, "failed to set comment")
|
||||
return err
|
||||
}
|
||||
case *ast.SequenceNode:
|
||||
if len(p.ValueHeadComments) == 0 {
|
||||
@@ -196,11 +209,11 @@ func (e *Encoder) setLineComment(node ast.Node, filtered ast.Node, comment *ast.
|
||||
// Line comment cannot be set for mapping value node.
|
||||
// It should probably be set for the parent map node
|
||||
if err := e.setLineCommentToParentMapNode(node, filtered, comment); err != nil {
|
||||
return errors.Wrapf(err, "failed to set line comment to parent node")
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if err := filtered.SetComment(comment); err != nil {
|
||||
return errors.Wrapf(err, "failed to set comment")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -214,11 +227,11 @@ func (e *Encoder) setLineCommentToParentMapNode(node ast.Node, filtered ast.Node
|
||||
switch p := parent.(type) {
|
||||
case *ast.MappingValueNode:
|
||||
if err := p.Key.SetComment(comment); err != nil {
|
||||
return errors.Wrapf(err, "failed to set comment")
|
||||
return err
|
||||
}
|
||||
case *ast.MappingNode:
|
||||
if err := p.SetComment(comment); err != nil {
|
||||
return errors.Wrapf(err, "failed to set comment")
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return ErrUnsupportedLinePositionType(parent)
|
||||
@@ -247,7 +260,7 @@ func (e *Encoder) setFootComment(node ast.Node, filtered ast.Node, comment *ast.
|
||||
func (e *Encoder) encodeDocument(doc []byte) (ast.Node, error) {
|
||||
f, err := parser.ParseBytes(doc, 0)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse yaml")
|
||||
return nil, err
|
||||
}
|
||||
for _, docNode := range f.Docs {
|
||||
if docNode.Body != nil {
|
||||
@@ -288,7 +301,7 @@ func (e *Encoder) existsTypeInCustomMarshalerMap(t reflect.Type) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *Encoder) marshalerFromCustomMarshalerMap(t reflect.Type) (func(interface{}) ([]byte, error), bool) {
|
||||
func (e *Encoder) marshalerFromCustomMarshalerMap(t reflect.Type) (func(context.Context, interface{}) ([]byte, error), bool) {
|
||||
if marshaler, exists := e.customMarshalerMap[t]; exists {
|
||||
return marshaler, exists
|
||||
}
|
||||
@@ -318,7 +331,7 @@ func (e *Encoder) canEncodeByMarshaler(v reflect.Value) bool {
|
||||
return true
|
||||
case InterfaceMarshaler:
|
||||
return true
|
||||
case time.Time:
|
||||
case time.Time, *time.Time:
|
||||
return true
|
||||
case time.Duration:
|
||||
return true
|
||||
@@ -334,13 +347,13 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
iface := v.Interface()
|
||||
|
||||
if marshaler, exists := e.marshalerFromCustomMarshalerMap(v.Type()); exists {
|
||||
doc, err := marshaler(iface)
|
||||
doc, err := marshaler(ctx, iface)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalYAML")
|
||||
return nil, err
|
||||
}
|
||||
node, err := e.encodeDocument(doc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode document")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -348,11 +361,11 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
if marshaler, ok := iface.(BytesMarshalerContext); ok {
|
||||
doc, err := marshaler.MarshalYAML(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalYAML")
|
||||
return nil, err
|
||||
}
|
||||
node, err := e.encodeDocument(doc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode document")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -360,11 +373,11 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
if marshaler, ok := iface.(BytesMarshaler); ok {
|
||||
doc, err := marshaler.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalYAML")
|
||||
return nil, err
|
||||
}
|
||||
node, err := e.encodeDocument(doc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode document")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -372,7 +385,7 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
if marshaler, ok := iface.(InterfaceMarshalerContext); ok {
|
||||
marshalV, err := marshaler.MarshalYAML(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalYAML")
|
||||
return nil, err
|
||||
}
|
||||
return e.encodeValue(ctx, reflect.ValueOf(marshalV), column)
|
||||
}
|
||||
@@ -380,7 +393,7 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
if marshaler, ok := iface.(InterfaceMarshaler); ok {
|
||||
marshalV, err := marshaler.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalYAML")
|
||||
return nil, err
|
||||
}
|
||||
return e.encodeValue(ctx, reflect.ValueOf(marshalV), column)
|
||||
}
|
||||
@@ -388,20 +401,21 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
if t, ok := iface.(time.Time); ok {
|
||||
return e.encodeTime(t, column), nil
|
||||
}
|
||||
// Handle *time.Time explicitly since it implements TextMarshaler and shouldn't be treated as plain text
|
||||
if t, ok := iface.(*time.Time); ok && t != nil {
|
||||
return e.encodeTime(*t, column), nil
|
||||
}
|
||||
|
||||
if t, ok := iface.(time.Duration); ok {
|
||||
return e.encodeDuration(t, column), nil
|
||||
}
|
||||
|
||||
if marshaler, ok := iface.(encoding.TextMarshaler); ok {
|
||||
doc, err := marshaler.MarshalText()
|
||||
text, err := marshaler.MarshalText()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalText")
|
||||
}
|
||||
node, err := e.encodeDocument(doc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode document")
|
||||
return nil, err
|
||||
}
|
||||
node := e.encodeString(string(text), column)
|
||||
return node, nil
|
||||
}
|
||||
|
||||
@@ -409,21 +423,21 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
|
||||
if marshaler, ok := iface.(jsonMarshaler); ok {
|
||||
jsonBytes, err := marshaler.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to MarshalJSON")
|
||||
return nil, err
|
||||
}
|
||||
doc, err := JSONToYAML(jsonBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to convert json to yaml")
|
||||
return nil, err
|
||||
}
|
||||
node, err := e.encodeDocument(doc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode document")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("does not implemented Marshaler")
|
||||
return nil, errors.New("does not implemented Marshaler")
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int) (ast.Node, error) {
|
||||
@@ -433,7 +447,7 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
|
||||
if e.canEncodeByMarshaler(v) {
|
||||
node, err := e.encodeByMarshaler(ctx, v, column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode by marshaler")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -447,12 +461,8 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
|
||||
case reflect.Float64:
|
||||
return e.encodeFloat(v.Float(), 64), nil
|
||||
case reflect.Ptr:
|
||||
anchorName := e.anchorPtrToNameMap[v.Pointer()]
|
||||
if anchorName != "" {
|
||||
aliasName := anchorName
|
||||
alias := ast.Alias(token.New("*", "*", e.pos(column)))
|
||||
alias.Value = ast.String(token.New(aliasName, aliasName, e.pos(column)))
|
||||
return alias, nil
|
||||
if value := e.encodePtrAnchor(v, column); value != nil {
|
||||
return value, nil
|
||||
}
|
||||
return e.encodeValue(ctx, v.Elem(), column)
|
||||
case reflect.Interface:
|
||||
@@ -465,6 +475,9 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
|
||||
if mapSlice, ok := v.Interface().(MapSlice); ok {
|
||||
return e.encodeMapSlice(ctx, mapSlice, column)
|
||||
}
|
||||
if value := e.encodePtrAnchor(v, column); value != nil {
|
||||
return value, nil
|
||||
}
|
||||
return e.encodeSlice(ctx, v)
|
||||
case reflect.Array:
|
||||
return e.encodeArray(ctx, v)
|
||||
@@ -479,12 +492,27 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
|
||||
}
|
||||
return e.encodeStruct(ctx, v, column)
|
||||
case reflect.Map:
|
||||
return e.encodeMap(ctx, v, column), nil
|
||||
if value := e.encodePtrAnchor(v, column); value != nil {
|
||||
return value, nil
|
||||
}
|
||||
return e.encodeMap(ctx, v, column)
|
||||
default:
|
||||
return nil, xerrors.Errorf("unknown value type %s", v.Type().String())
|
||||
return nil, fmt.Errorf("unknown value type %s", v.Type().String())
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Encoder) encodePtrAnchor(v reflect.Value, column int) ast.Node {
|
||||
anchorName, exists := e.getAnchor(v.Pointer())
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
aliasName := anchorName
|
||||
alias := ast.Alias(token.New("*", "*", e.pos(column)))
|
||||
alias.Value = ast.String(token.New(aliasName, aliasName, e.pos(column)))
|
||||
e.setSmartAlias(aliasName, v.Pointer())
|
||||
return alias
|
||||
}
|
||||
|
||||
func (e *Encoder) pos(column int) *token.Position {
|
||||
return &token.Position{
|
||||
Line: e.line,
|
||||
@@ -501,12 +529,12 @@ func (e *Encoder) encodeNil() *ast.NullNode {
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeInt(v int64) *ast.IntegerNode {
|
||||
value := fmt.Sprint(v)
|
||||
value := strconv.FormatInt(v, 10)
|
||||
return ast.Integer(token.New(value, value, e.pos(e.column)))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeUint(v uint64) *ast.IntegerNode {
|
||||
value := fmt.Sprint(v)
|
||||
value := strconv.FormatUint(v, 10)
|
||||
return ast.Integer(token.New(value, value, e.pos(e.column)))
|
||||
}
|
||||
|
||||
@@ -523,6 +551,9 @@ func (e *Encoder) encodeFloat(v float64, bitSize int) ast.Node {
|
||||
}
|
||||
value := strconv.FormatFloat(v, 'g', -1, bitSize)
|
||||
if !strings.Contains(value, ".") && !strings.Contains(value, "e") {
|
||||
if e.autoInt {
|
||||
return ast.Integer(token.New(value, value, e.pos(e.column)))
|
||||
}
|
||||
// append x.0 suffix to keep float value context
|
||||
value = fmt.Sprintf("%s.0", value)
|
||||
}
|
||||
@@ -539,6 +570,17 @@ func (e *Encoder) isNeedQuoted(v string) bool {
|
||||
if e.isFlowStyle && strings.ContainsAny(v, `]},'"`) {
|
||||
return true
|
||||
}
|
||||
if e.isFlowStyle {
|
||||
for i := 0; i < len(v); i++ {
|
||||
if v[i] != ':' {
|
||||
continue
|
||||
}
|
||||
if i+1 < len(v) && v[i+1] == '/' {
|
||||
continue
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
if token.IsNeedQuoted(v) {
|
||||
return true
|
||||
}
|
||||
@@ -557,45 +599,41 @@ func (e *Encoder) encodeString(v string, column int) *ast.StringNode {
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeBool(v bool) *ast.BoolNode {
|
||||
value := fmt.Sprint(v)
|
||||
value := strconv.FormatBool(v)
|
||||
return ast.Bool(token.New(value, value, e.pos(e.column)))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeSlice(ctx context.Context, value reflect.Value) (*ast.SequenceNode, error) {
|
||||
if e.indentSequence {
|
||||
e.column += e.indent
|
||||
e.column += e.indentNum
|
||||
defer func() { e.column -= e.indentNum }()
|
||||
}
|
||||
column := e.column
|
||||
sequence := ast.Sequence(token.New("-", "-", e.pos(column)), e.isFlowStyle)
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
node, err := e.encodeValue(ctx, value.Index(i), column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode value for slice")
|
||||
return nil, err
|
||||
}
|
||||
sequence.Values = append(sequence.Values, node)
|
||||
}
|
||||
if e.indentSequence {
|
||||
e.column -= e.indent
|
||||
}
|
||||
return sequence, nil
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeArray(ctx context.Context, value reflect.Value) (*ast.SequenceNode, error) {
|
||||
if e.indentSequence {
|
||||
e.column += e.indent
|
||||
e.column += e.indentNum
|
||||
defer func() { e.column -= e.indentNum }()
|
||||
}
|
||||
column := e.column
|
||||
sequence := ast.Sequence(token.New("-", "-", e.pos(column)), e.isFlowStyle)
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
node, err := e.encodeValue(ctx, value.Index(i), column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode value for array")
|
||||
return nil, err
|
||||
}
|
||||
sequence.Values = append(sequence.Values, node)
|
||||
}
|
||||
if e.indentSequence {
|
||||
e.column -= e.indent
|
||||
}
|
||||
return sequence, nil
|
||||
}
|
||||
|
||||
@@ -604,10 +642,13 @@ func (e *Encoder) encodeMapItem(ctx context.Context, item MapItem, column int) (
|
||||
v := reflect.ValueOf(item.Value)
|
||||
value, err := e.encodeValue(ctx, v, column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode MapItem")
|
||||
return nil, err
|
||||
}
|
||||
if e.isMapNode(value) {
|
||||
value.AddColumn(e.indent)
|
||||
value.AddColumn(e.indentNum)
|
||||
}
|
||||
if e.isTagAndMapNode(value) {
|
||||
value.AddColumn(e.indentNum)
|
||||
}
|
||||
return ast.MappingValue(
|
||||
token.New("", "", e.pos(column)),
|
||||
@@ -619,11 +660,11 @@ func (e *Encoder) encodeMapItem(ctx context.Context, item MapItem, column int) (
|
||||
func (e *Encoder) encodeMapSlice(ctx context.Context, value MapSlice, column int) (*ast.MappingNode, error) {
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||
for _, item := range value {
|
||||
value, err := e.encodeMapItem(ctx, item, column)
|
||||
encoded, err := e.encodeMapItem(ctx, item, column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode MapItem for MapSlice")
|
||||
return nil, err
|
||||
}
|
||||
node.Values = append(node.Values, value)
|
||||
node.Values = append(node.Values, encoded)
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -633,7 +674,12 @@ func (e *Encoder) isMapNode(node ast.Node) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int) ast.Node {
|
||||
func (e *Encoder) isTagAndMapNode(node ast.Node) bool {
|
||||
tn, ok := node.(*ast.TagNode)
|
||||
return ok && e.isMapNode(tn.Value)
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int) (ast.Node, error) {
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||
keys := make([]interface{}, len(value.MapKeys()))
|
||||
for i, k := range value.MapKeys() {
|
||||
@@ -645,20 +691,35 @@ func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int
|
||||
for _, key := range keys {
|
||||
k := reflect.ValueOf(key)
|
||||
v := value.MapIndex(k)
|
||||
value, err := e.encodeValue(ctx, v, column)
|
||||
encoded, err := e.encodeValue(ctx, v, column)
|
||||
if err != nil {
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
if e.isMapNode(value) {
|
||||
value.AddColumn(e.indent)
|
||||
if e.isMapNode(encoded) {
|
||||
encoded.AddColumn(e.indentNum)
|
||||
}
|
||||
if e.isTagAndMapNode(encoded) {
|
||||
encoded.AddColumn(e.indentNum)
|
||||
}
|
||||
keyText := fmt.Sprint(key)
|
||||
vRef := e.toPointer(v)
|
||||
|
||||
// during the second encoding, an anchor is assigned if it is found to be used by an alias.
|
||||
if aliasName, exists := e.getSmartAlias(vRef); exists {
|
||||
anchorName := aliasName
|
||||
anchorNode := ast.Anchor(token.New("&", "&", e.pos(column)))
|
||||
anchorNode.Name = ast.String(token.New(anchorName, anchorName, e.pos(column)))
|
||||
anchorNode.Value = encoded
|
||||
encoded = anchorNode
|
||||
}
|
||||
node.Values = append(node.Values, ast.MappingValue(
|
||||
nil,
|
||||
e.encodeString(fmt.Sprint(key), column),
|
||||
value,
|
||||
e.encodeString(keyText, column),
|
||||
encoded,
|
||||
))
|
||||
e.setSmartAnchor(vRef, keyText)
|
||||
}
|
||||
return node
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// IsZeroer is used to check whether an object is zero to determine
|
||||
@@ -668,7 +729,70 @@ type IsZeroer interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func (e *Encoder) isZeroValue(v reflect.Value) bool {
|
||||
func (e *Encoder) isOmittedByOmitZero(v reflect.Value) bool {
|
||||
kind := v.Kind()
|
||||
if z, ok := v.Interface().(IsZeroer); ok {
|
||||
if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
|
||||
return true
|
||||
}
|
||||
return z.IsZero()
|
||||
}
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
return len(v.String()) == 0
|
||||
case reflect.Interface, reflect.Ptr, reflect.Slice, reflect.Map:
|
||||
return v.IsNil()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Struct:
|
||||
vt := v.Type()
|
||||
for i := v.NumField() - 1; i >= 0; i-- {
|
||||
if vt.Field(i).PkgPath != "" {
|
||||
continue // private field
|
||||
}
|
||||
if !e.isOmittedByOmitZero(v.Field(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *Encoder) isOmittedByOmitEmptyOption(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
return len(v.String()) == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
case reflect.Slice, reflect.Map:
|
||||
return v.Len() == 0
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// The current implementation of the omitempty tag combines the functionality of encoding/json's omitempty and omitzero tags.
|
||||
// This stems from a historical decision to respect the implementation of gopkg.in/yaml.v2, but it has caused confusion,
|
||||
// so we are working to integrate it into the functionality of encoding/json. (However, this will take some time.)
|
||||
// In the current implementation, in addition to the exclusion conditions of omitempty,
|
||||
// if a type implements IsZero, that implementation will be used.
|
||||
// Furthermore, for non-pointer structs, if all fields are eligible for exclusion,
|
||||
// the struct itself will also be excluded. These behaviors are originally the functionality of omitzero.
|
||||
func (e *Encoder) isOmittedByOmitEmptyTag(v reflect.Value) bool {
|
||||
kind := v.Kind()
|
||||
if z, ok := v.Interface().(IsZeroer); ok {
|
||||
if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
|
||||
@@ -681,9 +805,7 @@ func (e *Encoder) isZeroValue(v reflect.Value) bool {
|
||||
return len(v.String()) == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
case reflect.Slice:
|
||||
return v.Len() == 0
|
||||
case reflect.Map:
|
||||
case reflect.Slice, reflect.Map:
|
||||
return v.Len() == 0
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
@@ -699,7 +821,7 @@ func (e *Encoder) isZeroValue(v reflect.Value) bool {
|
||||
if vt.Field(i).PkgPath != "" {
|
||||
continue // private field
|
||||
}
|
||||
if !e.isZeroValue(v.Field(i)) {
|
||||
if !e.isOmittedByOmitEmptyTag(v.Field(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -730,14 +852,14 @@ func (e *Encoder) encodeAnchor(anchorName string, value ast.Node, fieldValue ref
|
||||
anchorNode.Value = value
|
||||
if e.anchorCallback != nil {
|
||||
if err := e.anchorCallback(anchorNode, fieldValue.Interface()); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal anchor")
|
||||
return nil, err
|
||||
}
|
||||
if snode, ok := anchorNode.Name.(*ast.StringNode); ok {
|
||||
anchorName = snode.Value
|
||||
}
|
||||
}
|
||||
if fieldValue.Kind() == reflect.Ptr {
|
||||
e.anchorPtrToNameMap[fieldValue.Pointer()] = anchorName
|
||||
e.setAnchor(fieldValue.Pointer(), anchorName)
|
||||
}
|
||||
return anchorNode, nil
|
||||
}
|
||||
@@ -745,9 +867,9 @@ func (e *Encoder) encodeAnchor(anchorName string, value ast.Node, fieldValue ref
|
||||
func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column int) (ast.Node, error) {
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||
structType := value.Type()
|
||||
structFieldMap, err := structFieldMap(structType)
|
||||
fieldMap, err := structFieldMap(structType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get struct field map")
|
||||
return nil, err
|
||||
}
|
||||
hasInlineAnchorField := false
|
||||
var inlineAnchorValue reflect.Value
|
||||
@@ -757,119 +879,190 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
|
||||
continue
|
||||
}
|
||||
fieldValue := value.FieldByName(field.Name)
|
||||
structField := structFieldMap[field.Name]
|
||||
if structField.IsOmitEmpty && e.isZeroValue(fieldValue) {
|
||||
// omit encoding
|
||||
sf := fieldMap[field.Name]
|
||||
if (e.omitZero || sf.IsOmitZero) && e.isOmittedByOmitZero(fieldValue) {
|
||||
// omit encoding by omitzero tag or OmitZero option.
|
||||
continue
|
||||
}
|
||||
if e.omitEmpty && e.isOmittedByOmitEmptyOption(fieldValue) {
|
||||
// omit encoding by OmitEmpty option.
|
||||
continue
|
||||
}
|
||||
if sf.IsOmitEmpty && e.isOmittedByOmitEmptyTag(fieldValue) {
|
||||
// omit encoding by omitempty tag.
|
||||
continue
|
||||
}
|
||||
ve := e
|
||||
if !e.isFlowStyle && structField.IsFlow {
|
||||
if !e.isFlowStyle && sf.IsFlow {
|
||||
ve = &Encoder{}
|
||||
*ve = *e
|
||||
ve.isFlowStyle = true
|
||||
}
|
||||
value, err := ve.encodeValue(ctx, fieldValue, column)
|
||||
encoded, err := ve.encodeValue(ctx, fieldValue, column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode value")
|
||||
return nil, err
|
||||
}
|
||||
if e.isMapNode(value) {
|
||||
value.AddColumn(e.indent)
|
||||
if e.isMapNode(encoded) {
|
||||
encoded.AddColumn(e.indentNum)
|
||||
}
|
||||
var key ast.MapKeyNode = e.encodeString(structField.RenderName, column)
|
||||
var key ast.MapKeyNode = e.encodeString(sf.RenderName, column)
|
||||
switch {
|
||||
case structField.AnchorName != "":
|
||||
anchorNode, err := e.encodeAnchor(structField.AnchorName, value, fieldValue, column)
|
||||
case encoded.Type() == ast.AliasType:
|
||||
if aliasName := sf.AliasName; aliasName != "" {
|
||||
alias, ok := encoded.(*ast.AliasNode)
|
||||
if !ok {
|
||||
return nil, errors.ErrUnexpectedNodeType(encoded.Type(), ast.AliasType, encoded.GetToken())
|
||||
}
|
||||
got := alias.Value.String()
|
||||
if aliasName != got {
|
||||
return nil, fmt.Errorf("expected alias name is %q but got %q", aliasName, got)
|
||||
}
|
||||
}
|
||||
if sf.IsInline {
|
||||
// if both used alias and inline, output `<<: *alias`
|
||||
key = ast.MergeKey(token.New("<<", "<<", e.pos(column)))
|
||||
}
|
||||
case sf.AnchorName != "":
|
||||
anchorNode, err := e.encodeAnchor(sf.AnchorName, encoded, fieldValue, column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode anchor")
|
||||
return nil, err
|
||||
}
|
||||
value = anchorNode
|
||||
case structField.IsAutoAlias:
|
||||
if fieldValue.Kind() != reflect.Ptr {
|
||||
return nil, xerrors.Errorf(
|
||||
"%s in struct is not pointer type. but required automatically alias detection",
|
||||
structField.FieldName,
|
||||
)
|
||||
}
|
||||
anchorName := e.anchorPtrToNameMap[fieldValue.Pointer()]
|
||||
if anchorName == "" {
|
||||
return nil, xerrors.Errorf(
|
||||
"cannot find anchor name from pointer address for automatically alias detection",
|
||||
)
|
||||
}
|
||||
aliasName := anchorName
|
||||
alias := ast.Alias(token.New("*", "*", e.pos(column)))
|
||||
alias.Value = ast.String(token.New(aliasName, aliasName, e.pos(column)))
|
||||
value = alias
|
||||
if structField.IsInline {
|
||||
// if both used alias and inline, output `<<: *alias`
|
||||
key = ast.MergeKey(token.New("<<", "<<", e.pos(column)))
|
||||
}
|
||||
case structField.AliasName != "":
|
||||
aliasName := structField.AliasName
|
||||
alias := ast.Alias(token.New("*", "*", e.pos(column)))
|
||||
alias.Value = ast.String(token.New(aliasName, aliasName, e.pos(column)))
|
||||
value = alias
|
||||
if structField.IsInline {
|
||||
// if both used alias and inline, output `<<: *alias`
|
||||
key = ast.MergeKey(token.New("<<", "<<", e.pos(column)))
|
||||
}
|
||||
case structField.IsInline:
|
||||
isAutoAnchor := structField.IsAutoAnchor
|
||||
encoded = anchorNode
|
||||
case sf.IsInline:
|
||||
isAutoAnchor := sf.IsAutoAnchor
|
||||
if !hasInlineAnchorField {
|
||||
hasInlineAnchorField = isAutoAnchor
|
||||
}
|
||||
if isAutoAnchor {
|
||||
inlineAnchorValue = fieldValue
|
||||
}
|
||||
mapNode, ok := value.(ast.MapNode)
|
||||
mapNode, ok := encoded.(ast.MapNode)
|
||||
if !ok {
|
||||
// if an inline field is null, skip encoding it
|
||||
if _, ok := value.(*ast.NullNode); ok {
|
||||
if _, ok := encoded.(*ast.NullNode); ok {
|
||||
continue
|
||||
}
|
||||
return nil, xerrors.Errorf("inline value is must be map or struct type")
|
||||
return nil, errors.New("inline value is must be map or struct type")
|
||||
}
|
||||
mapIter := mapNode.MapRange()
|
||||
for mapIter.Next() {
|
||||
key := mapIter.Key()
|
||||
value := mapIter.Value()
|
||||
keyName := key.GetToken().Value
|
||||
if structFieldMap.isIncludedRenderName(keyName) {
|
||||
// if declared same key name, skip encoding this field
|
||||
mapKey := mapIter.Key()
|
||||
mapValue := mapIter.Value()
|
||||
keyName := mapKey.GetToken().Value
|
||||
if fieldMap.isIncludedRenderName(keyName) {
|
||||
// if declared the same key name, skip encoding this field
|
||||
continue
|
||||
}
|
||||
key.AddColumn(-e.indent)
|
||||
value.AddColumn(-e.indent)
|
||||
node.Values = append(node.Values, ast.MappingValue(nil, key, value))
|
||||
mapKey.AddColumn(-e.indentNum)
|
||||
mapValue.AddColumn(-e.indentNum)
|
||||
node.Values = append(node.Values, ast.MappingValue(nil, mapKey, mapValue))
|
||||
}
|
||||
continue
|
||||
case structField.IsAutoAnchor:
|
||||
anchorNode, err := e.encodeAnchor(structField.RenderName, value, fieldValue, column)
|
||||
case sf.IsAutoAnchor:
|
||||
anchorNode, err := e.encodeAnchor(sf.RenderName, encoded, fieldValue, column)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode anchor")
|
||||
return nil, err
|
||||
}
|
||||
value = anchorNode
|
||||
encoded = anchorNode
|
||||
}
|
||||
node.Values = append(node.Values, ast.MappingValue(nil, key, value))
|
||||
node.Values = append(node.Values, ast.MappingValue(nil, key, encoded))
|
||||
}
|
||||
if hasInlineAnchorField {
|
||||
node.AddColumn(e.indent)
|
||||
node.AddColumn(e.indentNum)
|
||||
anchorName := "anchor"
|
||||
anchorNode := ast.Anchor(token.New("&", "&", e.pos(column)))
|
||||
anchorNode.Name = ast.String(token.New(anchorName, anchorName, e.pos(column)))
|
||||
anchorNode.Value = node
|
||||
if e.anchorCallback != nil {
|
||||
if err := e.anchorCallback(anchorNode, value.Addr().Interface()); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal anchor")
|
||||
return nil, err
|
||||
}
|
||||
if snode, ok := anchorNode.Name.(*ast.StringNode); ok {
|
||||
anchorName = snode.Value
|
||||
}
|
||||
}
|
||||
if inlineAnchorValue.Kind() == reflect.Ptr {
|
||||
e.anchorPtrToNameMap[inlineAnchorValue.Pointer()] = anchorName
|
||||
e.setAnchor(inlineAnchorValue.Pointer(), anchorName)
|
||||
}
|
||||
return anchorNode, nil
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func (e *Encoder) toPointer(v reflect.Value) uintptr {
|
||||
if e.isInvalidValue(v) {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Ptr:
|
||||
return v.Pointer()
|
||||
case reflect.Interface:
|
||||
return e.toPointer(v.Elem())
|
||||
case reflect.Slice:
|
||||
return v.Pointer()
|
||||
case reflect.Map:
|
||||
return v.Pointer()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Encoder) clearSmartAnchorRef() {
|
||||
if !e.enableSmartAnchor {
|
||||
return
|
||||
}
|
||||
e.anchorRefToName = make(map[uintptr]string)
|
||||
e.anchorNameMap = make(map[string]struct{})
|
||||
}
|
||||
|
||||
func (e *Encoder) setSmartAnchor(ptr uintptr, name string) {
|
||||
if !e.enableSmartAnchor {
|
||||
return
|
||||
}
|
||||
e.setAnchor(ptr, e.generateAnchorName(name))
|
||||
}
|
||||
|
||||
func (e *Encoder) setAnchor(ptr uintptr, name string) {
|
||||
if ptr == 0 {
|
||||
return
|
||||
}
|
||||
if name == "" {
|
||||
return
|
||||
}
|
||||
e.anchorRefToName[ptr] = name
|
||||
e.anchorNameMap[name] = struct{}{}
|
||||
}
|
||||
|
||||
func (e *Encoder) generateAnchorName(base string) string {
|
||||
if _, exists := e.anchorNameMap[base]; !exists {
|
||||
return base
|
||||
}
|
||||
for i := 1; i < 100; i++ {
|
||||
name := base + strconv.Itoa(i)
|
||||
if _, exists := e.anchorNameMap[name]; exists {
|
||||
continue
|
||||
}
|
||||
return name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *Encoder) getAnchor(ref uintptr) (string, bool) {
|
||||
anchorName, exists := e.anchorRefToName[ref]
|
||||
return anchorName, exists
|
||||
}
|
||||
|
||||
func (e *Encoder) setSmartAlias(name string, ref uintptr) {
|
||||
if !e.enableSmartAnchor {
|
||||
return
|
||||
}
|
||||
e.aliasRefToName[ref] = name
|
||||
}
|
||||
|
||||
func (e *Encoder) getSmartAlias(ref uintptr) (string, bool) {
|
||||
if !e.enableSmartAnchor {
|
||||
return "", false
|
||||
}
|
||||
aliasName, exists := e.aliasRefToName[ref]
|
||||
return aliasName, exists
|
||||
}
|
||||
|
||||
49
vendor/github.com/goccy/go-yaml/error.go
generated
vendored
49
vendor/github.com/goccy/go-yaml/error.go
generated
vendored
@@ -1,62 +1,77 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"golang.org/x/xerrors"
|
||||
"github.com/goccy/go-yaml/internal/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidQuery = xerrors.New("invalid query")
|
||||
ErrInvalidPath = xerrors.New("invalid path instance")
|
||||
ErrInvalidPathString = xerrors.New("invalid path string")
|
||||
ErrNotFoundNode = xerrors.New("node not found")
|
||||
ErrUnknownCommentPositionType = xerrors.New("unknown comment position type")
|
||||
ErrInvalidCommentMapValue = xerrors.New("invalid comment map value. it must be not nil value")
|
||||
ErrInvalidQuery = errors.New("invalid query")
|
||||
ErrInvalidPath = errors.New("invalid path instance")
|
||||
ErrInvalidPathString = errors.New("invalid path string")
|
||||
ErrNotFoundNode = errors.New("node not found")
|
||||
ErrUnknownCommentPositionType = errors.New("unknown comment position type")
|
||||
ErrInvalidCommentMapValue = errors.New("invalid comment map value. it must be not nil value")
|
||||
ErrDecodeRequiredPointerType = errors.New("required pointer type value")
|
||||
ErrExceededMaxDepth = errors.New("exceeded max depth")
|
||||
FormatErrorWithToken = errors.FormatError
|
||||
)
|
||||
|
||||
type (
|
||||
SyntaxError = errors.SyntaxError
|
||||
TypeError = errors.TypeError
|
||||
OverflowError = errors.OverflowError
|
||||
DuplicateKeyError = errors.DuplicateKeyError
|
||||
UnknownFieldError = errors.UnknownFieldError
|
||||
UnexpectedNodeTypeError = errors.UnexpectedNodeTypeError
|
||||
Error = errors.Error
|
||||
)
|
||||
|
||||
func ErrUnsupportedHeadPositionType(node ast.Node) error {
|
||||
return xerrors.Errorf("unsupported comment head position for %s", node.Type())
|
||||
return fmt.Errorf("unsupported comment head position for %s", node.Type())
|
||||
}
|
||||
|
||||
func ErrUnsupportedLinePositionType(node ast.Node) error {
|
||||
return xerrors.Errorf("unsupported comment line position for %s", node.Type())
|
||||
return fmt.Errorf("unsupported comment line position for %s", node.Type())
|
||||
}
|
||||
|
||||
func ErrUnsupportedFootPositionType(node ast.Node) error {
|
||||
return xerrors.Errorf("unsupported comment foot position for %s", node.Type())
|
||||
return fmt.Errorf("unsupported comment foot position for %s", node.Type())
|
||||
}
|
||||
|
||||
// IsInvalidQueryError whether err is ErrInvalidQuery or not.
|
||||
func IsInvalidQueryError(err error) bool {
|
||||
return xerrors.Is(err, ErrInvalidQuery)
|
||||
return errors.Is(err, ErrInvalidQuery)
|
||||
}
|
||||
|
||||
// IsInvalidPathError whether err is ErrInvalidPath or not.
|
||||
func IsInvalidPathError(err error) bool {
|
||||
return xerrors.Is(err, ErrInvalidPath)
|
||||
return errors.Is(err, ErrInvalidPath)
|
||||
}
|
||||
|
||||
// IsInvalidPathStringError whether err is ErrInvalidPathString or not.
|
||||
func IsInvalidPathStringError(err error) bool {
|
||||
return xerrors.Is(err, ErrInvalidPathString)
|
||||
return errors.Is(err, ErrInvalidPathString)
|
||||
}
|
||||
|
||||
// IsNotFoundNodeError whether err is ErrNotFoundNode or not.
|
||||
func IsNotFoundNodeError(err error) bool {
|
||||
return xerrors.Is(err, ErrNotFoundNode)
|
||||
return errors.Is(err, ErrNotFoundNode)
|
||||
}
|
||||
|
||||
// IsInvalidTokenTypeError whether err is ast.ErrInvalidTokenType or not.
|
||||
func IsInvalidTokenTypeError(err error) bool {
|
||||
return xerrors.Is(err, ast.ErrInvalidTokenType)
|
||||
return errors.Is(err, ast.ErrInvalidTokenType)
|
||||
}
|
||||
|
||||
// IsInvalidAnchorNameError whether err is ast.ErrInvalidAnchorName or not.
|
||||
func IsInvalidAnchorNameError(err error) bool {
|
||||
return xerrors.Is(err, ast.ErrInvalidAnchorName)
|
||||
return errors.Is(err, ast.ErrInvalidAnchorName)
|
||||
}
|
||||
|
||||
// IsInvalidAliasNameError whether err is ast.ErrInvalidAliasName or not.
|
||||
func IsInvalidAliasNameError(err error) bool {
|
||||
return xerrors.Is(err, ast.ErrInvalidAliasName)
|
||||
return errors.Is(err, ast.ErrInvalidAliasName)
|
||||
}
|
||||
|
||||
430
vendor/github.com/goccy/go-yaml/internal/errors/error.go
generated
vendored
430
vendor/github.com/goccy/go-yaml/internal/errors/error.go
generated
vendored
@@ -1,225 +1,45 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"github.com/goccy/go-yaml/printer"
|
||||
"github.com/goccy/go-yaml/token"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultColorize = false
|
||||
defaultIncludeSource = true
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDecodeRequiredPointerType = xerrors.New("required pointer type value")
|
||||
As = errors.As
|
||||
Is = errors.Is
|
||||
New = errors.New
|
||||
)
|
||||
|
||||
// Wrapf wrap error for stack trace
|
||||
func Wrapf(err error, msg string, args ...interface{}) error {
|
||||
return &wrapError{
|
||||
baseError: &baseError{},
|
||||
err: xerrors.Errorf(msg, args...),
|
||||
nextErr: err,
|
||||
frame: xerrors.Caller(1),
|
||||
}
|
||||
const (
|
||||
defaultFormatColor = false
|
||||
defaultIncludeSource = true
|
||||
)
|
||||
|
||||
type Error interface {
|
||||
error
|
||||
GetToken() *token.Token
|
||||
GetMessage() string
|
||||
FormatError(bool, bool) string
|
||||
}
|
||||
|
||||
// ErrSyntax create syntax error instance with message and token
|
||||
func ErrSyntax(msg string, tk *token.Token) *syntaxError {
|
||||
return &syntaxError{
|
||||
baseError: &baseError{},
|
||||
msg: msg,
|
||||
token: tk,
|
||||
frame: xerrors.Caller(1),
|
||||
}
|
||||
}
|
||||
var (
|
||||
_ Error = new(SyntaxError)
|
||||
_ Error = new(TypeError)
|
||||
_ Error = new(OverflowError)
|
||||
_ Error = new(DuplicateKeyError)
|
||||
_ Error = new(UnknownFieldError)
|
||||
_ Error = new(UnexpectedNodeTypeError)
|
||||
)
|
||||
|
||||
type baseError struct {
|
||||
state fmt.State
|
||||
verb rune
|
||||
}
|
||||
|
||||
func (e *baseError) Error() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *baseError) chainStateAndVerb(err error) {
|
||||
wrapErr, ok := err.(*wrapError)
|
||||
if ok {
|
||||
wrapErr.state = e.state
|
||||
wrapErr.verb = e.verb
|
||||
}
|
||||
syntaxErr, ok := err.(*syntaxError)
|
||||
if ok {
|
||||
syntaxErr.state = e.state
|
||||
syntaxErr.verb = e.verb
|
||||
}
|
||||
}
|
||||
|
||||
type wrapError struct {
|
||||
*baseError
|
||||
err error
|
||||
nextErr error
|
||||
frame xerrors.Frame
|
||||
}
|
||||
|
||||
type FormatErrorPrinter struct {
|
||||
xerrors.Printer
|
||||
Colored bool
|
||||
InclSource bool
|
||||
}
|
||||
|
||||
func (e *wrapError) As(target interface{}) bool {
|
||||
err := e.nextErr
|
||||
for {
|
||||
if wrapErr, ok := err.(*wrapError); ok {
|
||||
err = wrapErr.nextErr
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return xerrors.As(err, target)
|
||||
}
|
||||
|
||||
func (e *wrapError) Unwrap() error {
|
||||
return e.nextErr
|
||||
}
|
||||
|
||||
func (e *wrapError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
|
||||
return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
|
||||
}
|
||||
|
||||
func (e *wrapError) FormatError(p xerrors.Printer) error {
|
||||
if _, ok := p.(*FormatErrorPrinter); !ok {
|
||||
p = &FormatErrorPrinter{
|
||||
Printer: p,
|
||||
Colored: defaultColorize,
|
||||
InclSource: defaultIncludeSource,
|
||||
}
|
||||
}
|
||||
if e.verb == 'v' && e.state.Flag('+') {
|
||||
// print stack trace for debugging
|
||||
p.Print(e.err, "\n")
|
||||
e.frame.Format(p)
|
||||
e.chainStateAndVerb(e.nextErr)
|
||||
return e.nextErr
|
||||
}
|
||||
err := e.nextErr
|
||||
for {
|
||||
if wrapErr, ok := err.(*wrapError); ok {
|
||||
err = wrapErr.nextErr
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
e.chainStateAndVerb(err)
|
||||
if fmtErr, ok := err.(xerrors.Formatter); ok {
|
||||
fmtErr.FormatError(p)
|
||||
} else {
|
||||
p.Print(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type wrapState struct {
|
||||
org fmt.State
|
||||
}
|
||||
|
||||
func (s *wrapState) Write(b []byte) (n int, err error) {
|
||||
return s.org.Write(b)
|
||||
}
|
||||
|
||||
func (s *wrapState) Width() (wid int, ok bool) {
|
||||
return s.org.Width()
|
||||
}
|
||||
|
||||
func (s *wrapState) Precision() (prec int, ok bool) {
|
||||
return s.org.Precision()
|
||||
}
|
||||
|
||||
func (s *wrapState) Flag(c int) bool {
|
||||
// set true to 'printDetail' forced because when p.Detail() is false, xerrors.Printer no output any text
|
||||
if c == '#' {
|
||||
// ignore '#' keyword because xerrors.FormatError doesn't set true to printDetail.
|
||||
// ( see https://github.com/golang/xerrors/blob/master/adaptor.go#L39-L43 )
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *wrapError) Format(state fmt.State, verb rune) {
|
||||
e.state = state
|
||||
e.verb = verb
|
||||
xerrors.FormatError(e, &wrapState{org: state}, verb)
|
||||
}
|
||||
|
||||
func (e *wrapError) Error() string {
|
||||
var buf bytes.Buffer
|
||||
e.PrettyPrint(&Sink{&buf}, defaultColorize, defaultIncludeSource)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type syntaxError struct {
|
||||
*baseError
|
||||
msg string
|
||||
token *token.Token
|
||||
frame xerrors.Frame
|
||||
}
|
||||
|
||||
func (e *syntaxError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
|
||||
return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
|
||||
}
|
||||
|
||||
func (e *syntaxError) FormatError(p xerrors.Printer) error {
|
||||
var pp printer.Printer
|
||||
|
||||
var colored, inclSource bool
|
||||
if fep, ok := p.(*FormatErrorPrinter); ok {
|
||||
colored = fep.Colored
|
||||
inclSource = fep.InclSource
|
||||
}
|
||||
|
||||
pos := fmt.Sprintf("[%d:%d] ", e.token.Position.Line, e.token.Position.Column)
|
||||
msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, e.msg), colored)
|
||||
if inclSource {
|
||||
msg += "\n" + pp.PrintErrorToken(e.token, colored)
|
||||
}
|
||||
p.Print(msg)
|
||||
|
||||
if e.verb == 'v' && e.state.Flag('+') {
|
||||
// %+v
|
||||
// print stack trace for debugging
|
||||
e.frame.Format(p)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PrettyPrinter interface {
|
||||
PrettyPrint(xerrors.Printer, bool, bool) error
|
||||
}
|
||||
type Sink struct{ *bytes.Buffer }
|
||||
|
||||
func (es *Sink) Print(args ...interface{}) {
|
||||
fmt.Fprint(es.Buffer, args...)
|
||||
}
|
||||
|
||||
func (es *Sink) Printf(f string, args ...interface{}) {
|
||||
fmt.Fprintf(es.Buffer, f, args...)
|
||||
}
|
||||
|
||||
func (es *Sink) Detail() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *syntaxError) Error() string {
|
||||
var buf bytes.Buffer
|
||||
e.PrettyPrint(&Sink{&buf}, defaultColorize, defaultIncludeSource)
|
||||
return buf.String()
|
||||
type SyntaxError struct {
|
||||
Message string
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
type TypeError struct {
|
||||
@@ -229,32 +49,198 @@ type TypeError struct {
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
func (e *TypeError) Error() string {
|
||||
type OverflowError struct {
|
||||
DstType reflect.Type
|
||||
SrcNum string
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
type DuplicateKeyError struct {
|
||||
Message string
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
type UnknownFieldError struct {
|
||||
Message string
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
type UnexpectedNodeTypeError struct {
|
||||
Actual ast.NodeType
|
||||
Expected ast.NodeType
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
// ErrSyntax create syntax error instance with message and token
|
||||
func ErrSyntax(msg string, tk *token.Token) *SyntaxError {
|
||||
return &SyntaxError{
|
||||
Message: msg,
|
||||
Token: tk,
|
||||
}
|
||||
}
|
||||
|
||||
// ErrOverflow creates an overflow error instance with message and a token.
|
||||
func ErrOverflow(dstType reflect.Type, num string, tk *token.Token) *OverflowError {
|
||||
return &OverflowError{
|
||||
DstType: dstType,
|
||||
SrcNum: num,
|
||||
Token: tk,
|
||||
}
|
||||
}
|
||||
|
||||
// ErrTypeMismatch cerates an type mismatch error instance with token.
|
||||
func ErrTypeMismatch(dstType, srcType reflect.Type, token *token.Token) *TypeError {
|
||||
return &TypeError{
|
||||
DstType: dstType,
|
||||
SrcType: srcType,
|
||||
Token: token,
|
||||
}
|
||||
}
|
||||
|
||||
// ErrDuplicateKey creates an duplicate key error instance with token.
|
||||
func ErrDuplicateKey(msg string, tk *token.Token) *DuplicateKeyError {
|
||||
return &DuplicateKeyError{
|
||||
Message: msg,
|
||||
Token: tk,
|
||||
}
|
||||
}
|
||||
|
||||
// ErrUnknownField creates an unknown field error instance with token.
|
||||
func ErrUnknownField(msg string, tk *token.Token) *UnknownFieldError {
|
||||
return &UnknownFieldError{
|
||||
Message: msg,
|
||||
Token: tk,
|
||||
}
|
||||
}
|
||||
|
||||
func ErrUnexpectedNodeType(actual, expected ast.NodeType, tk *token.Token) *UnexpectedNodeTypeError {
|
||||
return &UnexpectedNodeTypeError{
|
||||
Actual: actual,
|
||||
Expected: expected,
|
||||
Token: tk,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *SyntaxError) GetMessage() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
func (e *SyntaxError) GetToken() *token.Token {
|
||||
return e.Token
|
||||
}
|
||||
|
||||
func (e *SyntaxError) Error() string {
|
||||
return e.FormatError(defaultFormatColor, defaultIncludeSource)
|
||||
}
|
||||
|
||||
func (e *SyntaxError) FormatError(colored, inclSource bool) string {
|
||||
return FormatError(e.Message, e.Token, colored, inclSource)
|
||||
}
|
||||
|
||||
func (e *OverflowError) GetMessage() string {
|
||||
return e.msg()
|
||||
}
|
||||
|
||||
func (e *OverflowError) GetToken() *token.Token {
|
||||
return e.Token
|
||||
}
|
||||
|
||||
func (e *OverflowError) Error() string {
|
||||
return e.FormatError(defaultFormatColor, defaultIncludeSource)
|
||||
}
|
||||
|
||||
func (e *OverflowError) FormatError(colored, inclSource bool) string {
|
||||
return FormatError(e.msg(), e.Token, colored, inclSource)
|
||||
}
|
||||
|
||||
func (e *OverflowError) msg() string {
|
||||
return fmt.Sprintf("cannot unmarshal %s into Go value of type %s ( overflow )", e.SrcNum, e.DstType)
|
||||
}
|
||||
|
||||
func (e *TypeError) msg() string {
|
||||
if e.StructFieldName != nil {
|
||||
return fmt.Sprintf("cannot unmarshal %s into Go struct field %s of type %s", e.SrcType, *e.StructFieldName, e.DstType)
|
||||
}
|
||||
return fmt.Sprintf("cannot unmarshal %s into Go value of type %s", e.SrcType, e.DstType)
|
||||
}
|
||||
|
||||
func (e *TypeError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
|
||||
return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
|
||||
func (e *TypeError) GetMessage() string {
|
||||
return e.msg()
|
||||
}
|
||||
|
||||
func (e *TypeError) FormatError(p xerrors.Printer) error {
|
||||
func (e *TypeError) GetToken() *token.Token {
|
||||
return e.Token
|
||||
}
|
||||
|
||||
func (e *TypeError) Error() string {
|
||||
return e.FormatError(defaultFormatColor, defaultIncludeSource)
|
||||
}
|
||||
|
||||
func (e *TypeError) FormatError(colored, inclSource bool) string {
|
||||
return FormatError(e.msg(), e.Token, colored, inclSource)
|
||||
}
|
||||
|
||||
func (e *DuplicateKeyError) GetMessage() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
func (e *DuplicateKeyError) GetToken() *token.Token {
|
||||
return e.Token
|
||||
}
|
||||
|
||||
func (e *DuplicateKeyError) Error() string {
|
||||
return e.FormatError(defaultFormatColor, defaultIncludeSource)
|
||||
}
|
||||
|
||||
func (e *DuplicateKeyError) FormatError(colored, inclSource bool) string {
|
||||
return FormatError(e.Message, e.Token, colored, inclSource)
|
||||
}
|
||||
|
||||
func (e *UnknownFieldError) GetMessage() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
func (e *UnknownFieldError) GetToken() *token.Token {
|
||||
return e.Token
|
||||
}
|
||||
|
||||
func (e *UnknownFieldError) Error() string {
|
||||
return e.FormatError(defaultFormatColor, defaultIncludeSource)
|
||||
}
|
||||
|
||||
func (e *UnknownFieldError) FormatError(colored, inclSource bool) string {
|
||||
return FormatError(e.Message, e.Token, colored, inclSource)
|
||||
}
|
||||
|
||||
func (e *UnexpectedNodeTypeError) GetMessage() string {
|
||||
return e.msg()
|
||||
}
|
||||
|
||||
func (e *UnexpectedNodeTypeError) GetToken() *token.Token {
|
||||
return e.Token
|
||||
}
|
||||
|
||||
func (e *UnexpectedNodeTypeError) Error() string {
|
||||
return e.FormatError(defaultFormatColor, defaultIncludeSource)
|
||||
}
|
||||
|
||||
func (e *UnexpectedNodeTypeError) FormatError(colored, inclSource bool) string {
|
||||
return FormatError(e.msg(), e.Token, colored, inclSource)
|
||||
}
|
||||
|
||||
func (e *UnexpectedNodeTypeError) msg() string {
|
||||
return fmt.Sprintf("%s was used where %s is expected", e.Actual.YAMLName(), e.Expected.YAMLName())
|
||||
}
|
||||
|
||||
func FormatError(errMsg string, token *token.Token, colored, inclSource bool) string {
|
||||
var pp printer.Printer
|
||||
|
||||
var colored, inclSource bool
|
||||
if fep, ok := p.(*FormatErrorPrinter); ok {
|
||||
colored = fep.Colored
|
||||
inclSource = fep.InclSource
|
||||
if token == nil {
|
||||
return pp.PrintErrorMessage(errMsg, colored)
|
||||
}
|
||||
|
||||
pos := fmt.Sprintf("[%d:%d] ", e.Token.Position.Line, e.Token.Position.Column)
|
||||
msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, e.Error()), colored)
|
||||
pos := fmt.Sprintf("[%d:%d] ", token.Position.Line, token.Position.Column)
|
||||
msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, errMsg), colored)
|
||||
if inclSource {
|
||||
msg += "\n" + pp.PrintErrorToken(e.Token, colored)
|
||||
msg += "\n" + pp.PrintErrorToken(token, colored)
|
||||
}
|
||||
p.Print(msg)
|
||||
|
||||
return nil
|
||||
return msg
|
||||
}
|
||||
|
||||
539
vendor/github.com/goccy/go-yaml/internal/format/format.go
generated
vendored
Normal file
539
vendor/github.com/goccy/go-yaml/internal/format/format.go
generated
vendored
Normal file
@@ -0,0 +1,539 @@
|
||||
package format
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"github.com/goccy/go-yaml/token"
|
||||
)
|
||||
|
||||
func FormatNodeWithResolvedAlias(n ast.Node, anchorNodeMap map[string]ast.Node) string {
|
||||
tk := getFirstToken(n)
|
||||
if tk == nil {
|
||||
return ""
|
||||
}
|
||||
formatter := newFormatter(tk, hasComment(n))
|
||||
formatter.anchorNodeMap = anchorNodeMap
|
||||
return formatter.format(n)
|
||||
}
|
||||
|
||||
func FormatNode(n ast.Node) string {
|
||||
tk := getFirstToken(n)
|
||||
if tk == nil {
|
||||
return ""
|
||||
}
|
||||
return newFormatter(tk, hasComment(n)).format(n)
|
||||
}
|
||||
|
||||
func FormatFile(file *ast.File) string {
|
||||
if len(file.Docs) == 0 {
|
||||
return ""
|
||||
}
|
||||
tk := getFirstToken(file.Docs[0])
|
||||
if tk == nil {
|
||||
return ""
|
||||
}
|
||||
return newFormatter(tk, hasCommentFile(file)).formatFile(file)
|
||||
}
|
||||
|
||||
func hasCommentFile(f *ast.File) bool {
|
||||
for _, doc := range f.Docs {
|
||||
if hasComment(doc.Body) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasComment(n ast.Node) bool {
|
||||
if n == nil {
|
||||
return false
|
||||
}
|
||||
switch nn := n.(type) {
|
||||
case *ast.DocumentNode:
|
||||
return hasComment(nn.Body)
|
||||
case *ast.NullNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.BoolNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.IntegerNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.FloatNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.StringNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.InfinityNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.NanNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.LiteralNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.DirectiveNode:
|
||||
if nn.Comment != nil {
|
||||
return true
|
||||
}
|
||||
for _, value := range nn.Values {
|
||||
if hasComment(value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case *ast.TagNode:
|
||||
if nn.Comment != nil {
|
||||
return true
|
||||
}
|
||||
return hasComment(nn.Value)
|
||||
case *ast.MappingNode:
|
||||
if nn.Comment != nil || nn.FootComment != nil {
|
||||
return true
|
||||
}
|
||||
for _, value := range nn.Values {
|
||||
if value.Comment != nil || value.FootComment != nil {
|
||||
return true
|
||||
}
|
||||
if hasComment(value.Key) {
|
||||
return true
|
||||
}
|
||||
if hasComment(value.Value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case *ast.MappingKeyNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.MergeKeyNode:
|
||||
return nn.Comment != nil
|
||||
case *ast.SequenceNode:
|
||||
if nn.Comment != nil || nn.FootComment != nil {
|
||||
return true
|
||||
}
|
||||
for _, entry := range nn.Entries {
|
||||
if entry.Comment != nil || entry.HeadComment != nil || entry.LineComment != nil {
|
||||
return true
|
||||
}
|
||||
if hasComment(entry.Value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case *ast.AnchorNode:
|
||||
if nn.Comment != nil {
|
||||
return true
|
||||
}
|
||||
if hasComment(nn.Name) || hasComment(nn.Value) {
|
||||
return true
|
||||
}
|
||||
case *ast.AliasNode:
|
||||
if nn.Comment != nil {
|
||||
return true
|
||||
}
|
||||
if hasComment(nn.Value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getFirstToken(n ast.Node) *token.Token {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
switch nn := n.(type) {
|
||||
case *ast.DocumentNode:
|
||||
if nn.Start != nil {
|
||||
return nn.Start
|
||||
}
|
||||
return getFirstToken(nn.Body)
|
||||
case *ast.NullNode:
|
||||
return nn.Token
|
||||
case *ast.BoolNode:
|
||||
return nn.Token
|
||||
case *ast.IntegerNode:
|
||||
return nn.Token
|
||||
case *ast.FloatNode:
|
||||
return nn.Token
|
||||
case *ast.StringNode:
|
||||
return nn.Token
|
||||
case *ast.InfinityNode:
|
||||
return nn.Token
|
||||
case *ast.NanNode:
|
||||
return nn.Token
|
||||
case *ast.LiteralNode:
|
||||
return nn.Start
|
||||
case *ast.DirectiveNode:
|
||||
return nn.Start
|
||||
case *ast.TagNode:
|
||||
return nn.Start
|
||||
case *ast.MappingNode:
|
||||
if nn.IsFlowStyle {
|
||||
return nn.Start
|
||||
}
|
||||
if len(nn.Values) == 0 {
|
||||
return nn.Start
|
||||
}
|
||||
return getFirstToken(nn.Values[0].Key)
|
||||
case *ast.MappingKeyNode:
|
||||
return nn.Start
|
||||
case *ast.MergeKeyNode:
|
||||
return nn.Token
|
||||
case *ast.SequenceNode:
|
||||
return nn.Start
|
||||
case *ast.AnchorNode:
|
||||
return nn.Start
|
||||
case *ast.AliasNode:
|
||||
return nn.Start
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Formatter struct {
|
||||
existsComment bool
|
||||
tokenToOriginMap map[*token.Token]string
|
||||
anchorNodeMap map[string]ast.Node
|
||||
}
|
||||
|
||||
func newFormatter(tk *token.Token, existsComment bool) *Formatter {
|
||||
tokenToOriginMap := make(map[*token.Token]string)
|
||||
for tk.Prev != nil {
|
||||
tk = tk.Prev
|
||||
}
|
||||
tokenToOriginMap[tk] = tk.Origin
|
||||
|
||||
var origin string
|
||||
for tk.Next != nil {
|
||||
tk = tk.Next
|
||||
if tk.Type == token.CommentType {
|
||||
origin += strings.Repeat("\n", strings.Count(normalizeNewLineChars(tk.Origin), "\n"))
|
||||
continue
|
||||
}
|
||||
origin += tk.Origin
|
||||
tokenToOriginMap[tk] = origin
|
||||
origin = ""
|
||||
}
|
||||
return &Formatter{
|
||||
existsComment: existsComment,
|
||||
tokenToOriginMap: tokenToOriginMap,
|
||||
}
|
||||
}
|
||||
|
||||
func getIndentNumByFirstLineToken(tk *token.Token) int {
|
||||
defaultIndent := tk.Position.Column - 1
|
||||
|
||||
// key: value
|
||||
// ^
|
||||
// next
|
||||
if tk.Type == token.SequenceEntryType {
|
||||
// If the current token is the sequence entry.
|
||||
// the indent is calculated from the column value of the current token.
|
||||
return defaultIndent
|
||||
}
|
||||
|
||||
// key: value
|
||||
// ^
|
||||
// next
|
||||
if tk.Next != nil && tk.Next.Type == token.MappingValueType {
|
||||
// If the current token is the key in the mapping-value,
|
||||
// the indent is calculated from the column value of the current token.
|
||||
return defaultIndent
|
||||
}
|
||||
|
||||
if tk.Prev == nil {
|
||||
return defaultIndent
|
||||
}
|
||||
prev := tk.Prev
|
||||
|
||||
// key: value
|
||||
// ^
|
||||
// prev
|
||||
if prev.Type == token.MappingValueType {
|
||||
// If the current token is the value in the mapping-value,
|
||||
// the indent is calculated from the column value of the key two steps back.
|
||||
if prev.Prev == nil {
|
||||
return defaultIndent
|
||||
}
|
||||
return prev.Prev.Position.Column - 1
|
||||
}
|
||||
|
||||
// - value
|
||||
// ^
|
||||
// prev
|
||||
if prev.Type == token.SequenceEntryType {
|
||||
// If the value is not a mapping-value and the previous token was a sequence entry,
|
||||
// the indent is calculated using the column value of the sequence entry token.
|
||||
return prev.Position.Column - 1
|
||||
}
|
||||
|
||||
return defaultIndent
|
||||
}
|
||||
|
||||
func (f *Formatter) format(n ast.Node) string {
|
||||
return f.trimSpacePrefix(
|
||||
f.trimIndentSpace(
|
||||
getIndentNumByFirstLineToken(getFirstToken(n)),
|
||||
f.trimNewLineCharPrefix(f.formatNode(n)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatFile(file *ast.File) string {
|
||||
if len(file.Docs) == 0 {
|
||||
return ""
|
||||
}
|
||||
var ret string
|
||||
for _, doc := range file.Docs {
|
||||
ret += f.formatDocument(doc)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Formatter) origin(tk *token.Token) string {
|
||||
if tk == nil {
|
||||
return ""
|
||||
}
|
||||
if f.existsComment {
|
||||
return tk.Origin
|
||||
}
|
||||
return f.tokenToOriginMap[tk]
|
||||
}
|
||||
|
||||
func (f *Formatter) formatDocument(n *ast.DocumentNode) string {
|
||||
return f.origin(n.Start) + f.formatNode(n.Body) + f.origin(n.End)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatNull(n *ast.NullNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatString(n *ast.StringNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatInteger(n *ast.IntegerNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatFloat(n *ast.FloatNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatBool(n *ast.BoolNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatInfinity(n *ast.InfinityNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatNan(n *ast.NanNode) string {
|
||||
return f.origin(n.Token) + f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatLiteral(n *ast.LiteralNode) string {
|
||||
return f.origin(n.Start) + f.formatCommentGroup(n.Comment) + f.origin(n.Value.Token)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatMergeKey(n *ast.MergeKeyNode) string {
|
||||
return f.origin(n.Token)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatMappingValue(n *ast.MappingValueNode) string {
|
||||
return f.formatCommentGroup(n.Comment) +
|
||||
f.origin(n.Key.GetToken()) + ":" + f.formatCommentGroup(n.Key.GetComment()) + f.formatNode(n.Value) +
|
||||
f.formatCommentGroup(n.FootComment)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatDirective(n *ast.DirectiveNode) string {
|
||||
ret := f.origin(n.Start) + f.formatNode(n.Name)
|
||||
for _, val := range n.Values {
|
||||
ret += f.formatNode(val)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Formatter) formatMapping(n *ast.MappingNode) string {
|
||||
var ret string
|
||||
if n.IsFlowStyle {
|
||||
ret = f.origin(n.Start)
|
||||
}
|
||||
ret += f.formatCommentGroup(n.Comment)
|
||||
for _, value := range n.Values {
|
||||
if value.CollectEntry != nil {
|
||||
ret += f.origin(value.CollectEntry)
|
||||
}
|
||||
ret += f.formatMappingValue(value)
|
||||
}
|
||||
if n.IsFlowStyle {
|
||||
ret += f.origin(n.End)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Formatter) formatTag(n *ast.TagNode) string {
|
||||
return f.origin(n.Start) + f.formatNode(n.Value)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatMappingKey(n *ast.MappingKeyNode) string {
|
||||
return f.origin(n.Start) + f.formatNode(n.Value)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatSequence(n *ast.SequenceNode) string {
|
||||
var ret string
|
||||
if n.IsFlowStyle {
|
||||
ret = f.origin(n.Start)
|
||||
}
|
||||
if n.Comment != nil {
|
||||
// add head comment.
|
||||
ret += f.formatCommentGroup(n.Comment)
|
||||
}
|
||||
for _, entry := range n.Entries {
|
||||
ret += f.formatNode(entry)
|
||||
}
|
||||
if n.IsFlowStyle {
|
||||
ret += f.origin(n.End)
|
||||
}
|
||||
ret += f.formatCommentGroup(n.FootComment)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Formatter) formatSequenceEntry(n *ast.SequenceEntryNode) string {
|
||||
return f.formatCommentGroup(n.HeadComment) + f.origin(n.Start) + f.formatCommentGroup(n.LineComment) + f.formatNode(n.Value)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatAnchor(n *ast.AnchorNode) string {
|
||||
return f.origin(n.Start) + f.formatNode(n.Name) + f.formatNode(n.Value)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatAlias(n *ast.AliasNode) string {
|
||||
if f.anchorNodeMap != nil {
|
||||
anchorName := n.Value.GetToken().Value
|
||||
node := f.anchorNodeMap[anchorName]
|
||||
if node != nil {
|
||||
formatted := f.formatNode(node)
|
||||
// If formatted text contains newline characters, indentation needs to be considered.
|
||||
if strings.Contains(formatted, "\n") {
|
||||
// If the first character is not a newline, the first line should be output without indentation.
|
||||
isIgnoredFirstLine := !strings.HasPrefix(formatted, "\n")
|
||||
formatted = f.addIndentSpace(n.GetToken().Position.IndentNum, formatted, isIgnoredFirstLine)
|
||||
}
|
||||
return formatted
|
||||
}
|
||||
}
|
||||
return f.origin(n.Start) + f.formatNode(n.Value)
|
||||
}
|
||||
|
||||
func (f *Formatter) formatNode(n ast.Node) string {
|
||||
switch nn := n.(type) {
|
||||
case *ast.DocumentNode:
|
||||
return f.formatDocument(nn)
|
||||
case *ast.NullNode:
|
||||
return f.formatNull(nn)
|
||||
case *ast.BoolNode:
|
||||
return f.formatBool(nn)
|
||||
case *ast.IntegerNode:
|
||||
return f.formatInteger(nn)
|
||||
case *ast.FloatNode:
|
||||
return f.formatFloat(nn)
|
||||
case *ast.StringNode:
|
||||
return f.formatString(nn)
|
||||
case *ast.InfinityNode:
|
||||
return f.formatInfinity(nn)
|
||||
case *ast.NanNode:
|
||||
return f.formatNan(nn)
|
||||
case *ast.LiteralNode:
|
||||
return f.formatLiteral(nn)
|
||||
case *ast.DirectiveNode:
|
||||
return f.formatDirective(nn)
|
||||
case *ast.TagNode:
|
||||
return f.formatTag(nn)
|
||||
case *ast.MappingNode:
|
||||
return f.formatMapping(nn)
|
||||
case *ast.MappingKeyNode:
|
||||
return f.formatMappingKey(nn)
|
||||
case *ast.MappingValueNode:
|
||||
return f.formatMappingValue(nn)
|
||||
case *ast.MergeKeyNode:
|
||||
return f.formatMergeKey(nn)
|
||||
case *ast.SequenceNode:
|
||||
return f.formatSequence(nn)
|
||||
case *ast.SequenceEntryNode:
|
||||
return f.formatSequenceEntry(nn)
|
||||
case *ast.AnchorNode:
|
||||
return f.formatAnchor(nn)
|
||||
case *ast.AliasNode:
|
||||
return f.formatAlias(nn)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *Formatter) formatCommentGroup(g *ast.CommentGroupNode) string {
|
||||
if g == nil {
|
||||
return ""
|
||||
}
|
||||
var ret string
|
||||
for _, cm := range g.Comments {
|
||||
ret += f.formatComment(cm)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Formatter) formatComment(n *ast.CommentNode) string {
|
||||
if n == nil {
|
||||
return ""
|
||||
}
|
||||
return n.Token.Origin
|
||||
}
|
||||
|
||||
// nolint: unused
|
||||
func (f *Formatter) formatIndent(col int) string {
|
||||
if col <= 1 {
|
||||
return ""
|
||||
}
|
||||
return strings.Repeat(" ", col-1)
|
||||
}
|
||||
|
||||
func (f *Formatter) trimNewLineCharPrefix(v string) string {
|
||||
return strings.TrimLeftFunc(v, func(r rune) bool {
|
||||
return r == '\n' || r == '\r'
|
||||
})
|
||||
}
|
||||
|
||||
func (f *Formatter) trimSpacePrefix(v string) string {
|
||||
return strings.TrimLeftFunc(v, func(r rune) bool {
|
||||
return r == ' '
|
||||
})
|
||||
}
|
||||
|
||||
func (f *Formatter) trimIndentSpace(trimIndentNum int, v string) string {
|
||||
if trimIndentNum == 0 {
|
||||
return v
|
||||
}
|
||||
lines := strings.Split(normalizeNewLineChars(v), "\n")
|
||||
out := make([]string, 0, len(lines))
|
||||
for _, line := range lines {
|
||||
var cnt int
|
||||
out = append(out, strings.TrimLeftFunc(line, func(r rune) bool {
|
||||
cnt++
|
||||
return r == ' ' && cnt <= trimIndentNum
|
||||
}))
|
||||
}
|
||||
return strings.Join(out, "\n")
|
||||
}
|
||||
|
||||
func (f *Formatter) addIndentSpace(indentNum int, v string, isIgnoredFirstLine bool) string {
|
||||
if indentNum == 0 {
|
||||
return v
|
||||
}
|
||||
indent := strings.Repeat(" ", indentNum)
|
||||
lines := strings.Split(normalizeNewLineChars(v), "\n")
|
||||
out := make([]string, 0, len(lines))
|
||||
for idx, line := range lines {
|
||||
if line == "" || (isIgnoredFirstLine && idx == 0) {
|
||||
out = append(out, line)
|
||||
continue
|
||||
}
|
||||
out = append(out, indent+line)
|
||||
}
|
||||
return strings.Join(out, "\n")
|
||||
}
|
||||
|
||||
// normalizeNewLineChars normalize CRLF and CR to LF.
|
||||
func normalizeNewLineChars(v string) string {
|
||||
return strings.ReplaceAll(strings.ReplaceAll(v, "\r\n", "\n"), "\r", "\n")
|
||||
}
|
||||
81
vendor/github.com/goccy/go-yaml/option.go
generated
vendored
81
vendor/github.com/goccy/go-yaml/option.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
@@ -50,11 +51,10 @@ func Validator(v StructValidator) DecodeOption {
|
||||
}
|
||||
}
|
||||
|
||||
// Strict enable DisallowUnknownField and DisallowDuplicateKey
|
||||
// Strict enable DisallowUnknownField
|
||||
func Strict() DecodeOption {
|
||||
return func(d *Decoder) error {
|
||||
d.disallowUnknownField = true
|
||||
d.disallowDuplicateKey = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -69,10 +69,10 @@ func DisallowUnknownField() DecodeOption {
|
||||
}
|
||||
}
|
||||
|
||||
// DisallowDuplicateKey causes an error when mapping keys that are duplicates
|
||||
func DisallowDuplicateKey() DecodeOption {
|
||||
// AllowDuplicateMapKey ignore syntax error when mapping keys that are duplicates.
|
||||
func AllowDuplicateMapKey() DecodeOption {
|
||||
return func(d *Decoder) error {
|
||||
d.disallowDuplicateKey = true
|
||||
d.allowDuplicateMapKey = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -102,20 +102,32 @@ func UseJSONUnmarshaler() DecodeOption {
|
||||
func CustomUnmarshaler[T any](unmarshaler func(*T, []byte) error) DecodeOption {
|
||||
return func(d *Decoder) error {
|
||||
var typ *T
|
||||
d.customUnmarshalerMap[reflect.TypeOf(typ)] = func(v interface{}, b []byte) error {
|
||||
d.customUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error {
|
||||
return unmarshaler(v.(*T), b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CustomUnmarshalerContext overrides any decoding process for the type specified in generics.
|
||||
// Similar to CustomUnmarshaler, but allows passing a context to the unmarshaler function.
|
||||
func CustomUnmarshalerContext[T any](unmarshaler func(context.Context, *T, []byte) error) DecodeOption {
|
||||
return func(d *Decoder) error {
|
||||
var typ *T
|
||||
d.customUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error {
|
||||
return unmarshaler(ctx, v.(*T), b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeOption functional option type for Encoder
|
||||
type EncodeOption func(e *Encoder) error
|
||||
|
||||
// Indent change indent number
|
||||
func Indent(spaces int) EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
e.indent = spaces
|
||||
e.indentNum = spaces
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -144,6 +156,18 @@ func Flow(isFlowStyle bool) EncodeOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithSmartAnchor when multiple map values share the same pointer,
|
||||
// an anchor is automatically assigned to the first occurrence, and aliases are used for subsequent elements.
|
||||
// The map key name is used as the anchor name by default.
|
||||
// If key names conflict, a suffix is automatically added to avoid collisions.
|
||||
// This is an experimental feature and cannot be used simultaneously with anchor tags.
|
||||
func WithSmartAnchor() EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
e.enableSmartAnchor = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// UseLiteralStyleIfMultiline causes encoding multiline strings with a literal syntax,
|
||||
// no matter what characters they include
|
||||
func UseLiteralStyleIfMultiline(useLiteralStyleIfMultiline bool) EncodeOption {
|
||||
@@ -188,13 +212,54 @@ func UseJSONMarshaler() EncodeOption {
|
||||
func CustomMarshaler[T any](marshaler func(T) ([]byte, error)) EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
var typ T
|
||||
e.customMarshalerMap[reflect.TypeOf(typ)] = func(v interface{}) ([]byte, error) {
|
||||
e.customMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) {
|
||||
return marshaler(v.(T))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CustomMarshalerContext overrides any encoding process for the type specified in generics.
|
||||
// Similar to CustomMarshaler, but allows passing a context to the marshaler function.
|
||||
func CustomMarshalerContext[T any](marshaler func(context.Context, T) ([]byte, error)) EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
var typ T
|
||||
e.customMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) {
|
||||
return marshaler(ctx, v.(T))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// AutoInt automatically converts floating-point numbers to integers when the fractional part is zero.
|
||||
// For example, a value of 1.0 will be encoded as 1.
|
||||
func AutoInt() EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
e.autoInt = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OmitEmpty behaves in the same way as the interpretation of the omitempty tag in the encoding/json library.
|
||||
// set on all the fields.
|
||||
// In the current implementation, the omitempty tag is not implemented in the same way as encoding/json,
|
||||
// so please specify this option if you expect the same behavior.
|
||||
func OmitEmpty() EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
e.omitEmpty = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OmitZero forces the encoder to assume an `omitzero` struct tag is
|
||||
// set on all the fields. See `Marshal` commentary for the `omitzero` tag logic.
|
||||
func OmitZero() EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
e.omitZero = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CommentPosition type of the position for comment.
|
||||
type CommentPosition int
|
||||
|
||||
|
||||
28
vendor/github.com/goccy/go-yaml/parser/color.go
generated
vendored
Normal file
28
vendor/github.com/goccy/go-yaml/parser/color.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package parser
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
colorFgHiBlack int = iota + 90
|
||||
colorFgHiRed
|
||||
colorFgHiGreen
|
||||
colorFgHiYellow
|
||||
colorFgHiBlue
|
||||
colorFgHiMagenta
|
||||
colorFgHiCyan
|
||||
)
|
||||
|
||||
var colorTable = []int{
|
||||
colorFgHiRed,
|
||||
colorFgHiGreen,
|
||||
colorFgHiYellow,
|
||||
colorFgHiBlue,
|
||||
colorFgHiMagenta,
|
||||
colorFgHiCyan,
|
||||
}
|
||||
|
||||
func colorize(idx int, content string) string {
|
||||
colorIdx := idx % len(colorTable)
|
||||
color := colorTable[colorIdx]
|
||||
return fmt.Sprintf("\x1b[1;%dm", color) + content + "\x1b[22;0m"
|
||||
}
|
||||
249
vendor/github.com/goccy/go-yaml/parser/context.go
generated
vendored
249
vendor/github.com/goccy/go-yaml/parser/context.go
generated
vendored
@@ -9,11 +9,15 @@ import (
|
||||
|
||||
// context context at parsing
|
||||
type context struct {
|
||||
parent *context
|
||||
idx int
|
||||
tokenRef *tokenRef
|
||||
path string
|
||||
isFlow bool
|
||||
}
|
||||
|
||||
type tokenRef struct {
|
||||
tokens []*Token
|
||||
size int
|
||||
tokens token.Tokens
|
||||
path string
|
||||
idx int
|
||||
}
|
||||
|
||||
var pathSpecialChars = []string{
|
||||
@@ -36,91 +40,28 @@ func normalizePath(path string) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func (c *context) withChild(path string) *context {
|
||||
ctx := c.copy()
|
||||
path = normalizePath(path)
|
||||
ctx.path += fmt.Sprintf(".%s", path)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (c *context) withIndex(idx uint) *context {
|
||||
ctx := c.copy()
|
||||
ctx.path += fmt.Sprintf("[%d]", idx)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (c *context) copy() *context {
|
||||
return &context{
|
||||
parent: c,
|
||||
idx: c.idx,
|
||||
size: c.size,
|
||||
tokens: append(token.Tokens{}, c.tokens...),
|
||||
path: c.path,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) next() bool {
|
||||
return c.idx < c.size
|
||||
}
|
||||
|
||||
func (c *context) previousToken() *token.Token {
|
||||
if c.idx > 0 {
|
||||
return c.tokens[c.idx-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) insertToken(idx int, tk *token.Token) {
|
||||
if c.parent != nil {
|
||||
c.parent.insertToken(idx, tk)
|
||||
}
|
||||
if c.size < idx {
|
||||
return
|
||||
}
|
||||
if c.size == idx {
|
||||
curToken := c.tokens[c.size-1]
|
||||
tk.Next = curToken
|
||||
curToken.Prev = tk
|
||||
|
||||
c.tokens = append(c.tokens, tk)
|
||||
c.size = len(c.tokens)
|
||||
return
|
||||
}
|
||||
|
||||
curToken := c.tokens[idx]
|
||||
tk.Next = curToken
|
||||
curToken.Prev = tk
|
||||
|
||||
c.tokens = append(c.tokens[:idx+1], c.tokens[idx:]...)
|
||||
c.tokens[idx] = tk
|
||||
c.size = len(c.tokens)
|
||||
}
|
||||
|
||||
func (c *context) currentToken() *token.Token {
|
||||
if c.idx >= c.size {
|
||||
func (c *context) currentToken() *Token {
|
||||
if c.tokenRef.idx >= c.tokenRef.size {
|
||||
return nil
|
||||
}
|
||||
return c.tokens[c.idx]
|
||||
return c.tokenRef.tokens[c.tokenRef.idx]
|
||||
}
|
||||
|
||||
func (c *context) nextToken() *token.Token {
|
||||
if c.idx+1 >= c.size {
|
||||
func (c *context) isComment() bool {
|
||||
return c.currentToken().Type() == token.CommentType
|
||||
}
|
||||
|
||||
func (c *context) nextToken() *Token {
|
||||
if c.tokenRef.idx+1 >= c.tokenRef.size {
|
||||
return nil
|
||||
}
|
||||
return c.tokens[c.idx+1]
|
||||
return c.tokenRef.tokens[c.tokenRef.idx+1]
|
||||
}
|
||||
|
||||
func (c *context) afterNextToken() *token.Token {
|
||||
if c.idx+2 >= c.size {
|
||||
return nil
|
||||
}
|
||||
return c.tokens[c.idx+2]
|
||||
}
|
||||
|
||||
func (c *context) nextNotCommentToken() *token.Token {
|
||||
for i := c.idx + 1; i < c.size; i++ {
|
||||
tk := c.tokens[i]
|
||||
if tk.Type == token.CommentType {
|
||||
func (c *context) nextNotCommentToken() *Token {
|
||||
for i := c.tokenRef.idx + 1; i < c.tokenRef.size; i++ {
|
||||
tk := c.tokenRef.tokens[i]
|
||||
if tk.Type() == token.CommentType {
|
||||
continue
|
||||
}
|
||||
return tk
|
||||
@@ -128,65 +69,119 @@ func (c *context) nextNotCommentToken() *token.Token {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) afterNextNotCommentToken() *token.Token {
|
||||
notCommentTokenCount := 0
|
||||
for i := c.idx + 1; i < c.size; i++ {
|
||||
tk := c.tokens[i]
|
||||
if tk.Type == token.CommentType {
|
||||
continue
|
||||
}
|
||||
notCommentTokenCount++
|
||||
if notCommentTokenCount == 2 {
|
||||
return tk
|
||||
}
|
||||
}
|
||||
return nil
|
||||
func (c *context) isTokenNotFound() bool {
|
||||
return c.currentToken() == nil
|
||||
}
|
||||
|
||||
func (c *context) isCurrentCommentToken() bool {
|
||||
tk := c.currentToken()
|
||||
if tk == nil {
|
||||
return false
|
||||
func (c *context) withGroup(g *TokenGroup) *context {
|
||||
ctx := *c
|
||||
ctx.tokenRef = &tokenRef{
|
||||
tokens: g.Tokens,
|
||||
size: len(g.Tokens),
|
||||
}
|
||||
return tk.Type == token.CommentType
|
||||
return &ctx
|
||||
}
|
||||
|
||||
func (c *context) progressIgnoreComment(num int) {
|
||||
if c.parent != nil {
|
||||
c.parent.progressIgnoreComment(num)
|
||||
func (c *context) withChild(path string) *context {
|
||||
ctx := *c
|
||||
ctx.path = c.path + "." + normalizePath(path)
|
||||
return &ctx
|
||||
}
|
||||
|
||||
func (c *context) withIndex(idx uint) *context {
|
||||
ctx := *c
|
||||
ctx.path = c.path + "[" + fmt.Sprint(idx) + "]"
|
||||
return &ctx
|
||||
}
|
||||
|
||||
func (c *context) withFlow(isFlow bool) *context {
|
||||
ctx := *c
|
||||
ctx.isFlow = isFlow
|
||||
return &ctx
|
||||
}
|
||||
|
||||
func newContext() *context {
|
||||
return &context{
|
||||
path: "$",
|
||||
}
|
||||
if c.size <= c.idx+num {
|
||||
c.idx = c.size
|
||||
}
|
||||
|
||||
func (c *context) goNext() {
|
||||
ref := c.tokenRef
|
||||
if ref.size <= ref.idx+1 {
|
||||
ref.idx = ref.size
|
||||
} else {
|
||||
c.idx += num
|
||||
ref.idx++
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) progress(num int) {
|
||||
if c.isCurrentCommentToken() {
|
||||
func (c *context) next() bool {
|
||||
return c.tokenRef.idx < c.tokenRef.size
|
||||
}
|
||||
|
||||
func (c *context) insertNullToken(tk *Token) *Token {
|
||||
nullToken := c.createImplicitNullToken(tk)
|
||||
c.insertToken(nullToken)
|
||||
c.goNext()
|
||||
|
||||
return nullToken
|
||||
}
|
||||
|
||||
func (c *context) addNullValueToken(tk *Token) *Token {
|
||||
nullToken := c.createImplicitNullToken(tk)
|
||||
rawTk := nullToken.RawToken()
|
||||
|
||||
// add space for map or sequence value.
|
||||
rawTk.Position.Column++
|
||||
|
||||
c.addToken(nullToken)
|
||||
c.goNext()
|
||||
|
||||
return nullToken
|
||||
}
|
||||
|
||||
func (c *context) createImplicitNullToken(base *Token) *Token {
|
||||
pos := *(base.RawToken().Position)
|
||||
pos.Column++
|
||||
tk := token.New("null", " null", &pos)
|
||||
tk.Type = token.ImplicitNullType
|
||||
return &Token{Token: tk}
|
||||
}
|
||||
|
||||
func (c *context) insertToken(tk *Token) {
|
||||
ref := c.tokenRef
|
||||
idx := ref.idx
|
||||
if ref.size < idx {
|
||||
return
|
||||
}
|
||||
c.progressIgnoreComment(num)
|
||||
if ref.size == idx {
|
||||
curToken := ref.tokens[ref.size-1]
|
||||
tk.RawToken().Next = curToken.RawToken()
|
||||
curToken.RawToken().Prev = tk.RawToken()
|
||||
|
||||
ref.tokens = append(ref.tokens, tk)
|
||||
ref.size = len(ref.tokens)
|
||||
return
|
||||
}
|
||||
|
||||
curToken := ref.tokens[idx]
|
||||
tk.RawToken().Next = curToken.RawToken()
|
||||
curToken.RawToken().Prev = tk.RawToken()
|
||||
|
||||
ref.tokens = append(ref.tokens[:idx+1], ref.tokens[idx:]...)
|
||||
ref.tokens[idx] = tk
|
||||
ref.size = len(ref.tokens)
|
||||
}
|
||||
|
||||
func newContext(tokens token.Tokens, mode Mode) *context {
|
||||
filteredTokens := []*token.Token{}
|
||||
if mode&ParseComments != 0 {
|
||||
filteredTokens = tokens
|
||||
} else {
|
||||
for _, tk := range tokens {
|
||||
if tk.Type == token.CommentType {
|
||||
continue
|
||||
}
|
||||
// keep prev/next reference between tokens containing comments
|
||||
// https://github.com/goccy/go-yaml/issues/254
|
||||
filteredTokens = append(filteredTokens, tk)
|
||||
}
|
||||
}
|
||||
return &context{
|
||||
idx: 0,
|
||||
size: len(filteredTokens),
|
||||
tokens: token.Tokens(filteredTokens),
|
||||
path: "$",
|
||||
func (c *context) addToken(tk *Token) {
|
||||
ref := c.tokenRef
|
||||
lastTk := ref.tokens[ref.size-1]
|
||||
if lastTk.Group != nil {
|
||||
lastTk = lastTk.Group.Last()
|
||||
}
|
||||
lastTk.RawToken().Next = tk.RawToken()
|
||||
tk.RawToken().Prev = lastTk.RawToken()
|
||||
|
||||
ref.tokens = append(ref.tokens, tk)
|
||||
ref.size = len(ref.tokens)
|
||||
}
|
||||
|
||||
257
vendor/github.com/goccy/go-yaml/parser/node.go
generated
vendored
Normal file
257
vendor/github.com/goccy/go-yaml/parser/node.go
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"github.com/goccy/go-yaml/internal/errors"
|
||||
"github.com/goccy/go-yaml/token"
|
||||
)
|
||||
|
||||
func newMappingNode(ctx *context, tk *Token, isFlow bool, values ...*ast.MappingValueNode) (*ast.MappingNode, error) {
|
||||
node := ast.Mapping(tk.RawToken(), isFlow, values...)
|
||||
node.SetPath(ctx.path)
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newMappingValueNode(ctx *context, colonTk, entryTk *Token, key ast.MapKeyNode, value ast.Node) (*ast.MappingValueNode, error) {
|
||||
node := ast.MappingValue(colonTk.RawToken(), key, value)
|
||||
node.SetPath(ctx.path)
|
||||
node.CollectEntry = entryTk.RawToken()
|
||||
if key.GetToken().Position.Line == value.GetToken().Position.Line {
|
||||
// originally key was commented, but now that null value has been added, value must be commented.
|
||||
if err := setLineComment(ctx, value, colonTk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// set line comment by colonTk or entryTk.
|
||||
if err := setLineComment(ctx, value, entryTk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := setLineComment(ctx, key, colonTk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// set line comment by colonTk or entryTk.
|
||||
if err := setLineComment(ctx, key, entryTk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newMappingKeyNode(ctx *context, tk *Token) (*ast.MappingKeyNode, error) {
|
||||
node := ast.MappingKey(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newAnchorNode(ctx *context, tk *Token) (*ast.AnchorNode, error) {
|
||||
node := ast.Anchor(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newAliasNode(ctx *context, tk *Token) (*ast.AliasNode, error) {
|
||||
node := ast.Alias(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newDirectiveNode(ctx *context, tk *Token) (*ast.DirectiveNode, error) {
|
||||
node := ast.Directive(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newMergeKeyNode(ctx *context, tk *Token) (*ast.MergeKeyNode, error) {
|
||||
node := ast.MergeKey(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newNullNode(ctx *context, tk *Token) (*ast.NullNode, error) {
|
||||
node := ast.Null(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newBoolNode(ctx *context, tk *Token) (*ast.BoolNode, error) {
|
||||
node := ast.Bool(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newIntegerNode(ctx *context, tk *Token) (*ast.IntegerNode, error) {
|
||||
node := ast.Integer(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newFloatNode(ctx *context, tk *Token) (*ast.FloatNode, error) {
|
||||
node := ast.Float(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newInfinityNode(ctx *context, tk *Token) (*ast.InfinityNode, error) {
|
||||
node := ast.Infinity(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newNanNode(ctx *context, tk *Token) (*ast.NanNode, error) {
|
||||
node := ast.Nan(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newStringNode(ctx *context, tk *Token) (*ast.StringNode, error) {
|
||||
node := ast.String(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newLiteralNode(ctx *context, tk *Token) (*ast.LiteralNode, error) {
|
||||
node := ast.Literal(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newTagNode(ctx *context, tk *Token) (*ast.TagNode, error) {
|
||||
node := ast.Tag(tk.RawToken())
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newSequenceNode(ctx *context, tk *Token, isFlow bool) (*ast.SequenceNode, error) {
|
||||
node := ast.Sequence(tk.RawToken(), isFlow)
|
||||
node.SetPath(ctx.path)
|
||||
if err := setLineComment(ctx, node, tk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newTagDefaultScalarValueNode(ctx *context, tag *token.Token) (ast.ScalarNode, error) {
|
||||
pos := *(tag.Position)
|
||||
pos.Column++
|
||||
|
||||
var (
|
||||
tk *Token
|
||||
node ast.ScalarNode
|
||||
)
|
||||
switch token.ReservedTagKeyword(tag.Value) {
|
||||
case token.IntegerTag:
|
||||
tk = &Token{Token: token.New("0", "0", &pos)}
|
||||
n, err := newIntegerNode(ctx, tk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node = n
|
||||
case token.FloatTag:
|
||||
tk = &Token{Token: token.New("0", "0", &pos)}
|
||||
n, err := newFloatNode(ctx, tk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node = n
|
||||
case token.StringTag, token.BinaryTag, token.TimestampTag:
|
||||
tk = &Token{Token: token.New("", "", &pos)}
|
||||
n, err := newStringNode(ctx, tk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node = n
|
||||
case token.BooleanTag:
|
||||
tk = &Token{Token: token.New("false", "false", &pos)}
|
||||
n, err := newBoolNode(ctx, tk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node = n
|
||||
case token.NullTag:
|
||||
tk = &Token{Token: token.New("null", "null", &pos)}
|
||||
n, err := newNullNode(ctx, tk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node = n
|
||||
default:
|
||||
return nil, errors.ErrSyntax(fmt.Sprintf("cannot assign default value for %q tag", tag.Value), tag)
|
||||
}
|
||||
ctx.insertToken(tk)
|
||||
ctx.goNext()
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func setLineComment(ctx *context, node ast.Node, tk *Token) error {
|
||||
if tk == nil || tk.LineComment == nil {
|
||||
return nil
|
||||
}
|
||||
comment := ast.CommentGroup([]*token.Token{tk.LineComment})
|
||||
comment.SetPath(ctx.path)
|
||||
if err := node.SetComment(comment); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHeadComment(cm *ast.CommentGroupNode, value ast.Node) error {
|
||||
if cm == nil {
|
||||
return nil
|
||||
}
|
||||
switch n := value.(type) {
|
||||
case *ast.MappingNode:
|
||||
if len(n.Values) != 0 && value.GetComment() == nil {
|
||||
cm.SetPath(n.Values[0].GetPath())
|
||||
return n.Values[0].SetComment(cm)
|
||||
}
|
||||
case *ast.MappingValueNode:
|
||||
cm.SetPath(n.GetPath())
|
||||
return n.SetComment(cm)
|
||||
}
|
||||
cm.SetPath(value.GetPath())
|
||||
return value.SetComment(cm)
|
||||
}
|
||||
12
vendor/github.com/goccy/go-yaml/parser/option.go
generated
vendored
Normal file
12
vendor/github.com/goccy/go-yaml/parser/option.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
package parser
|
||||
|
||||
// Option represents parser's option.
|
||||
type Option func(p *parser)
|
||||
|
||||
// AllowDuplicateMapKey allow the use of keys with the same name in the same map,
|
||||
// but by default, this is not permitted.
|
||||
func AllowDuplicateMapKey() Option {
|
||||
return func(p *parser) {
|
||||
p.allowDuplicateMapKey = true
|
||||
}
|
||||
}
|
||||
1981
vendor/github.com/goccy/go-yaml/parser/parser.go
generated
vendored
1981
vendor/github.com/goccy/go-yaml/parser/parser.go
generated
vendored
File diff suppressed because it is too large
Load Diff
746
vendor/github.com/goccy/go-yaml/parser/token.go
generated
vendored
Normal file
746
vendor/github.com/goccy/go-yaml/parser/token.go
generated
vendored
Normal file
@@ -0,0 +1,746 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/goccy/go-yaml/internal/errors"
|
||||
"github.com/goccy/go-yaml/token"
|
||||
)
|
||||
|
||||
type TokenGroupType int
|
||||
|
||||
const (
|
||||
TokenGroupNone TokenGroupType = iota
|
||||
TokenGroupDirective
|
||||
TokenGroupDirectiveName
|
||||
TokenGroupDocument
|
||||
TokenGroupDocumentBody
|
||||
TokenGroupAnchor
|
||||
TokenGroupAnchorName
|
||||
TokenGroupAlias
|
||||
TokenGroupLiteral
|
||||
TokenGroupFolded
|
||||
TokenGroupScalarTag
|
||||
TokenGroupMapKey
|
||||
TokenGroupMapKeyValue
|
||||
)
|
||||
|
||||
func (t TokenGroupType) String() string {
|
||||
switch t {
|
||||
case TokenGroupNone:
|
||||
return "none"
|
||||
case TokenGroupDirective:
|
||||
return "directive"
|
||||
case TokenGroupDirectiveName:
|
||||
return "directive_name"
|
||||
case TokenGroupDocument:
|
||||
return "document"
|
||||
case TokenGroupDocumentBody:
|
||||
return "document_body"
|
||||
case TokenGroupAnchor:
|
||||
return "anchor"
|
||||
case TokenGroupAnchorName:
|
||||
return "anchor_name"
|
||||
case TokenGroupAlias:
|
||||
return "alias"
|
||||
case TokenGroupLiteral:
|
||||
return "literal"
|
||||
case TokenGroupFolded:
|
||||
return "folded"
|
||||
case TokenGroupScalarTag:
|
||||
return "scalar_tag"
|
||||
case TokenGroupMapKey:
|
||||
return "map_key"
|
||||
case TokenGroupMapKeyValue:
|
||||
return "map_key_value"
|
||||
}
|
||||
return "none"
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Token *token.Token
|
||||
Group *TokenGroup
|
||||
LineComment *token.Token
|
||||
}
|
||||
|
||||
func (t *Token) RawToken() *token.Token {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
if t.Token != nil {
|
||||
return t.Token
|
||||
}
|
||||
return t.Group.RawToken()
|
||||
}
|
||||
|
||||
func (t *Token) Type() token.Type {
|
||||
if t == nil {
|
||||
return 0
|
||||
}
|
||||
if t.Token != nil {
|
||||
return t.Token.Type
|
||||
}
|
||||
return t.Group.TokenType()
|
||||
}
|
||||
|
||||
func (t *Token) GroupType() TokenGroupType {
|
||||
if t == nil {
|
||||
return TokenGroupNone
|
||||
}
|
||||
if t.Token != nil {
|
||||
return TokenGroupNone
|
||||
}
|
||||
return t.Group.Type
|
||||
}
|
||||
|
||||
func (t *Token) Line() int {
|
||||
if t == nil {
|
||||
return 0
|
||||
}
|
||||
if t.Token != nil {
|
||||
return t.Token.Position.Line
|
||||
}
|
||||
return t.Group.Line()
|
||||
}
|
||||
|
||||
func (t *Token) Column() int {
|
||||
if t == nil {
|
||||
return 0
|
||||
}
|
||||
if t.Token != nil {
|
||||
return t.Token.Position.Column
|
||||
}
|
||||
return t.Group.Column()
|
||||
}
|
||||
|
||||
func (t *Token) SetGroupType(typ TokenGroupType) {
|
||||
if t.Group == nil {
|
||||
return
|
||||
}
|
||||
t.Group.Type = typ
|
||||
}
|
||||
|
||||
func (t *Token) Dump() {
|
||||
ctx := new(groupTokenRenderContext)
|
||||
if t.Token != nil {
|
||||
fmt.Fprint(os.Stdout, t.Token.Value)
|
||||
return
|
||||
}
|
||||
t.Group.dump(ctx)
|
||||
fmt.Fprintf(os.Stdout, "\n")
|
||||
}
|
||||
|
||||
func (t *Token) dump(ctx *groupTokenRenderContext) {
|
||||
if t.Token != nil {
|
||||
fmt.Fprint(os.Stdout, t.Token.Value)
|
||||
return
|
||||
}
|
||||
t.Group.dump(ctx)
|
||||
}
|
||||
|
||||
type groupTokenRenderContext struct {
|
||||
num int
|
||||
}
|
||||
|
||||
type TokenGroup struct {
|
||||
Type TokenGroupType
|
||||
Tokens []*Token
|
||||
}
|
||||
|
||||
func (g *TokenGroup) First() *Token {
|
||||
if len(g.Tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
return g.Tokens[0]
|
||||
}
|
||||
|
||||
func (g *TokenGroup) Last() *Token {
|
||||
if len(g.Tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
return g.Tokens[len(g.Tokens)-1]
|
||||
}
|
||||
|
||||
func (g *TokenGroup) dump(ctx *groupTokenRenderContext) {
|
||||
num := ctx.num
|
||||
fmt.Fprint(os.Stdout, colorize(num, "("))
|
||||
ctx.num++
|
||||
for _, tk := range g.Tokens {
|
||||
tk.dump(ctx)
|
||||
}
|
||||
fmt.Fprint(os.Stdout, colorize(num, ")"))
|
||||
}
|
||||
|
||||
func (g *TokenGroup) RawToken() *token.Token {
|
||||
if len(g.Tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
return g.Tokens[0].RawToken()
|
||||
}
|
||||
|
||||
func (g *TokenGroup) Line() int {
|
||||
if len(g.Tokens) == 0 {
|
||||
return 0
|
||||
}
|
||||
return g.Tokens[0].Line()
|
||||
}
|
||||
|
||||
func (g *TokenGroup) Column() int {
|
||||
if len(g.Tokens) == 0 {
|
||||
return 0
|
||||
}
|
||||
return g.Tokens[0].Column()
|
||||
}
|
||||
|
||||
func (g *TokenGroup) TokenType() token.Type {
|
||||
if len(g.Tokens) == 0 {
|
||||
return 0
|
||||
}
|
||||
return g.Tokens[0].Type()
|
||||
}
|
||||
|
||||
func CreateGroupedTokens(tokens token.Tokens) ([]*Token, error) {
|
||||
var err error
|
||||
tks := newTokens(tokens)
|
||||
tks = createLineCommentTokenGroups(tks)
|
||||
tks, err = createLiteralAndFoldedTokenGroups(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tks, err = createAnchorAndAliasTokenGroups(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tks, err = createScalarTagTokenGroups(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tks, err = createAnchorWithScalarTagTokenGroups(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tks, err = createMapKeyTokenGroups(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tks = createMapKeyValueTokenGroups(tks)
|
||||
tks, err = createDirectiveTokenGroups(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tks, err = createDocumentTokens(tks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tks, nil
|
||||
}
|
||||
|
||||
func newTokens(tks token.Tokens) []*Token {
|
||||
ret := make([]*Token, 0, len(tks))
|
||||
for _, tk := range tks {
|
||||
ret = append(ret, &Token{Token: tk})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func createLineCommentTokenGroups(tokens []*Token) []*Token {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.CommentType:
|
||||
if i > 0 && tokens[i-1].Line() == tk.Line() {
|
||||
tokens[i-1].LineComment = tk.RawToken()
|
||||
} else {
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func createLiteralAndFoldedTokenGroups(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.LiteralType:
|
||||
tks := []*Token{tk}
|
||||
if i+1 < len(tokens) {
|
||||
tks = append(tks, tokens[i+1])
|
||||
}
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupLiteral,
|
||||
Tokens: tks,
|
||||
},
|
||||
})
|
||||
i++
|
||||
case token.FoldedType:
|
||||
tks := []*Token{tk}
|
||||
if i+1 < len(tokens) {
|
||||
tks = append(tks, tokens[i+1])
|
||||
}
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupFolded,
|
||||
Tokens: tks,
|
||||
},
|
||||
})
|
||||
i++
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createAnchorAndAliasTokenGroups(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.AnchorType:
|
||||
if i+1 >= len(tokens) {
|
||||
return nil, errors.ErrSyntax("undefined anchor name", tk.RawToken())
|
||||
}
|
||||
if i+2 >= len(tokens) {
|
||||
return nil, errors.ErrSyntax("undefined anchor value", tk.RawToken())
|
||||
}
|
||||
anchorName := &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupAnchorName,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
}
|
||||
valueTk := tokens[i+2]
|
||||
if tk.Line() == valueTk.Line() && valueTk.Type() == token.SequenceEntryType {
|
||||
return nil, errors.ErrSyntax("sequence entries are not allowed after anchor on the same line", valueTk.RawToken())
|
||||
}
|
||||
if tk.Line() == valueTk.Line() && isScalarType(valueTk) {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupAnchor,
|
||||
Tokens: []*Token{anchorName, valueTk},
|
||||
},
|
||||
})
|
||||
i++
|
||||
} else {
|
||||
ret = append(ret, anchorName)
|
||||
}
|
||||
i++
|
||||
case token.AliasType:
|
||||
if i+1 == len(tokens) {
|
||||
return nil, errors.ErrSyntax("undefined alias name", tk.RawToken())
|
||||
}
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupAlias,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
})
|
||||
i++
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createScalarTagTokenGroups(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
if tk.Type() != token.TagType {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
tag := tk.RawToken()
|
||||
if strings.HasPrefix(tag.Value, "!!") {
|
||||
// secondary tag.
|
||||
switch token.ReservedTagKeyword(tag.Value) {
|
||||
case token.IntegerTag, token.FloatTag, token.StringTag, token.BinaryTag, token.TimestampTag, token.BooleanTag, token.NullTag:
|
||||
if len(tokens) <= i+1 {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tk.Line() != tokens[i+1].Line() {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tokens[i+1].GroupType() == TokenGroupAnchorName {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if isScalarType(tokens[i+1]) {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupScalarTag,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
})
|
||||
i++
|
||||
} else {
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
case token.MergeTag:
|
||||
if len(tokens) <= i+1 {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tk.Line() != tokens[i+1].Line() {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tokens[i+1].GroupType() == TokenGroupAnchorName {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tokens[i+1].Type() != token.MergeKeyType {
|
||||
return nil, errors.ErrSyntax("could not find merge key", tokens[i+1].RawToken())
|
||||
}
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupScalarTag,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
})
|
||||
i++
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
} else {
|
||||
if len(tokens) <= i+1 {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tk.Line() != tokens[i+1].Line() {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if tokens[i+1].GroupType() == TokenGroupAnchorName {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if isFlowType(tokens[i+1]) {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupScalarTag,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
})
|
||||
i++
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createAnchorWithScalarTagTokenGroups(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.GroupType() {
|
||||
case TokenGroupAnchorName:
|
||||
if i+1 >= len(tokens) {
|
||||
return nil, errors.ErrSyntax("undefined anchor value", tk.RawToken())
|
||||
}
|
||||
valueTk := tokens[i+1]
|
||||
if tk.Line() == valueTk.Line() && valueTk.GroupType() == TokenGroupScalarTag {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupAnchor,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
})
|
||||
i++
|
||||
} else {
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createMapKeyTokenGroups(tokens []*Token) ([]*Token, error) {
|
||||
tks, err := createMapKeyByMappingKey(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return createMapKeyByMappingValue(tks)
|
||||
}
|
||||
|
||||
func createMapKeyByMappingKey(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.MappingKeyType:
|
||||
if i+1 >= len(tokens) {
|
||||
return nil, errors.ErrSyntax("undefined map key", tk.RawToken())
|
||||
}
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupMapKey,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
})
|
||||
i++
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createMapKeyByMappingValue(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.MappingValueType:
|
||||
if i == 0 {
|
||||
return nil, errors.ErrSyntax("unexpected key name", tk.RawToken())
|
||||
}
|
||||
mapKeyTk := tokens[i-1]
|
||||
if isNotMapKeyType(mapKeyTk) {
|
||||
return nil, errors.ErrSyntax("found an invalid key for this map", tokens[i].RawToken())
|
||||
}
|
||||
newTk := &Token{Token: mapKeyTk.Token, Group: mapKeyTk.Group}
|
||||
mapKeyTk.Token = nil
|
||||
mapKeyTk.Group = &TokenGroup{
|
||||
Type: TokenGroupMapKey,
|
||||
Tokens: []*Token{newTk, tk},
|
||||
}
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createMapKeyValueTokenGroups(tokens []*Token) []*Token {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.GroupType() {
|
||||
case TokenGroupMapKey:
|
||||
if len(tokens) <= i+1 {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
valueTk := tokens[i+1]
|
||||
if tk.Line() != valueTk.Line() {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if valueTk.GroupType() == TokenGroupAnchorName {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
if valueTk.Type() == token.TagType && valueTk.GroupType() != TokenGroupScalarTag {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
|
||||
if isScalarType(valueTk) || valueTk.Type() == token.TagType {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupMapKeyValue,
|
||||
Tokens: []*Token{tk, valueTk},
|
||||
},
|
||||
})
|
||||
i++
|
||||
} else {
|
||||
ret = append(ret, tk)
|
||||
continue
|
||||
}
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func createDirectiveTokenGroups(tokens []*Token) ([]*Token, error) {
|
||||
ret := make([]*Token, 0, len(tokens))
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.DirectiveType:
|
||||
if i+1 >= len(tokens) {
|
||||
return nil, errors.ErrSyntax("undefined directive value", tk.RawToken())
|
||||
}
|
||||
directiveName := &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDirectiveName,
|
||||
Tokens: []*Token{tk, tokens[i+1]},
|
||||
},
|
||||
}
|
||||
i++
|
||||
var valueTks []*Token
|
||||
for j := i + 1; j < len(tokens); j++ {
|
||||
if tokens[j].Line() != tk.Line() {
|
||||
break
|
||||
}
|
||||
valueTks = append(valueTks, tokens[j])
|
||||
i++
|
||||
}
|
||||
if i+1 >= len(tokens) || tokens[i+1].Type() != token.DocumentHeaderType {
|
||||
return nil, errors.ErrSyntax("unexpected directive value. document not started", tk.RawToken())
|
||||
}
|
||||
if len(valueTks) != 0 {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDirective,
|
||||
Tokens: append([]*Token{directiveName}, valueTks...),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
ret = append(ret, directiveName)
|
||||
}
|
||||
default:
|
||||
ret = append(ret, tk)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func createDocumentTokens(tokens []*Token) ([]*Token, error) {
|
||||
var ret []*Token
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
tk := tokens[i]
|
||||
switch tk.Type() {
|
||||
case token.DocumentHeaderType:
|
||||
if i != 0 {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{Tokens: tokens[:i]},
|
||||
})
|
||||
}
|
||||
if i+1 == len(tokens) {
|
||||
// if current token is last token, add DocumentHeader only tokens to ret.
|
||||
return append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDocument,
|
||||
Tokens: []*Token{tk},
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
if tokens[i+1].Type() == token.DocumentHeaderType {
|
||||
return append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDocument,
|
||||
Tokens: []*Token{tk},
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
if tokens[i].Line() == tokens[i+1].Line() {
|
||||
switch tokens[i+1].GroupType() {
|
||||
case TokenGroupMapKey, TokenGroupMapKeyValue:
|
||||
return nil, errors.ErrSyntax("value cannot be placed after document separator", tokens[i+1].RawToken())
|
||||
}
|
||||
switch tokens[i+1].Type() {
|
||||
case token.SequenceEntryType:
|
||||
return nil, errors.ErrSyntax("value cannot be placed after document separator", tokens[i+1].RawToken())
|
||||
}
|
||||
}
|
||||
tks, err := createDocumentTokens(tokens[i+1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(tks) != 0 {
|
||||
tks[0].SetGroupType(TokenGroupDocument)
|
||||
tks[0].Group.Tokens = append([]*Token{tk}, tks[0].Group.Tokens...)
|
||||
return append(ret, tks...), nil
|
||||
}
|
||||
return append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDocument,
|
||||
Tokens: []*Token{tk},
|
||||
},
|
||||
}), nil
|
||||
case token.DocumentEndType:
|
||||
if i != 0 {
|
||||
ret = append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDocument,
|
||||
Tokens: tokens[0 : i+1],
|
||||
},
|
||||
})
|
||||
}
|
||||
if i+1 == len(tokens) {
|
||||
return ret, nil
|
||||
}
|
||||
if isScalarType(tokens[i+1]) {
|
||||
return nil, errors.ErrSyntax("unexpected end content", tokens[i+1].RawToken())
|
||||
}
|
||||
|
||||
tks, err := createDocumentTokens(tokens[i+1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(ret, tks...), nil
|
||||
}
|
||||
}
|
||||
return append(ret, &Token{
|
||||
Group: &TokenGroup{
|
||||
Type: TokenGroupDocument,
|
||||
Tokens: tokens,
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func isScalarType(tk *Token) bool {
|
||||
switch tk.GroupType() {
|
||||
case TokenGroupMapKey, TokenGroupMapKeyValue:
|
||||
return false
|
||||
}
|
||||
typ := tk.Type()
|
||||
return typ == token.AnchorType ||
|
||||
typ == token.AliasType ||
|
||||
typ == token.LiteralType ||
|
||||
typ == token.FoldedType ||
|
||||
typ == token.NullType ||
|
||||
typ == token.ImplicitNullType ||
|
||||
typ == token.BoolType ||
|
||||
typ == token.IntegerType ||
|
||||
typ == token.BinaryIntegerType ||
|
||||
typ == token.OctetIntegerType ||
|
||||
typ == token.HexIntegerType ||
|
||||
typ == token.FloatType ||
|
||||
typ == token.InfinityType ||
|
||||
typ == token.NanType ||
|
||||
typ == token.StringType ||
|
||||
typ == token.SingleQuoteType ||
|
||||
typ == token.DoubleQuoteType
|
||||
}
|
||||
|
||||
func isNotMapKeyType(tk *Token) bool {
|
||||
typ := tk.Type()
|
||||
return typ == token.DirectiveType ||
|
||||
typ == token.DocumentHeaderType ||
|
||||
typ == token.DocumentEndType ||
|
||||
typ == token.CollectEntryType ||
|
||||
typ == token.MappingStartType ||
|
||||
typ == token.MappingValueType ||
|
||||
typ == token.MappingEndType ||
|
||||
typ == token.SequenceStartType ||
|
||||
typ == token.SequenceEntryType ||
|
||||
typ == token.SequenceEndType
|
||||
}
|
||||
|
||||
func isFlowType(tk *Token) bool {
|
||||
typ := tk.Type()
|
||||
return typ == token.MappingStartType ||
|
||||
typ == token.MappingEndType ||
|
||||
typ == token.SequenceStartType ||
|
||||
typ == token.SequenceEntryType
|
||||
}
|
||||
177
vendor/github.com/goccy/go-yaml/path.go
generated
vendored
177
vendor/github.com/goccy/go-yaml/path.go
generated
vendored
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"github.com/goccy/go-yaml/internal/errors"
|
||||
"github.com/goccy/go-yaml/parser"
|
||||
"github.com/goccy/go-yaml/printer"
|
||||
)
|
||||
@@ -39,7 +38,7 @@ func PathString(s string) (*Path, error) {
|
||||
case '.':
|
||||
b, buf, c, err := parsePathDot(builder, buf, cursor)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse path of dot")
|
||||
return nil, err
|
||||
}
|
||||
length = len(buf)
|
||||
builder = b
|
||||
@@ -47,13 +46,13 @@ func PathString(s string) (*Path, error) {
|
||||
case '[':
|
||||
b, buf, c, err := parsePathIndex(builder, buf, cursor)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse path of index")
|
||||
return nil, err
|
||||
}
|
||||
length = len(buf)
|
||||
builder = b
|
||||
cursor = c
|
||||
default:
|
||||
return nil, errors.Wrapf(ErrInvalidPathString, "invalid path at %d", cursor)
|
||||
return nil, fmt.Errorf("invalid path at %d: %w", cursor, ErrInvalidPathString)
|
||||
}
|
||||
}
|
||||
return builder.Build(), nil
|
||||
@@ -67,28 +66,31 @@ func parsePathRecursive(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, [
|
||||
c := buf[cursor]
|
||||
switch c {
|
||||
case '$':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '..' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified '$' after '..' character: %w", ErrInvalidPathString)
|
||||
case '*':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '..' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified '*' after '..' character: %w", ErrInvalidPathString)
|
||||
case '.', '[':
|
||||
goto end
|
||||
case ']':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '..' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified ']' after '..' character: %w", ErrInvalidPathString)
|
||||
}
|
||||
}
|
||||
end:
|
||||
if start == cursor {
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "not found recursive selector")
|
||||
return nil, nil, 0, fmt.Errorf("not found recursive selector: %w", ErrInvalidPathString)
|
||||
}
|
||||
return b.Recursive(string(buf[start:cursor])), buf, cursor, nil
|
||||
}
|
||||
|
||||
func parsePathDot(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
|
||||
if b.root == nil || b.node == nil {
|
||||
return nil, nil, 0, fmt.Errorf("required '$' character at first: %w", ErrInvalidPathString)
|
||||
}
|
||||
length := len(buf)
|
||||
if cursor+1 < length && buf[cursor+1] == '.' {
|
||||
b, buf, c, err := parsePathRecursive(b, buf, cursor)
|
||||
if err != nil {
|
||||
return nil, nil, 0, errors.Wrapf(err, "failed to parse path of recursive")
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
return b, buf, c, nil
|
||||
}
|
||||
@@ -103,23 +105,27 @@ func parsePathDot(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune,
|
||||
c := buf[cursor]
|
||||
switch c {
|
||||
case '$':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '.' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified '$' after '.' character: %w", ErrInvalidPathString)
|
||||
case '*':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '.' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified '*' after '.' character: %w", ErrInvalidPathString)
|
||||
case '.', '[':
|
||||
goto end
|
||||
case ']':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '.' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified ']' after '.' character: %w", ErrInvalidPathString)
|
||||
}
|
||||
}
|
||||
end:
|
||||
if start == cursor {
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "cloud not find by empty key")
|
||||
return nil, nil, 0, fmt.Errorf("could not find by empty key: %w", ErrInvalidPathString)
|
||||
}
|
||||
return b.child(string(buf[start:cursor])), buf, cursor, nil
|
||||
}
|
||||
|
||||
func parseQuotedKey(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
|
||||
if b.root == nil || b.node == nil {
|
||||
return nil, nil, 0, fmt.Errorf("required '$' character at first: %w", ErrInvalidPathString)
|
||||
}
|
||||
|
||||
cursor++ // skip single quote
|
||||
start := cursor
|
||||
length := len(buf)
|
||||
@@ -136,31 +142,35 @@ func parseQuotedKey(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
|
||||
}
|
||||
end:
|
||||
if !foundEndDelim {
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "could not find end delimiter for key")
|
||||
return nil, nil, 0, fmt.Errorf("could not find end delimiter for key: %w", ErrInvalidPathString)
|
||||
}
|
||||
if start == cursor {
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "could not find by empty key")
|
||||
return nil, nil, 0, fmt.Errorf("could not find by empty key: %w", ErrInvalidPathString)
|
||||
}
|
||||
selector := buf[start:cursor]
|
||||
cursor++
|
||||
if cursor < length {
|
||||
switch buf[cursor] {
|
||||
case '$':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '.' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified '$' after '.' character: %w", ErrInvalidPathString)
|
||||
case '*':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '.' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified '*' after '.' character: %w", ErrInvalidPathString)
|
||||
case ']':
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '.' character")
|
||||
return nil, nil, 0, fmt.Errorf("specified ']' after '.' character: %w", ErrInvalidPathString)
|
||||
}
|
||||
}
|
||||
return b.child(string(selector)), buf, cursor, nil
|
||||
}
|
||||
|
||||
func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
|
||||
if b.root == nil || b.node == nil {
|
||||
return nil, nil, 0, fmt.Errorf("required '$' character at first: %w", ErrInvalidPathString)
|
||||
}
|
||||
|
||||
length := len(buf)
|
||||
cursor++ // skip '[' character
|
||||
if length <= cursor {
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "unexpected end of YAML Path")
|
||||
return nil, nil, 0, fmt.Errorf("unexpected end of YAML Path: %w", ErrInvalidPathString)
|
||||
}
|
||||
c := buf[cursor]
|
||||
switch c {
|
||||
@@ -176,7 +186,7 @@ func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
|
||||
break
|
||||
}
|
||||
if buf[cursor] != ']' {
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "invalid character %s at %d", string(buf[cursor]), cursor)
|
||||
return nil, nil, 0, fmt.Errorf("invalid character %s at %d: %w", string(buf[cursor]), cursor, ErrInvalidPathString)
|
||||
}
|
||||
numOrAll := string(buf[start:cursor])
|
||||
if numOrAll == "*" {
|
||||
@@ -184,11 +194,11 @@ func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
|
||||
}
|
||||
num, err := strconv.ParseInt(numOrAll, 10, 64)
|
||||
if err != nil {
|
||||
return nil, nil, 0, errors.Wrapf(err, "failed to parse number")
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
return b.Index(uint(num)), buf, cursor + 1, nil
|
||||
}
|
||||
return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "invalid character %s at %d", c, cursor)
|
||||
return nil, nil, 0, fmt.Errorf("invalid character %q at %d: %w", c, cursor, ErrInvalidPathString)
|
||||
}
|
||||
|
||||
// Path represent YAMLPath ( like a JSONPath ).
|
||||
@@ -205,10 +215,10 @@ func (p *Path) String() string {
|
||||
func (p *Path) Read(r io.Reader, v interface{}) error {
|
||||
node, err := p.ReadNode(r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to read node")
|
||||
return err
|
||||
}
|
||||
if err := Unmarshal([]byte(node.String()), v); err != nil {
|
||||
return errors.Wrapf(err, "failed to unmarshal")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -220,15 +230,15 @@ func (p *Path) ReadNode(r io.Reader) (ast.Node, error) {
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if _, err := io.Copy(&buf, r); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to copy from reader")
|
||||
return nil, err
|
||||
}
|
||||
f, err := parser.ParseBytes(buf.Bytes(), 0)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse yaml")
|
||||
return nil, err
|
||||
}
|
||||
node, err := p.FilterFile(f)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter from ast.File")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -237,10 +247,10 @@ func (p *Path) ReadNode(r io.Reader) (ast.Node, error) {
|
||||
func (p *Path) Filter(target, v interface{}) error {
|
||||
b, err := Marshal(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to marshal target value")
|
||||
return err
|
||||
}
|
||||
if err := p.Read(bytes.NewBuffer(b), v); err != nil {
|
||||
return errors.Wrapf(err, "failed to read")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -250,20 +260,23 @@ func (p *Path) FilterFile(f *ast.File) (ast.Node, error) {
|
||||
for _, doc := range f.Docs {
|
||||
node, err := p.FilterNode(doc.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter node by path ( %s )", p.node)
|
||||
return nil, err
|
||||
}
|
||||
if node != nil {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(ErrNotFoundNode, "failed to find path ( %s )", p.node)
|
||||
return nil, fmt.Errorf("failed to find path ( %s ): %w", p.node, ErrNotFoundNode)
|
||||
}
|
||||
|
||||
// FilterNode filter from node by YAMLPath.
|
||||
func (p *Path) FilterNode(node ast.Node) (ast.Node, error) {
|
||||
if node == nil {
|
||||
return nil, nil
|
||||
}
|
||||
n, err := p.node.filter(node)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter node by path ( %s )", p.node)
|
||||
return nil, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
@@ -272,14 +285,14 @@ func (p *Path) FilterNode(node ast.Node) (ast.Node, error) {
|
||||
func (p *Path) MergeFromReader(dst *ast.File, src io.Reader) error {
|
||||
var buf bytes.Buffer
|
||||
if _, err := io.Copy(&buf, src); err != nil {
|
||||
return errors.Wrapf(err, "failed to copy from reader")
|
||||
return err
|
||||
}
|
||||
file, err := parser.ParseBytes(buf.Bytes(), 0)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse")
|
||||
return err
|
||||
}
|
||||
if err := p.MergeFromFile(dst, file); err != nil {
|
||||
return errors.Wrapf(err, "failed to merge file")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -288,11 +301,11 @@ func (p *Path) MergeFromReader(dst *ast.File, src io.Reader) error {
|
||||
func (p *Path) MergeFromFile(dst *ast.File, src *ast.File) error {
|
||||
base, err := p.FilterFile(dst)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to filter file")
|
||||
return err
|
||||
}
|
||||
for _, doc := range src.Docs {
|
||||
if err := ast.Merge(base, doc); err != nil {
|
||||
return errors.Wrapf(err, "failed to merge")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -302,10 +315,10 @@ func (p *Path) MergeFromFile(dst *ast.File, src *ast.File) error {
|
||||
func (p *Path) MergeFromNode(dst *ast.File, src ast.Node) error {
|
||||
base, err := p.FilterFile(dst)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to filter file")
|
||||
return err
|
||||
}
|
||||
if err := ast.Merge(base, src); err != nil {
|
||||
return errors.Wrapf(err, "failed to merge")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -314,14 +327,14 @@ func (p *Path) MergeFromNode(dst *ast.File, src ast.Node) error {
|
||||
func (p *Path) ReplaceWithReader(dst *ast.File, src io.Reader) error {
|
||||
var buf bytes.Buffer
|
||||
if _, err := io.Copy(&buf, src); err != nil {
|
||||
return errors.Wrapf(err, "failed to copy from reader")
|
||||
return err
|
||||
}
|
||||
file, err := parser.ParseBytes(buf.Bytes(), 0)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse")
|
||||
return err
|
||||
}
|
||||
if err := p.ReplaceWithFile(dst, file); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace file")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -330,7 +343,7 @@ func (p *Path) ReplaceWithReader(dst *ast.File, src io.Reader) error {
|
||||
func (p *Path) ReplaceWithFile(dst *ast.File, src *ast.File) error {
|
||||
for _, doc := range src.Docs {
|
||||
if err := p.ReplaceWithNode(dst, doc); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace file by path ( %s )", p.node)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -343,7 +356,7 @@ func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error {
|
||||
node = node.(*ast.DocumentNode).Body
|
||||
}
|
||||
if err := p.node.replace(doc.Body, node); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace node by path ( %s )", p.node)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -472,7 +485,7 @@ func (n *rootNode) filter(node ast.Node) (ast.Node, error) {
|
||||
}
|
||||
filtered, err := n.child.filter(node)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
@@ -482,7 +495,7 @@ func (n *rootNode) replace(node ast.Node, target ast.Node) error {
|
||||
return nil
|
||||
}
|
||||
if err := n.child.replace(node, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -514,7 +527,7 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
|
||||
var err error
|
||||
key, err = strconv.Unquote(key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to unquote")
|
||||
return nil, err
|
||||
}
|
||||
case '\'':
|
||||
if len(key) > 1 && key[len(key)-1] == '\'' {
|
||||
@@ -528,13 +541,13 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
|
||||
}
|
||||
filtered, err := n.child.filter(value.Value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
}
|
||||
case ast.MappingValueType:
|
||||
value := node.(*ast.MappingValueNode)
|
||||
value, _ := node.(*ast.MappingValueNode)
|
||||
key := value.Key.GetToken().Value
|
||||
if key == selector {
|
||||
if n.child == nil {
|
||||
@@ -542,12 +555,12 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
|
||||
}
|
||||
filtered, err := n.child.filter(value.Value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
default:
|
||||
return nil, errors.Wrapf(ErrInvalidQuery, "expected node type is map or map value. but got %s", node.Type())
|
||||
return nil, fmt.Errorf("expected node type is map or map value. but got %s: %w", node.Type(), ErrInvalidQuery)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -559,11 +572,11 @@ func (n *selectorNode) replaceMapValue(value *ast.MappingValueNode, target ast.N
|
||||
}
|
||||
if n.child == nil {
|
||||
if err := value.Replace(target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := n.child.replace(value.Value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -574,16 +587,16 @@ func (n *selectorNode) replace(node ast.Node, target ast.Node) error {
|
||||
case ast.MappingType:
|
||||
for _, value := range node.(*ast.MappingNode).Values {
|
||||
if err := n.replaceMapValue(value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace map value")
|
||||
return err
|
||||
}
|
||||
}
|
||||
case ast.MappingValueType:
|
||||
value := node.(*ast.MappingValueNode)
|
||||
value, _ := node.(*ast.MappingValueNode)
|
||||
if err := n.replaceMapValue(value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace map value")
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errors.Wrapf(ErrInvalidQuery, "expected node type is map or map value. but got %s", node.Type())
|
||||
return fmt.Errorf("expected node type is map or map value. but got %s: %w", node.Type(), ErrInvalidQuery)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -612,11 +625,11 @@ func newIndexNode(selector uint) *indexNode {
|
||||
|
||||
func (n *indexNode) filter(node ast.Node) (ast.Node, error) {
|
||||
if node.Type() != ast.SequenceType {
|
||||
return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
|
||||
return nil, fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
|
||||
}
|
||||
sequence := node.(*ast.SequenceNode)
|
||||
sequence, _ := node.(*ast.SequenceNode)
|
||||
if n.selector >= uint(len(sequence.Values)) {
|
||||
return nil, errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values)
|
||||
return nil, fmt.Errorf("expected index is %d. but got sequences has %d items: %w", n.selector, len(sequence.Values), ErrInvalidQuery)
|
||||
}
|
||||
value := sequence.Values[n.selector]
|
||||
if n.child == nil {
|
||||
@@ -624,27 +637,27 @@ func (n *indexNode) filter(node ast.Node) (ast.Node, error) {
|
||||
}
|
||||
filtered, err := n.child.filter(value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
|
||||
func (n *indexNode) replace(node ast.Node, target ast.Node) error {
|
||||
if node.Type() != ast.SequenceType {
|
||||
return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
|
||||
return fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
|
||||
}
|
||||
sequence := node.(*ast.SequenceNode)
|
||||
sequence, _ := node.(*ast.SequenceNode)
|
||||
if n.selector >= uint(len(sequence.Values)) {
|
||||
return errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values)
|
||||
return fmt.Errorf("expected index is %d. but got sequences has %d items: %w", n.selector, len(sequence.Values), ErrInvalidQuery)
|
||||
}
|
||||
if n.child == nil {
|
||||
if err := sequence.Replace(int(n.selector), target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := n.child.replace(sequence.Values[n.selector], target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -677,9 +690,9 @@ func (n *indexAllNode) String() string {
|
||||
|
||||
func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
|
||||
if node.Type() != ast.SequenceType {
|
||||
return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
|
||||
return nil, fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
|
||||
}
|
||||
sequence := node.(*ast.SequenceNode)
|
||||
sequence, _ := node.(*ast.SequenceNode)
|
||||
if n.child == nil {
|
||||
return sequence, nil
|
||||
}
|
||||
@@ -688,7 +701,7 @@ func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
|
||||
for _, value := range sequence.Values {
|
||||
filtered, err := n.child.filter(value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
out.Values = append(out.Values, filtered)
|
||||
}
|
||||
@@ -697,20 +710,20 @@ func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
|
||||
|
||||
func (n *indexAllNode) replace(node ast.Node, target ast.Node) error {
|
||||
if node.Type() != ast.SequenceType {
|
||||
return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
|
||||
return fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
|
||||
}
|
||||
sequence := node.(*ast.SequenceNode)
|
||||
sequence, _ := node.(*ast.SequenceNode)
|
||||
if n.child == nil {
|
||||
for idx := range sequence.Values {
|
||||
if err := sequence.Replace(idx, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, value := range sequence.Values {
|
||||
if err := n.child.replace(value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -743,7 +756,7 @@ func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
|
||||
for _, value := range typedNode.Values {
|
||||
seq, err := n.filterNode(value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
sequence.Values = append(sequence.Values, seq.Values...)
|
||||
}
|
||||
@@ -754,14 +767,14 @@ func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
|
||||
}
|
||||
seq, err := n.filterNode(typedNode.Value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
sequence.Values = append(sequence.Values, seq.Values...)
|
||||
case *ast.SequenceNode:
|
||||
for _, value := range typedNode.Values {
|
||||
seq, err := n.filterNode(value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
sequence.Values = append(sequence.Values, seq.Values...)
|
||||
}
|
||||
@@ -772,7 +785,7 @@ func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
|
||||
func (n *recursiveNode) filter(node ast.Node) (ast.Node, error) {
|
||||
sequence, err := n.filterNode(node)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to filter")
|
||||
return nil, err
|
||||
}
|
||||
sequence.Start = node.GetToken()
|
||||
return sequence, nil
|
||||
@@ -783,23 +796,23 @@ func (n *recursiveNode) replaceNode(node ast.Node, target ast.Node) error {
|
||||
case *ast.MappingNode:
|
||||
for _, value := range typedNode.Values {
|
||||
if err := n.replaceNode(value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
}
|
||||
case *ast.MappingValueNode:
|
||||
key := typedNode.Key.GetToken().Value
|
||||
if n.selector == key {
|
||||
if err := typedNode.Replace(target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := n.replaceNode(typedNode.Value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
case *ast.SequenceNode:
|
||||
for _, value := range typedNode.Values {
|
||||
if err := n.replaceNode(value, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -808,7 +821,7 @@ func (n *recursiveNode) replaceNode(node ast.Node, target ast.Node) error {
|
||||
|
||||
func (n *recursiveNode) replace(node ast.Node, target ast.Node) error {
|
||||
if err := n.replaceNode(node, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to replace")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
83
vendor/github.com/goccy/go-yaml/printer/color.go
generated
vendored
Normal file
83
vendor/github.com/goccy/go-yaml/printer/color.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// This source inspired by https://github.com/fatih/color.
|
||||
package printer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ColorAttribute int
|
||||
|
||||
const (
|
||||
ColorReset ColorAttribute = iota
|
||||
ColorBold
|
||||
ColorFaint
|
||||
ColorItalic
|
||||
ColorUnderline
|
||||
ColorBlinkSlow
|
||||
ColorBlinkRapid
|
||||
ColorReverseVideo
|
||||
ColorConcealed
|
||||
ColorCrossedOut
|
||||
)
|
||||
|
||||
const (
|
||||
ColorFgHiBlack ColorAttribute = iota + 90
|
||||
ColorFgHiRed
|
||||
ColorFgHiGreen
|
||||
ColorFgHiYellow
|
||||
ColorFgHiBlue
|
||||
ColorFgHiMagenta
|
||||
ColorFgHiCyan
|
||||
ColorFgHiWhite
|
||||
)
|
||||
|
||||
const (
|
||||
ColorResetBold ColorAttribute = iota + 22
|
||||
ColorResetItalic
|
||||
ColorResetUnderline
|
||||
ColorResetBlinking
|
||||
|
||||
ColorResetReversed
|
||||
ColorResetConcealed
|
||||
ColorResetCrossedOut
|
||||
)
|
||||
|
||||
const escape = "\x1b"
|
||||
|
||||
var colorResetMap = map[ColorAttribute]ColorAttribute{
|
||||
ColorBold: ColorResetBold,
|
||||
ColorFaint: ColorResetBold,
|
||||
ColorItalic: ColorResetItalic,
|
||||
ColorUnderline: ColorResetUnderline,
|
||||
ColorBlinkSlow: ColorResetBlinking,
|
||||
ColorBlinkRapid: ColorResetBlinking,
|
||||
ColorReverseVideo: ColorResetReversed,
|
||||
ColorConcealed: ColorResetConcealed,
|
||||
ColorCrossedOut: ColorResetCrossedOut,
|
||||
}
|
||||
|
||||
func format(attrs ...ColorAttribute) string {
|
||||
format := make([]string, 0, len(attrs))
|
||||
for _, attr := range attrs {
|
||||
format = append(format, fmt.Sprint(attr))
|
||||
}
|
||||
return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";"))
|
||||
}
|
||||
|
||||
func unformat(attrs ...ColorAttribute) string {
|
||||
format := make([]string, len(attrs))
|
||||
for _, attr := range attrs {
|
||||
v := fmt.Sprint(ColorReset)
|
||||
reset, exists := colorResetMap[attr]
|
||||
if exists {
|
||||
v = fmt.Sprint(reset)
|
||||
}
|
||||
format = append(format, v)
|
||||
}
|
||||
return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";"))
|
||||
}
|
||||
|
||||
func colorize(msg string, attrs ...ColorAttribute) string {
|
||||
return format(attrs...) + msg + unformat(attrs...)
|
||||
}
|
||||
55
vendor/github.com/goccy/go-yaml/printer/printer.go
generated
vendored
55
vendor/github.com/goccy/go-yaml/printer/printer.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"github.com/goccy/go-yaml/token"
|
||||
)
|
||||
@@ -29,6 +28,7 @@ type Printer struct {
|
||||
Bool PrintFunc
|
||||
String PrintFunc
|
||||
Number PrintFunc
|
||||
Comment PrintFunc
|
||||
}
|
||||
|
||||
func defaultLineNumberFormat(num int) string {
|
||||
@@ -82,6 +82,11 @@ func (p *Printer) property(tk *token.Token) *Property {
|
||||
return p.Number()
|
||||
}
|
||||
return prop
|
||||
case token.CommentType:
|
||||
if p.Comment != nil {
|
||||
return p.Comment()
|
||||
}
|
||||
return prop
|
||||
default:
|
||||
}
|
||||
return prop
|
||||
@@ -144,47 +149,47 @@ func (p *Printer) PrintNode(node ast.Node) []byte {
|
||||
return []byte(fmt.Sprintf("%+v\n", node))
|
||||
}
|
||||
|
||||
const escape = "\x1b"
|
||||
|
||||
func format(attr color.Attribute) string {
|
||||
return fmt.Sprintf("%s[%dm", escape, attr)
|
||||
}
|
||||
|
||||
func (p *Printer) setDefaultColorSet() {
|
||||
p.Bool = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(color.FgHiMagenta),
|
||||
Suffix: format(color.Reset),
|
||||
Prefix: format(ColorFgHiMagenta),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
p.Number = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(color.FgHiMagenta),
|
||||
Suffix: format(color.Reset),
|
||||
Prefix: format(ColorFgHiMagenta),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
p.MapKey = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(color.FgHiCyan),
|
||||
Suffix: format(color.Reset),
|
||||
Prefix: format(ColorFgHiCyan),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
p.Anchor = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(color.FgHiYellow),
|
||||
Suffix: format(color.Reset),
|
||||
Prefix: format(ColorFgHiYellow),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
p.Alias = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(color.FgHiYellow),
|
||||
Suffix: format(color.Reset),
|
||||
Prefix: format(ColorFgHiYellow),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
p.String = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(color.FgHiGreen),
|
||||
Suffix: format(color.Reset),
|
||||
Prefix: format(ColorFgHiGreen),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
p.Comment = func() *Property {
|
||||
return &Property{
|
||||
Prefix: format(ColorFgHiBlack),
|
||||
Suffix: format(ColorReset),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,9 +197,9 @@ func (p *Printer) setDefaultColorSet() {
|
||||
func (p *Printer) PrintErrorMessage(msg string, isColored bool) string {
|
||||
if isColored {
|
||||
return fmt.Sprintf("%s%s%s",
|
||||
format(color.FgHiRed),
|
||||
format(ColorFgHiRed),
|
||||
msg,
|
||||
format(color.Reset),
|
||||
format(ColorReset),
|
||||
)
|
||||
}
|
||||
return msg
|
||||
@@ -246,10 +251,7 @@ func (p *Printer) isNewLineLastChar(s string) bool {
|
||||
}
|
||||
|
||||
func (p *Printer) printBeforeTokens(tk *token.Token, minLine, extLine int) token.Tokens {
|
||||
for {
|
||||
if tk.Prev == nil {
|
||||
break
|
||||
}
|
||||
for tk.Prev != nil {
|
||||
if tk.Prev.Position.Line < minLine {
|
||||
break
|
||||
}
|
||||
@@ -317,8 +319,7 @@ func (p *Printer) setupErrorTokenFormat(annotateLine int, isColored bool) {
|
||||
p.LineNumber = true
|
||||
p.LineNumberFormat = func(num int) string {
|
||||
if isColored {
|
||||
fn := color.New(color.Bold, color.FgHiWhite).SprintFunc()
|
||||
return fn(prefix(annotateLine, num))
|
||||
return colorize(prefix(annotateLine, num), ColorBold, ColorFgHiWhite)
|
||||
}
|
||||
return prefix(annotateLine, num)
|
||||
}
|
||||
|
||||
326
vendor/github.com/goccy/go-yaml/scanner/context.go
generated
vendored
326
vendor/github.com/goccy/go-yaml/scanner/context.go
generated
vendored
@@ -1,13 +1,14 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/goccy/go-yaml/token"
|
||||
)
|
||||
|
||||
const whitespace = ' '
|
||||
|
||||
// Context context at scanning
|
||||
type Context struct {
|
||||
idx int
|
||||
@@ -18,11 +19,20 @@ type Context struct {
|
||||
buf []rune
|
||||
obuf []rune
|
||||
tokens token.Tokens
|
||||
isRawFolded bool
|
||||
isLiteral bool
|
||||
isFolded bool
|
||||
isSingleLine bool
|
||||
literalOpt string
|
||||
mstate *MultiLineState
|
||||
}
|
||||
|
||||
type MultiLineState struct {
|
||||
opt string
|
||||
firstLineIndentColumn int
|
||||
prevLineIndentColumn int
|
||||
lineIndentColumn int
|
||||
lastNotSpaceOnlyLineIndentColumn int
|
||||
spaceOnlyIndentColumn int
|
||||
foldedNewLine bool
|
||||
isRawFolded bool
|
||||
isLiteral bool
|
||||
isFolded bool
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -35,14 +45,13 @@ var (
|
||||
|
||||
func createContext() *Context {
|
||||
return &Context{
|
||||
idx: 0,
|
||||
tokens: token.Tokens{},
|
||||
isSingleLine: true,
|
||||
idx: 0,
|
||||
tokens: token.Tokens{},
|
||||
}
|
||||
}
|
||||
|
||||
func newContext(src []rune) *Context {
|
||||
ctx := ctxPool.Get().(*Context)
|
||||
ctx, _ := ctxPool.Get().(*Context)
|
||||
ctx.reset(src)
|
||||
return ctx
|
||||
}
|
||||
@@ -51,17 +60,18 @@ func (c *Context) release() {
|
||||
ctxPool.Put(c)
|
||||
}
|
||||
|
||||
func (c *Context) clear() {
|
||||
c.resetBuffer()
|
||||
c.mstate = nil
|
||||
}
|
||||
|
||||
func (c *Context) reset(src []rune) {
|
||||
c.idx = 0
|
||||
c.size = len(src)
|
||||
c.src = src
|
||||
c.tokens = c.tokens[:0]
|
||||
c.resetBuffer()
|
||||
c.isRawFolded = false
|
||||
c.isSingleLine = true
|
||||
c.isLiteral = false
|
||||
c.isFolded = false
|
||||
c.literalOpt = ""
|
||||
c.mstate = nil
|
||||
}
|
||||
|
||||
func (c *Context) resetBuffer() {
|
||||
@@ -71,15 +81,185 @@ func (c *Context) resetBuffer() {
|
||||
c.notSpaceOrgCharPos = 0
|
||||
}
|
||||
|
||||
func (c *Context) isSaveIndentMode() bool {
|
||||
return c.isLiteral || c.isFolded || c.isRawFolded
|
||||
func (c *Context) breakMultiLine() {
|
||||
c.mstate = nil
|
||||
}
|
||||
|
||||
func (c *Context) breakLiteral() {
|
||||
c.isLiteral = false
|
||||
c.isRawFolded = false
|
||||
c.isFolded = false
|
||||
c.literalOpt = ""
|
||||
func (c *Context) getMultiLineState() *MultiLineState {
|
||||
return c.mstate
|
||||
}
|
||||
|
||||
func (c *Context) setLiteral(lastDelimColumn int, opt string) {
|
||||
mstate := &MultiLineState{
|
||||
isLiteral: true,
|
||||
opt: opt,
|
||||
}
|
||||
indent := firstLineIndentColumnByOpt(opt)
|
||||
if indent > 0 {
|
||||
mstate.firstLineIndentColumn = lastDelimColumn + indent
|
||||
}
|
||||
c.mstate = mstate
|
||||
}
|
||||
|
||||
func (c *Context) setFolded(lastDelimColumn int, opt string) {
|
||||
mstate := &MultiLineState{
|
||||
isFolded: true,
|
||||
opt: opt,
|
||||
}
|
||||
indent := firstLineIndentColumnByOpt(opt)
|
||||
if indent > 0 {
|
||||
mstate.firstLineIndentColumn = lastDelimColumn + indent
|
||||
}
|
||||
c.mstate = mstate
|
||||
}
|
||||
|
||||
func (c *Context) setRawFolded(column int) {
|
||||
mstate := &MultiLineState{
|
||||
isRawFolded: true,
|
||||
}
|
||||
mstate.updateIndentColumn(column)
|
||||
c.mstate = mstate
|
||||
}
|
||||
|
||||
func firstLineIndentColumnByOpt(opt string) int {
|
||||
opt = strings.TrimPrefix(opt, "-")
|
||||
opt = strings.TrimPrefix(opt, "+")
|
||||
opt = strings.TrimSuffix(opt, "-")
|
||||
opt = strings.TrimSuffix(opt, "+")
|
||||
i, _ := strconv.ParseInt(opt, 10, 64)
|
||||
return int(i)
|
||||
}
|
||||
|
||||
func (s *MultiLineState) lastDelimColumn() int {
|
||||
if s.firstLineIndentColumn == 0 {
|
||||
return 0
|
||||
}
|
||||
return s.firstLineIndentColumn - 1
|
||||
}
|
||||
|
||||
func (s *MultiLineState) updateIndentColumn(column int) {
|
||||
if s.firstLineIndentColumn == 0 {
|
||||
s.firstLineIndentColumn = column
|
||||
}
|
||||
if s.lineIndentColumn == 0 {
|
||||
s.lineIndentColumn = column
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MultiLineState) updateSpaceOnlyIndentColumn(column int) {
|
||||
if s.firstLineIndentColumn != 0 {
|
||||
return
|
||||
}
|
||||
s.spaceOnlyIndentColumn = column
|
||||
}
|
||||
|
||||
func (s *MultiLineState) validateIndentAfterSpaceOnly(column int) error {
|
||||
if s.firstLineIndentColumn != 0 {
|
||||
return nil
|
||||
}
|
||||
if s.spaceOnlyIndentColumn > column {
|
||||
return errors.New("invalid number of indent is specified after space only")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MultiLineState) validateIndentColumn() error {
|
||||
if firstLineIndentColumnByOpt(s.opt) == 0 {
|
||||
return nil
|
||||
}
|
||||
if s.firstLineIndentColumn > s.lineIndentColumn {
|
||||
return errors.New("invalid number of indent is specified in the multi-line header")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MultiLineState) updateNewLineState() {
|
||||
s.prevLineIndentColumn = s.lineIndentColumn
|
||||
if s.lineIndentColumn != 0 {
|
||||
s.lastNotSpaceOnlyLineIndentColumn = s.lineIndentColumn
|
||||
}
|
||||
s.foldedNewLine = true
|
||||
s.lineIndentColumn = 0
|
||||
}
|
||||
|
||||
func (s *MultiLineState) isIndentColumn(column int) bool {
|
||||
if s.firstLineIndentColumn == 0 {
|
||||
return column == 1
|
||||
}
|
||||
return s.firstLineIndentColumn > column
|
||||
}
|
||||
|
||||
func (s *MultiLineState) addIndent(ctx *Context, column int) {
|
||||
if s.firstLineIndentColumn == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// If the first line of the document has already been evaluated, the number is treated as the threshold, since the `firstLineIndentColumn` is a positive number.
|
||||
if column < s.firstLineIndentColumn {
|
||||
return
|
||||
}
|
||||
|
||||
// `c.foldedNewLine` is a variable that is set to true for every newline.
|
||||
if !s.isLiteral && s.foldedNewLine {
|
||||
s.foldedNewLine = false
|
||||
}
|
||||
// Since addBuf ignore space character, add to the buffer directly.
|
||||
ctx.buf = append(ctx.buf, ' ')
|
||||
ctx.notSpaceCharPos = len(ctx.buf)
|
||||
}
|
||||
|
||||
// updateNewLineInFolded if Folded or RawFolded context and the content on the current line starts at the same column as the previous line,
|
||||
// treat the new-line-char as a space.
|
||||
func (s *MultiLineState) updateNewLineInFolded(ctx *Context, column int) {
|
||||
if s.isLiteral {
|
||||
return
|
||||
}
|
||||
|
||||
// Folded or RawFolded.
|
||||
|
||||
if !s.foldedNewLine {
|
||||
return
|
||||
}
|
||||
var (
|
||||
lastChar rune
|
||||
prevLastChar rune
|
||||
)
|
||||
if len(ctx.buf) != 0 {
|
||||
lastChar = ctx.buf[len(ctx.buf)-1]
|
||||
}
|
||||
if len(ctx.buf) > 1 {
|
||||
prevLastChar = ctx.buf[len(ctx.buf)-2]
|
||||
}
|
||||
if s.lineIndentColumn == s.prevLineIndentColumn {
|
||||
// ---
|
||||
// >
|
||||
// a
|
||||
// b
|
||||
if lastChar == '\n' {
|
||||
ctx.buf[len(ctx.buf)-1] = ' '
|
||||
}
|
||||
} else if s.prevLineIndentColumn == 0 && s.lastNotSpaceOnlyLineIndentColumn == column {
|
||||
// if previous line is indent-space and new-line-char only, prevLineIndentColumn is zero.
|
||||
// In this case, last new-line-char is removed.
|
||||
// ---
|
||||
// >
|
||||
// a
|
||||
//
|
||||
// b
|
||||
if lastChar == '\n' && prevLastChar == '\n' {
|
||||
ctx.buf = ctx.buf[:len(ctx.buf)-1]
|
||||
ctx.notSpaceCharPos = len(ctx.buf)
|
||||
}
|
||||
}
|
||||
s.foldedNewLine = false
|
||||
}
|
||||
|
||||
func (s *MultiLineState) hasTrimAllEndNewlineOpt() bool {
|
||||
return strings.HasPrefix(s.opt, "-") || strings.HasSuffix(s.opt, "-") || s.isRawFolded
|
||||
}
|
||||
|
||||
func (s *MultiLineState) hasKeepAllEndNewlineOpt() bool {
|
||||
return strings.HasPrefix(s.opt, "+") || strings.HasSuffix(s.opt, "+")
|
||||
}
|
||||
|
||||
func (c *Context) addToken(tk *token.Token) {
|
||||
@@ -90,7 +270,7 @@ func (c *Context) addToken(tk *token.Token) {
|
||||
}
|
||||
|
||||
func (c *Context) addBuf(r rune) {
|
||||
if len(c.buf) == 0 && r == ' ' {
|
||||
if len(c.buf) == 0 && (r == ' ' || r == '\t') {
|
||||
return
|
||||
}
|
||||
c.buf = append(c.buf, r)
|
||||
@@ -99,6 +279,16 @@ func (c *Context) addBuf(r rune) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) addBufWithTab(r rune) {
|
||||
if len(c.buf) == 0 && r == ' ' {
|
||||
return
|
||||
}
|
||||
c.buf = append(c.buf, r)
|
||||
if r != ' ' {
|
||||
c.notSpaceCharPos = len(c.buf)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) addOriginBuf(r rune) {
|
||||
c.obuf = append(c.obuf, r)
|
||||
if r != ' ' && r != '\t' {
|
||||
@@ -106,7 +296,7 @@ func (c *Context) addOriginBuf(r rune) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) removeRightSpaceFromBuf() int {
|
||||
func (c *Context) removeRightSpaceFromBuf() {
|
||||
trimmedBuf := c.obuf[:c.notSpaceOrgCharPos]
|
||||
buflen := len(trimmedBuf)
|
||||
diff := len(c.obuf) - buflen
|
||||
@@ -114,11 +304,6 @@ func (c *Context) removeRightSpaceFromBuf() int {
|
||||
c.obuf = c.obuf[:buflen]
|
||||
c.buf = c.bufferedSrc()
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
func (c *Context) isDocument() bool {
|
||||
return c.isLiteral || c.isFolded || c.isRawFolded
|
||||
}
|
||||
|
||||
func (c *Context) isEOS() bool {
|
||||
@@ -126,7 +311,7 @@ func (c *Context) isEOS() bool {
|
||||
}
|
||||
|
||||
func (c *Context) isNextEOS() bool {
|
||||
return len(c.src)-1 <= c.idx+1
|
||||
return len(c.src) <= c.idx+1
|
||||
}
|
||||
|
||||
func (c *Context) next() bool {
|
||||
@@ -151,18 +336,6 @@ func (c *Context) currentChar() rune {
|
||||
return rune(0)
|
||||
}
|
||||
|
||||
func (c *Context) currentCharWithSkipWhitespace() rune {
|
||||
idx := c.idx
|
||||
for c.size > idx {
|
||||
ch := c.src[idx]
|
||||
if ch != whitespace {
|
||||
return ch
|
||||
}
|
||||
idx++
|
||||
}
|
||||
return rune(0)
|
||||
}
|
||||
|
||||
func (c *Context) nextChar() rune {
|
||||
if c.size > c.idx+1 {
|
||||
return c.src[c.idx+1]
|
||||
@@ -186,25 +359,52 @@ func (c *Context) progress(num int) {
|
||||
c.idx += num
|
||||
}
|
||||
|
||||
func (c *Context) nextPos() int {
|
||||
return c.idx + 1
|
||||
}
|
||||
|
||||
func (c *Context) existsBuffer() bool {
|
||||
return len(c.bufferedSrc()) != 0
|
||||
}
|
||||
|
||||
func (c *Context) isMultiLine() bool {
|
||||
return c.mstate != nil
|
||||
}
|
||||
|
||||
func (c *Context) bufferedSrc() []rune {
|
||||
src := c.buf[:c.notSpaceCharPos]
|
||||
if c.isDocument() && c.literalOpt == "-" {
|
||||
// remove end '\n' character and trailing empty lines
|
||||
if c.isMultiLine() {
|
||||
mstate := c.getMultiLineState()
|
||||
// remove end '\n' character and trailing empty lines.
|
||||
// https://yaml.org/spec/1.2.2/#8112-block-chomping-indicator
|
||||
for {
|
||||
if len(src) > 0 && src[len(src)-1] == '\n' {
|
||||
src = src[:len(src)-1]
|
||||
continue
|
||||
if mstate.hasTrimAllEndNewlineOpt() {
|
||||
// If the '-' flag is specified, all trailing newline characters will be removed.
|
||||
src = []rune(strings.TrimRight(string(src), "\n"))
|
||||
} else if !mstate.hasKeepAllEndNewlineOpt() {
|
||||
// Normally, all but one of the trailing newline characters are removed.
|
||||
var newLineCharCount int
|
||||
for i := len(src) - 1; i >= 0; i-- {
|
||||
if src[i] == '\n' {
|
||||
newLineCharCount++
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
removedNewLineCharCount := newLineCharCount - 1
|
||||
for removedNewLineCharCount > 0 {
|
||||
src = []rune(strings.TrimSuffix(string(src), "\n"))
|
||||
removedNewLineCharCount--
|
||||
}
|
||||
}
|
||||
|
||||
// If the text ends with a space character, remove all of them.
|
||||
if mstate.hasTrimAllEndNewlineOpt() {
|
||||
src = []rune(strings.TrimRight(string(src), " "))
|
||||
}
|
||||
if string(src) == "\n" {
|
||||
// If the content consists only of a newline,
|
||||
// it can be considered as the document ending without any specified value,
|
||||
// so it is treated as an empty string.
|
||||
src = []rune{}
|
||||
}
|
||||
if mstate.hasKeepAllEndNewlineOpt() && len(src) == 0 {
|
||||
src = []rune{'\n'}
|
||||
}
|
||||
}
|
||||
return src
|
||||
@@ -216,18 +416,34 @@ func (c *Context) bufferedToken(pos *token.Position) *token.Token {
|
||||
}
|
||||
source := c.bufferedSrc()
|
||||
if len(source) == 0 {
|
||||
c.buf = c.buf[:0] // clear value's buffer only.
|
||||
return nil
|
||||
}
|
||||
var tk *token.Token
|
||||
if c.isDocument() {
|
||||
if c.isMultiLine() {
|
||||
tk = token.String(string(source), string(c.obuf), pos)
|
||||
} else {
|
||||
tk = token.New(string(source), string(c.obuf), pos)
|
||||
}
|
||||
c.setTokenTypeByPrevTag(tk)
|
||||
c.resetBuffer()
|
||||
return tk
|
||||
}
|
||||
|
||||
func (c *Context) setTokenTypeByPrevTag(tk *token.Token) {
|
||||
lastTk := c.lastToken()
|
||||
if lastTk == nil {
|
||||
return
|
||||
}
|
||||
if lastTk.Type != token.TagType {
|
||||
return
|
||||
}
|
||||
tag := token.ReservedTagKeyword(lastTk.Value)
|
||||
if _, exists := token.ReservedTagKeywordMap[tag]; !exists {
|
||||
tk.Type = token.StringType
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) lastToken() *token.Token {
|
||||
if len(c.tokens) != 0 {
|
||||
return c.tokens[len(c.tokens)-1]
|
||||
|
||||
17
vendor/github.com/goccy/go-yaml/scanner/error.go
generated
vendored
Normal file
17
vendor/github.com/goccy/go-yaml/scanner/error.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package scanner
|
||||
|
||||
import "github.com/goccy/go-yaml/token"
|
||||
|
||||
type InvalidTokenError struct {
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
func (e *InvalidTokenError) Error() string {
|
||||
return e.Token.Error
|
||||
}
|
||||
|
||||
func ErrInvalidToken(tk *token.Token) *InvalidTokenError {
|
||||
return &InvalidTokenError{
|
||||
Token: tk,
|
||||
}
|
||||
}
|
||||
1521
vendor/github.com/goccy/go-yaml/scanner/scanner.go
generated
vendored
1521
vendor/github.com/goccy/go-yaml/scanner/scanner.go
generated
vendored
File diff suppressed because it is too large
Load Diff
14
vendor/github.com/goccy/go-yaml/stdlib_quote.go
generated
vendored
14
vendor/github.com/goccy/go-yaml/stdlib_quote.go
generated
vendored
@@ -53,8 +53,18 @@ func appendQuotedWith(buf []byte, s string, quote byte) []byte {
|
||||
|
||||
func appendEscapedRune(buf []byte, r rune, quote byte) []byte {
|
||||
var runeTmp [utf8.UTFMax]byte
|
||||
if r == rune(quote) || r == '\\' { // always backslashed
|
||||
buf = append(buf, '\\')
|
||||
// goccy/go-yaml patch on top of the standard library's appendEscapedRune function.
|
||||
//
|
||||
// We use this to implement the YAML single-quoted string, where the only escape sequence is '', which represents a single quote.
|
||||
// The below snippet from the standard library is for escaping e.g. \ with \\, which is not what we want for the single-quoted string.
|
||||
//
|
||||
// if r == rune(quote) || r == '\\' { // always backslashed
|
||||
// buf = append(buf, '\\')
|
||||
// buf = append(buf, byte(r))
|
||||
// return buf
|
||||
// }
|
||||
if r == rune(quote) {
|
||||
buf = append(buf, byte(r))
|
||||
buf = append(buf, byte(r))
|
||||
return buf
|
||||
}
|
||||
|
||||
44
vendor/github.com/goccy/go-yaml/struct.go
generated
vendored
44
vendor/github.com/goccy/go-yaml/struct.go
generated
vendored
@@ -1,10 +1,9 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,6 +20,7 @@ type StructField struct {
|
||||
IsAutoAnchor bool
|
||||
IsAutoAlias bool
|
||||
IsOmitEmpty bool
|
||||
IsOmitZero bool
|
||||
IsFlow bool
|
||||
IsInline bool
|
||||
}
|
||||
@@ -45,7 +45,7 @@ func structField(field reflect.StructField) *StructField {
|
||||
fieldName = options[0]
|
||||
}
|
||||
}
|
||||
structField := &StructField{
|
||||
sf := &StructField{
|
||||
FieldName: field.Name,
|
||||
RenderName: fieldName,
|
||||
}
|
||||
@@ -53,30 +53,32 @@ func structField(field reflect.StructField) *StructField {
|
||||
for _, opt := range options[1:] {
|
||||
switch {
|
||||
case opt == "omitempty":
|
||||
structField.IsOmitEmpty = true
|
||||
sf.IsOmitEmpty = true
|
||||
case opt == "omitzero":
|
||||
sf.IsOmitZero = true
|
||||
case opt == "flow":
|
||||
structField.IsFlow = true
|
||||
sf.IsFlow = true
|
||||
case opt == "inline":
|
||||
structField.IsInline = true
|
||||
sf.IsInline = true
|
||||
case strings.HasPrefix(opt, "anchor"):
|
||||
anchor := strings.Split(opt, "=")
|
||||
if len(anchor) > 1 {
|
||||
structField.AnchorName = anchor[1]
|
||||
sf.AnchorName = anchor[1]
|
||||
} else {
|
||||
structField.IsAutoAnchor = true
|
||||
sf.IsAutoAnchor = true
|
||||
}
|
||||
case strings.HasPrefix(opt, "alias"):
|
||||
alias := strings.Split(opt, "=")
|
||||
if len(alias) > 1 {
|
||||
structField.AliasName = alias[1]
|
||||
sf.AliasName = alias[1]
|
||||
} else {
|
||||
structField.IsAutoAlias = true
|
||||
sf.IsAutoAlias = true
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
return structField
|
||||
return sf
|
||||
}
|
||||
|
||||
func isIgnoredStructField(field reflect.StructField) bool {
|
||||
@@ -84,11 +86,7 @@ func isIgnoredStructField(field reflect.StructField) bool {
|
||||
// private field
|
||||
return true
|
||||
}
|
||||
tag := getTag(field)
|
||||
if tag == "-" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return getTag(field) == "-"
|
||||
}
|
||||
|
||||
type StructFieldMap map[string]*StructField
|
||||
@@ -112,19 +110,19 @@ func (m StructFieldMap) hasMergeProperty() bool {
|
||||
}
|
||||
|
||||
func structFieldMap(structType reflect.Type) (StructFieldMap, error) {
|
||||
structFieldMap := StructFieldMap{}
|
||||
fieldMap := StructFieldMap{}
|
||||
renderNameMap := map[string]struct{}{}
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
field := structType.Field(i)
|
||||
if isIgnoredStructField(field) {
|
||||
continue
|
||||
}
|
||||
structField := structField(field)
|
||||
if _, exists := renderNameMap[structField.RenderName]; exists {
|
||||
return nil, xerrors.Errorf("duplicated struct field name %s", structField.RenderName)
|
||||
sf := structField(field)
|
||||
if _, exists := renderNameMap[sf.RenderName]; exists {
|
||||
return nil, fmt.Errorf("duplicated struct field name %s", sf.RenderName)
|
||||
}
|
||||
structFieldMap[structField.FieldName] = structField
|
||||
renderNameMap[structField.RenderName] = struct{}{}
|
||||
fieldMap[sf.FieldName] = sf
|
||||
renderNameMap[sf.RenderName] = struct{}{}
|
||||
}
|
||||
return structFieldMap, nil
|
||||
return fieldMap, nil
|
||||
}
|
||||
|
||||
343
vendor/github.com/goccy/go-yaml/token/token.go
generated
vendored
343
vendor/github.com/goccy/go-yaml/token/token.go
generated
vendored
@@ -1,8 +1,11 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Character type for character
|
||||
@@ -99,6 +102,10 @@ const (
|
||||
SpaceType
|
||||
// NullType type for Null token
|
||||
NullType
|
||||
// ImplicitNullType type for implicit Null token.
|
||||
// This is used when explicit keywords such as null or ~ are not specified.
|
||||
// It is distinguished during encoding and output as an empty string.
|
||||
ImplicitNullType
|
||||
// InfinityType type for Infinity token
|
||||
InfinityType
|
||||
// NanType type for Nan token
|
||||
@@ -117,6 +124,8 @@ const (
|
||||
StringType
|
||||
// BoolType type for Bool token
|
||||
BoolType
|
||||
// InvalidType type for invalid token
|
||||
InvalidType
|
||||
)
|
||||
|
||||
// String type identifier to text
|
||||
@@ -182,10 +191,14 @@ func (t Type) String() string {
|
||||
return "Float"
|
||||
case NullType:
|
||||
return "Null"
|
||||
case ImplicitNullType:
|
||||
return "ImplicitNull"
|
||||
case InfinityType:
|
||||
return "Infinity"
|
||||
case NanType:
|
||||
return "Nan"
|
||||
case InvalidType:
|
||||
return "Invalid"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -202,6 +215,8 @@ const (
|
||||
CharacterTypeMiscellaneous
|
||||
// CharacterTypeEscaped type of escaped character
|
||||
CharacterTypeEscaped
|
||||
// CharacterTypeInvalid type for a invalid token.
|
||||
CharacterTypeInvalid
|
||||
)
|
||||
|
||||
// String character type identifier to text
|
||||
@@ -210,7 +225,7 @@ func (c CharacterType) String() string {
|
||||
case CharacterTypeIndicator:
|
||||
return "Indicator"
|
||||
case CharacterTypeWhiteSpace:
|
||||
return "WhiteSpcae"
|
||||
return "WhiteSpace"
|
||||
case CharacterTypeMiscellaneous:
|
||||
return "Miscellaneous"
|
||||
case CharacterTypeEscaped:
|
||||
@@ -339,9 +354,12 @@ func reservedKeywordToken(typ Type, value, org string, pos *Position) *Token {
|
||||
|
||||
func init() {
|
||||
for _, keyword := range reservedNullKeywords {
|
||||
reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
|
||||
f := func(value, org string, pos *Position) *Token {
|
||||
return reservedKeywordToken(NullType, value, org, pos)
|
||||
}
|
||||
|
||||
reservedKeywordMap[keyword] = f
|
||||
reservedEncKeywordMap[keyword] = f
|
||||
}
|
||||
for _, keyword := range reservedBoolKeywords {
|
||||
f := func(value, org string, pos *Position) *Token {
|
||||
@@ -391,6 +409,10 @@ const (
|
||||
SetTag ReservedTagKeyword = "!!set"
|
||||
// TimestampTag `!!timestamp` tag
|
||||
TimestampTag ReservedTagKeyword = "!!timestamp"
|
||||
// BooleanTag `!!bool` tag
|
||||
BooleanTag ReservedTagKeyword = "!!bool"
|
||||
// MergeTag `!!merge` tag
|
||||
MergeTag ReservedTagKeyword = "!!merge"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -496,121 +518,163 @@ var (
|
||||
Position: pos,
|
||||
}
|
||||
},
|
||||
BooleanTag: func(value, org string, pos *Position) *Token {
|
||||
return &Token{
|
||||
Type: TagType,
|
||||
CharacterType: CharacterTypeIndicator,
|
||||
Indicator: NodePropertyIndicator,
|
||||
Value: value,
|
||||
Origin: org,
|
||||
Position: pos,
|
||||
}
|
||||
},
|
||||
MergeTag: func(value, org string, pos *Position) *Token {
|
||||
return &Token{
|
||||
Type: TagType,
|
||||
CharacterType: CharacterTypeIndicator,
|
||||
Indicator: NodePropertyIndicator,
|
||||
Value: value,
|
||||
Origin: org,
|
||||
Position: pos,
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type numType int
|
||||
type NumberType string
|
||||
|
||||
const (
|
||||
numTypeNone numType = iota
|
||||
numTypeBinary
|
||||
numTypeOctet
|
||||
numTypeHex
|
||||
numTypeFloat
|
||||
NumberTypeDecimal NumberType = "decimal"
|
||||
NumberTypeBinary NumberType = "binary"
|
||||
NumberTypeOctet NumberType = "octet"
|
||||
NumberTypeHex NumberType = "hex"
|
||||
NumberTypeFloat NumberType = "float"
|
||||
)
|
||||
|
||||
type numStat struct {
|
||||
isNum bool
|
||||
typ numType
|
||||
type NumberValue struct {
|
||||
Type NumberType
|
||||
Value any
|
||||
Text string
|
||||
}
|
||||
|
||||
func getNumberStat(str string) *numStat {
|
||||
stat := &numStat{}
|
||||
if str == "" {
|
||||
return stat
|
||||
func ToNumber(value string) *NumberValue {
|
||||
num, err := toNumber(value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if str == "-" || str == "." || str == "+" || str == "_" {
|
||||
return stat
|
||||
}
|
||||
if str[0] == '_' {
|
||||
return stat
|
||||
}
|
||||
dotFound := false
|
||||
isNegative := false
|
||||
isExponent := false
|
||||
if str[0] == '-' {
|
||||
isNegative = true
|
||||
}
|
||||
for idx, c := range str {
|
||||
switch c {
|
||||
case 'x':
|
||||
if (isNegative && idx == 2) || (!isNegative && idx == 1) {
|
||||
continue
|
||||
}
|
||||
case 'o':
|
||||
if (isNegative && idx == 2) || (!isNegative && idx == 1) {
|
||||
continue
|
||||
}
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
continue
|
||||
case 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F':
|
||||
if (len(str) > 2 && str[0] == '0' && str[1] == 'x') ||
|
||||
(len(str) > 3 && isNegative && str[1] == '0' && str[2] == 'x') {
|
||||
// hex number
|
||||
continue
|
||||
}
|
||||
if c == 'b' && ((isNegative && idx == 2) || (!isNegative && idx == 1)) {
|
||||
// binary number
|
||||
continue
|
||||
}
|
||||
if (c == 'e' || c == 'E') && dotFound {
|
||||
// exponent
|
||||
isExponent = true
|
||||
continue
|
||||
}
|
||||
case '.':
|
||||
if dotFound {
|
||||
// multiple dot
|
||||
return stat
|
||||
}
|
||||
dotFound = true
|
||||
continue
|
||||
case '-':
|
||||
if idx == 0 || isExponent {
|
||||
continue
|
||||
}
|
||||
case '+':
|
||||
if idx == 0 || isExponent {
|
||||
continue
|
||||
}
|
||||
case '_':
|
||||
continue
|
||||
}
|
||||
return stat
|
||||
}
|
||||
stat.isNum = true
|
||||
switch {
|
||||
case dotFound:
|
||||
stat.typ = numTypeFloat
|
||||
case strings.HasPrefix(str, "0b") || strings.HasPrefix(str, "-0b"):
|
||||
stat.typ = numTypeBinary
|
||||
case strings.HasPrefix(str, "0x") || strings.HasPrefix(str, "-0x"):
|
||||
stat.typ = numTypeHex
|
||||
case strings.HasPrefix(str, "0o") || strings.HasPrefix(str, "-0o"):
|
||||
stat.typ = numTypeOctet
|
||||
case (len(str) > 1 && str[0] == '0') || (len(str) > 1 && str[0] == '-' && str[1] == '0'):
|
||||
stat.typ = numTypeOctet
|
||||
}
|
||||
return stat
|
||||
return num
|
||||
}
|
||||
|
||||
func looksLikeTimeValue(value string) bool {
|
||||
for i, c := range value {
|
||||
switch c {
|
||||
case ':', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
continue
|
||||
case '0':
|
||||
if i == 0 {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
func isNumber(value string) bool {
|
||||
num, err := toNumber(value)
|
||||
if err != nil {
|
||||
var numErr *strconv.NumError
|
||||
if errors.As(err, &numErr) && errors.Is(numErr.Err, strconv.ErrRange) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return num != nil
|
||||
}
|
||||
|
||||
// IsNeedQuoted whether need quote for passed string or not
|
||||
func toNumber(value string) (*NumberValue, error) {
|
||||
if len(value) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if strings.HasPrefix(value, "_") {
|
||||
return nil, nil
|
||||
}
|
||||
dotCount := strings.Count(value, ".")
|
||||
if dotCount > 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
isNegative := strings.HasPrefix(value, "-")
|
||||
normalized := strings.ReplaceAll(strings.TrimPrefix(strings.TrimPrefix(value, "+"), "-"), "_", "")
|
||||
|
||||
var (
|
||||
typ NumberType
|
||||
base int
|
||||
)
|
||||
switch {
|
||||
case strings.HasPrefix(normalized, "0x"):
|
||||
normalized = strings.TrimPrefix(normalized, "0x")
|
||||
base = 16
|
||||
typ = NumberTypeHex
|
||||
case strings.HasPrefix(normalized, "0o"):
|
||||
normalized = strings.TrimPrefix(normalized, "0o")
|
||||
base = 8
|
||||
typ = NumberTypeOctet
|
||||
case strings.HasPrefix(normalized, "0b"):
|
||||
normalized = strings.TrimPrefix(normalized, "0b")
|
||||
base = 2
|
||||
typ = NumberTypeBinary
|
||||
case strings.HasPrefix(normalized, "0") && len(normalized) > 1 && dotCount == 0:
|
||||
base = 8
|
||||
typ = NumberTypeOctet
|
||||
case dotCount == 1:
|
||||
typ = NumberTypeFloat
|
||||
default:
|
||||
typ = NumberTypeDecimal
|
||||
base = 10
|
||||
}
|
||||
|
||||
text := normalized
|
||||
if isNegative {
|
||||
text = "-" + text
|
||||
}
|
||||
|
||||
var v any
|
||||
if typ == NumberTypeFloat {
|
||||
f, err := strconv.ParseFloat(text, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v = f
|
||||
} else if isNegative {
|
||||
i, err := strconv.ParseInt(text, base, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v = i
|
||||
} else {
|
||||
u, err := strconv.ParseUint(text, base, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v = u
|
||||
}
|
||||
|
||||
return &NumberValue{
|
||||
Type: typ,
|
||||
Value: v,
|
||||
Text: text,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// This is a subset of the formats permitted by the regular expression
|
||||
// defined at http://yaml.org/type/timestamp.html. Note that time.Parse
|
||||
// cannot handle: "2001-12-14 21:59:43.10 -5" from the examples.
|
||||
var timestampFormats = []string{
|
||||
time.RFC3339Nano,
|
||||
"2006-01-02t15:04:05.999999999Z07:00", // RFC3339Nano with lower-case "t".
|
||||
time.DateTime,
|
||||
time.DateOnly,
|
||||
|
||||
// Not in examples, but to preserve backward compatibility by quoting time values.
|
||||
"15:4",
|
||||
}
|
||||
|
||||
func isTimestamp(value string) bool {
|
||||
for _, format := range timestampFormats {
|
||||
if _, err := time.Parse(format, value); err == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsNeedQuoted checks whether the value needs quote for passed string or not
|
||||
func IsNeedQuoted(value string) bool {
|
||||
if value == "" {
|
||||
return true
|
||||
@@ -618,7 +682,10 @@ func IsNeedQuoted(value string) bool {
|
||||
if _, exists := reservedEncKeywordMap[value]; exists {
|
||||
return true
|
||||
}
|
||||
if stat := getNumberStat(value); stat.isNum {
|
||||
if isNumber(value) {
|
||||
return true
|
||||
}
|
||||
if value == "-" {
|
||||
return true
|
||||
}
|
||||
first := value[0]
|
||||
@@ -631,14 +698,14 @@ func IsNeedQuoted(value string) bool {
|
||||
case ':', ' ':
|
||||
return true
|
||||
}
|
||||
if looksLikeTimeValue(value) {
|
||||
if isTimestamp(value) {
|
||||
return true
|
||||
}
|
||||
for i, c := range value {
|
||||
switch c {
|
||||
case '#', '\\':
|
||||
return true
|
||||
case ':':
|
||||
case ':', '-':
|
||||
if i+1 < len(value) && value[i+1] == ' ' {
|
||||
return true
|
||||
}
|
||||
@@ -663,13 +730,13 @@ func LiteralBlockHeader(value string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// New create reserved keyword token or number token and other string token
|
||||
// New create reserved keyword token or number token and other string token.
|
||||
func New(value string, org string, pos *Position) *Token {
|
||||
fn := reservedKeywordMap[value]
|
||||
if fn != nil {
|
||||
return fn(value, org, pos)
|
||||
}
|
||||
if stat := getNumberStat(value); stat.isNum {
|
||||
if num := ToNumber(value); num != nil {
|
||||
tk := &Token{
|
||||
Type: IntegerType,
|
||||
CharacterType: CharacterTypeMiscellaneous,
|
||||
@@ -678,14 +745,14 @@ func New(value string, org string, pos *Position) *Token {
|
||||
Origin: org,
|
||||
Position: pos,
|
||||
}
|
||||
switch stat.typ {
|
||||
case numTypeFloat:
|
||||
switch num.Type {
|
||||
case NumberTypeFloat:
|
||||
tk.Type = FloatType
|
||||
case numTypeBinary:
|
||||
case NumberTypeBinary:
|
||||
tk.Type = BinaryIntegerType
|
||||
case numTypeOctet:
|
||||
case NumberTypeOctet:
|
||||
tk.Type = OctetIntegerType
|
||||
case numTypeHex:
|
||||
case NumberTypeHex:
|
||||
tk.Type = HexIntegerType
|
||||
}
|
||||
return tk
|
||||
@@ -709,14 +776,24 @@ func (p *Position) String() string {
|
||||
|
||||
// Token type for token
|
||||
type Token struct {
|
||||
Type Type
|
||||
// Type is a token type.
|
||||
Type Type
|
||||
// CharacterType is a character type.
|
||||
CharacterType CharacterType
|
||||
Indicator Indicator
|
||||
Value string
|
||||
Origin string
|
||||
Position *Position
|
||||
Next *Token
|
||||
Prev *Token
|
||||
// Indicator is a indicator type.
|
||||
Indicator Indicator
|
||||
// Value is a string extracted with only meaningful characters, with spaces and such removed.
|
||||
Value string
|
||||
// Origin is a string that stores the original text as-is.
|
||||
Origin string
|
||||
// Error keeps error message for InvalidToken.
|
||||
Error string
|
||||
// Position is a token position.
|
||||
Position *Position
|
||||
// Next is a next token reference.
|
||||
Next *Token
|
||||
// Prev is a previous token reference.
|
||||
Prev *Token
|
||||
}
|
||||
|
||||
// PreviousType previous token type
|
||||
@@ -756,9 +833,26 @@ func (t *Token) Clone() *Token {
|
||||
return &copied
|
||||
}
|
||||
|
||||
// Dump outputs token information to stdout for debugging.
|
||||
func (t *Token) Dump() {
|
||||
fmt.Printf(
|
||||
"[TYPE]:%q [CHARTYPE]:%q [INDICATOR]:%q [VALUE]:%q [ORG]:%q [POS(line:column:level:offset)]: %d:%d:%d:%d\n",
|
||||
t.Type, t.CharacterType, t.Indicator, t.Value, t.Origin, t.Position.Line, t.Position.Column, t.Position.IndentLevel, t.Position.Offset,
|
||||
)
|
||||
}
|
||||
|
||||
// Tokens type of token collection
|
||||
type Tokens []*Token
|
||||
|
||||
func (t Tokens) InvalidToken() *Token {
|
||||
for _, tt := range t {
|
||||
if tt.Type == InvalidType {
|
||||
return tt
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tokens) add(tk *Token) {
|
||||
tokens := *t
|
||||
if len(tokens) == 0 {
|
||||
@@ -782,7 +876,8 @@ func (t *Tokens) Add(tks ...*Token) {
|
||||
// Dump dump all token structures for debugging
|
||||
func (t Tokens) Dump() {
|
||||
for _, tk := range t {
|
||||
fmt.Printf("- %+v\n", tk)
|
||||
fmt.Print("- ")
|
||||
tk.Dump()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,6 +1149,18 @@ func DocumentEnd(org string, pos *Position) *Token {
|
||||
}
|
||||
}
|
||||
|
||||
func Invalid(err string, org string, pos *Position) *Token {
|
||||
return &Token{
|
||||
Type: InvalidType,
|
||||
CharacterType: CharacterTypeInvalid,
|
||||
Indicator: NotIndicator,
|
||||
Value: org,
|
||||
Origin: org,
|
||||
Error: err,
|
||||
Position: pos,
|
||||
}
|
||||
}
|
||||
|
||||
// DetectLineBreakCharacter detect line break character in only one inside scalar content scope.
|
||||
func DetectLineBreakCharacter(src string) string {
|
||||
nc := strings.Count(src, "\n")
|
||||
|
||||
82
vendor/github.com/goccy/go-yaml/yaml.go
generated
vendored
82
vendor/github.com/goccy/go-yaml/yaml.go
generated
vendored
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
"github.com/goccy/go-yaml/internal/errors"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// BytesMarshaler interface may be implemented by types to customize their
|
||||
@@ -58,6 +57,16 @@ type InterfaceUnmarshalerContext interface {
|
||||
UnmarshalYAML(context.Context, func(interface{}) error) error
|
||||
}
|
||||
|
||||
// NodeUnmarshaler interface is similar to BytesUnmarshaler but provide related AST node instead of raw YAML source.
|
||||
type NodeUnmarshaler interface {
|
||||
UnmarshalYAML(ast.Node) error
|
||||
}
|
||||
|
||||
// NodeUnmarshalerContext interface is similar to BytesUnmarshaler but provide related AST node instead of raw YAML source.
|
||||
type NodeUnmarshalerContext interface {
|
||||
UnmarshalYAML(context.Context, ast.Node) error
|
||||
}
|
||||
|
||||
// MapItem is an item in a MapSlice.
|
||||
type MapItem struct {
|
||||
Key, Value interface{}
|
||||
@@ -80,11 +89,11 @@ func (s MapSlice) ToMap() map[interface{}]interface{} {
|
||||
// of the generated document will reflect the structure of the value itself.
|
||||
// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
|
||||
//
|
||||
// Struct fields are only marshalled if they are exported (have an upper case
|
||||
// first letter), and are marshalled using the field name lowercased as the
|
||||
// Struct fields are only marshaled if they are exported (have an upper case
|
||||
// first letter), and are marshaled using the field name lowercased as the
|
||||
// default key. Custom keys may be defined via the "yaml" name in the field
|
||||
// tag: the content preceding the first comma is used as the key, and the
|
||||
// following comma-separated options are used to tweak the marshalling process.
|
||||
// following comma-separated options are used to tweak the marshaling process.
|
||||
// Conflicting names result in a runtime error.
|
||||
//
|
||||
// The field tag format accepted is:
|
||||
@@ -99,6 +108,13 @@ func (s MapSlice) ToMap() map[interface{}]interface{} {
|
||||
// fields are zero, unless they implement an IsZero
|
||||
// method (see the IsZeroer interface type), in which
|
||||
// case the field will be included if that method returns true.
|
||||
// Note that this definition is slightly different from the Go's
|
||||
// encoding/json 'omitempty' definition. It combines some elements
|
||||
// of 'omitempty' and 'omitzero'. See https://github.com/goccy/go-yaml/issues/695.
|
||||
//
|
||||
// omitzero The omitzero tag behaves in the same way as the interpretation of the omitzero tag in the encoding/json library.
|
||||
// 1) If the field type has an "IsZero() bool" method, that will be used to determine whether the value is zero.
|
||||
// 2) Otherwise, the value is zero if it is the zero value for its type.
|
||||
//
|
||||
// flow Marshal using a flow style (useful for structs,
|
||||
// sequences and maps).
|
||||
@@ -138,7 +154,7 @@ func MarshalWithOptions(v interface{}, opts ...EncodeOption) ([]byte, error) {
|
||||
func MarshalContext(ctx context.Context, v interface{}, opts ...EncodeOption) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := NewEncoder(&buf, opts...).EncodeContext(ctx, v); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal")
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
@@ -148,7 +164,7 @@ func ValueToNode(v interface{}, opts ...EncodeOption) (ast.Node, error) {
|
||||
var buf bytes.Buffer
|
||||
node, err := NewEncoder(&buf, opts...).EncodeToNode(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to convert value to node")
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
@@ -161,7 +177,7 @@ func ValueToNode(v interface{}, opts ...EncodeOption) (ast.Node, error) {
|
||||
// lowercased as the default key. Custom keys may be defined via the
|
||||
// "yaml" name in the field tag: the content preceding the first comma
|
||||
// is used as the key, and the following comma-separated options are
|
||||
// used to tweak the marshalling process (see Marshal).
|
||||
// used to tweak the marshaling process (see Marshal).
|
||||
// Conflicting names result in a runtime error.
|
||||
//
|
||||
// For example:
|
||||
@@ -192,7 +208,7 @@ func UnmarshalContext(ctx context.Context, data []byte, v interface{}, opts ...D
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "failed to unmarshal")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -201,7 +217,7 @@ func UnmarshalContext(ctx context.Context, data []byte, v interface{}, opts ...D
|
||||
func NodeToValue(node ast.Node, v interface{}, opts ...DecodeOption) error {
|
||||
var buf bytes.Buffer
|
||||
if err := NewDecoder(&buf, opts...).DecodeFromNode(node, v); err != nil {
|
||||
return errors.Wrapf(err, "failed to convert node to value")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -213,11 +229,9 @@ func NodeToValue(node ast.Node, v interface{}, opts ...DecodeOption) error {
|
||||
// If the third argument `inclSource` is true, the error message will
|
||||
// contain snippets of the YAML source that was used.
|
||||
func FormatError(e error, colored, inclSource bool) string {
|
||||
var pp errors.PrettyPrinter
|
||||
if xerrors.As(e, &pp) {
|
||||
var buf bytes.Buffer
|
||||
pp.PrettyPrint(&errors.Sink{&buf}, colored, inclSource)
|
||||
return buf.String()
|
||||
var yamlErr Error
|
||||
if errors.As(e, &yamlErr) {
|
||||
return yamlErr.FormatError(colored, inclSource)
|
||||
}
|
||||
|
||||
return e.Error()
|
||||
@@ -227,11 +241,11 @@ func FormatError(e error, colored, inclSource bool) string {
|
||||
func YAMLToJSON(bytes []byte) ([]byte, error) {
|
||||
var v interface{}
|
||||
if err := UnmarshalWithOptions(bytes, &v, UseOrderedMap()); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal")
|
||||
return nil, err
|
||||
}
|
||||
out, err := MarshalWithOptions(v, JSON())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal with json option")
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -240,11 +254,11 @@ func YAMLToJSON(bytes []byte) ([]byte, error) {
|
||||
func JSONToYAML(bytes []byte) ([]byte, error) {
|
||||
var v interface{}
|
||||
if err := UnmarshalWithOptions(bytes, &v, UseOrderedMap()); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal from json bytes")
|
||||
return nil, err
|
||||
}
|
||||
out, err := Marshal(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal")
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -252,8 +266,8 @@ func JSONToYAML(bytes []byte) ([]byte, error) {
|
||||
var (
|
||||
globalCustomMarshalerMu sync.Mutex
|
||||
globalCustomUnmarshalerMu sync.Mutex
|
||||
globalCustomMarshalerMap = map[reflect.Type]func(interface{}) ([]byte, error){}
|
||||
globalCustomUnmarshalerMap = map[reflect.Type]func(interface{}, []byte) error{}
|
||||
globalCustomMarshalerMap = map[reflect.Type]func(context.Context, interface{}) ([]byte, error){}
|
||||
globalCustomUnmarshalerMap = map[reflect.Type]func(context.Context, interface{}, []byte) error{}
|
||||
)
|
||||
|
||||
// RegisterCustomMarshaler overrides any encoding process for the type specified in generics.
|
||||
@@ -267,11 +281,23 @@ func RegisterCustomMarshaler[T any](marshaler func(T) ([]byte, error)) {
|
||||
defer globalCustomMarshalerMu.Unlock()
|
||||
|
||||
var typ T
|
||||
globalCustomMarshalerMap[reflect.TypeOf(typ)] = func(v interface{}) ([]byte, error) {
|
||||
globalCustomMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) {
|
||||
return marshaler(v.(T))
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCustomMarshalerContext overrides any encoding process for the type specified in generics.
|
||||
// Similar to RegisterCustomMarshalerContext, but allows passing a context to the unmarshaler function.
|
||||
func RegisterCustomMarshalerContext[T any](marshaler func(context.Context, T) ([]byte, error)) {
|
||||
globalCustomMarshalerMu.Lock()
|
||||
defer globalCustomMarshalerMu.Unlock()
|
||||
|
||||
var typ T
|
||||
globalCustomMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) {
|
||||
return marshaler(ctx, v.(T))
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCustomUnmarshaler overrides any decoding process for the type specified in generics.
|
||||
// If you want to switch the behavior for each decoder, use `CustomUnmarshaler` defined as DecodeOption.
|
||||
//
|
||||
@@ -282,7 +308,19 @@ func RegisterCustomUnmarshaler[T any](unmarshaler func(*T, []byte) error) {
|
||||
defer globalCustomUnmarshalerMu.Unlock()
|
||||
|
||||
var typ *T
|
||||
globalCustomUnmarshalerMap[reflect.TypeOf(typ)] = func(v interface{}, b []byte) error {
|
||||
globalCustomUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error {
|
||||
return unmarshaler(v.(*T), b)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCustomUnmarshalerContext overrides any decoding process for the type specified in generics.
|
||||
// Similar to RegisterCustomUnmarshalerContext, but allows passing a context to the unmarshaler function.
|
||||
func RegisterCustomUnmarshalerContext[T any](unmarshaler func(context.Context, *T, []byte) error) {
|
||||
globalCustomUnmarshalerMu.Lock()
|
||||
defer globalCustomUnmarshalerMu.Unlock()
|
||||
|
||||
var typ *T
|
||||
globalCustomUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error {
|
||||
return unmarshaler(ctx, v.(*T), b)
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
generated
vendored
6
vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
generated
vendored
@@ -1,3 +1,9 @@
|
||||
## 2.26.0
|
||||
|
||||
### Features
|
||||
|
||||
Ginkgo can now generate json-formatted reports that are compatible with the `go test` json format. Use `ginkgo --gojson-report=report.go.json`. This is not intended to be a replacement for Ginkgo's native json format which is more information rich and better models Ginkgo's test structure semantics.
|
||||
|
||||
## 2.25.3
|
||||
|
||||
### Fixes
|
||||
|
||||
10
vendor/github.com/onsi/ginkgo/v2/README.md
generated
vendored
10
vendor/github.com/onsi/ginkgo/v2/README.md
generated
vendored
@@ -113,3 +113,13 @@ Ginkgo is MIT-Licensed
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
## Sponsors
|
||||
|
||||
Sponsors commit to a [sponsorship](https://github.com/sponsors/onsi) for a year. If you're an organization that makes use of Ginkgo please consider becoming a sponsor!
|
||||
|
||||
<p style="font-size:21px; color:black;">Browser testing via
|
||||
<a href="https://www.lambdatest.com/" target="_blank">
|
||||
<img src="https://www.lambdatest.com/blue-logo.png" style="vertical-align: middle;" width="250" height="45" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
3
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go
generated
vendored
3
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go
generated
vendored
@@ -90,6 +90,9 @@ func FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIC
|
||||
if reporterConfig.JSONReport != "" {
|
||||
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JSONReport, GenerateFunc: reporters.GenerateJSONReport, MergeFunc: reporters.MergeAndCleanupJSONReports})
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.GoJSONReport, GenerateFunc: reporters.GenerateGoTestJSONReport, MergeFunc: reporters.MergeAndCleanupGoTestJSONReports})
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JUnitReport, GenerateFunc: reporters.GenerateJUnitReport, MergeFunc: reporters.MergeAndCleanupJUnitReports})
|
||||
}
|
||||
|
||||
6
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
generated
vendored
6
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
generated
vendored
@@ -107,6 +107,9 @@ func runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig t
|
||||
if reporterConfig.JSONReport != "" {
|
||||
reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
reporterConfig.GoJSONReport = AbsPathForGeneratedAsset(reporterConfig.GoJSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)
|
||||
}
|
||||
@@ -179,6 +182,9 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
|
||||
if reporterConfig.JSONReport != "" {
|
||||
reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
reporterConfig.GoJSONReport = AbsPathForGeneratedAsset(reporterConfig.GoJSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)
|
||||
}
|
||||
|
||||
1
vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
generated
vendored
1
vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
generated
vendored
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
_ "go.uber.org/automaxprocs"
|
||||
"github.com/onsi/ginkgo/v2/ginkgo/build"
|
||||
"github.com/onsi/ginkgo/v2/ginkgo/command"
|
||||
"github.com/onsi/ginkgo/v2/ginkgo/generators"
|
||||
|
||||
8
vendor/github.com/onsi/ginkgo/v2/ginkgo/maxprocs.go
generated
vendored
Normal file
8
vendor/github.com/onsi/ginkgo/v2/ginkgo/maxprocs.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build !go1.25
|
||||
// +build !go1.25
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "go.uber.org/automaxprocs"
|
||||
)
|
||||
158
vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
generated
vendored
Normal file
158
vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
package reporters
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
func ptr[T any](in T) *T {
|
||||
return &in
|
||||
}
|
||||
|
||||
type encoder interface {
|
||||
Encode(v any) error
|
||||
}
|
||||
|
||||
// gojsonEvent matches the format from go internals
|
||||
// https://github.com/golang/go/blob/master/src/cmd/internal/test2json/test2json.go#L31-L41
|
||||
// https://pkg.go.dev/cmd/test2json
|
||||
type gojsonEvent struct {
|
||||
Time *time.Time `json:",omitempty"`
|
||||
Action GoJSONAction
|
||||
Package string `json:",omitempty"`
|
||||
Test string `json:",omitempty"`
|
||||
Elapsed *float64 `json:",omitempty"`
|
||||
Output *string `json:",omitempty"`
|
||||
FailedBuild string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type GoJSONAction string
|
||||
|
||||
const (
|
||||
// start - the test binary is about to be executed
|
||||
GoJSONStart GoJSONAction = "start"
|
||||
// run - the test has started running
|
||||
GoJSONRun GoJSONAction = "run"
|
||||
// pause - the test has been paused
|
||||
GoJSONPause GoJSONAction = "pause"
|
||||
// cont - the test has continued running
|
||||
GoJSONCont GoJSONAction = "cont"
|
||||
// pass - the test passed
|
||||
GoJSONPass GoJSONAction = "pass"
|
||||
// bench - the benchmark printed log output but did not fail
|
||||
GoJSONBench GoJSONAction = "bench"
|
||||
// fail - the test or benchmark failed
|
||||
GoJSONFail GoJSONAction = "fail"
|
||||
// output - the test printed output
|
||||
GoJSONOutput GoJSONAction = "output"
|
||||
// skip - the test was skipped or the package contained no tests
|
||||
GoJSONSkip GoJSONAction = "skip"
|
||||
)
|
||||
|
||||
func goJSONActionFromSpecState(state types.SpecState) GoJSONAction {
|
||||
switch state {
|
||||
case types.SpecStateInvalid:
|
||||
return GoJSONFail
|
||||
case types.SpecStatePending:
|
||||
return GoJSONSkip
|
||||
case types.SpecStateSkipped:
|
||||
return GoJSONSkip
|
||||
case types.SpecStatePassed:
|
||||
return GoJSONPass
|
||||
case types.SpecStateFailed:
|
||||
return GoJSONFail
|
||||
case types.SpecStateAborted:
|
||||
return GoJSONFail
|
||||
case types.SpecStatePanicked:
|
||||
return GoJSONFail
|
||||
case types.SpecStateInterrupted:
|
||||
return GoJSONFail
|
||||
case types.SpecStateTimedout:
|
||||
return GoJSONFail
|
||||
default:
|
||||
panic("unexpected state should not happen")
|
||||
}
|
||||
}
|
||||
|
||||
// gojsonReport wraps types.Report and calcualtes extra fields requires by gojson
|
||||
type gojsonReport struct {
|
||||
o types.Report
|
||||
// Extra calculated fields
|
||||
goPkg string
|
||||
elapsed float64
|
||||
}
|
||||
|
||||
func newReport(in types.Report) *gojsonReport {
|
||||
return &gojsonReport{
|
||||
o: in,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *gojsonReport) Fill() error {
|
||||
// NOTE: could the types.Report include the go package name?
|
||||
goPkg, err := suitePathToPkg(r.o.SuitePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.goPkg = goPkg
|
||||
r.elapsed = r.o.RunTime.Seconds()
|
||||
return nil
|
||||
}
|
||||
|
||||
// gojsonSpecReport wraps types.SpecReport and calculates extra fields required by gojson
|
||||
type gojsonSpecReport struct {
|
||||
o types.SpecReport
|
||||
// extra calculated fields
|
||||
testName string
|
||||
elapsed float64
|
||||
action GoJSONAction
|
||||
}
|
||||
|
||||
func newSpecReport(in types.SpecReport) *gojsonSpecReport {
|
||||
return &gojsonSpecReport{
|
||||
o: in,
|
||||
}
|
||||
}
|
||||
|
||||
func (sr *gojsonSpecReport) Fill() error {
|
||||
sr.elapsed = sr.o.RunTime.Seconds()
|
||||
sr.testName = createTestName(sr.o)
|
||||
sr.action = goJSONActionFromSpecState(sr.o.State)
|
||||
return nil
|
||||
}
|
||||
|
||||
func suitePathToPkg(dir string) (string, error) {
|
||||
cfg := &packages.Config{
|
||||
Mode: packages.NeedFiles | packages.NeedSyntax,
|
||||
}
|
||||
pkgs, err := packages.Load(cfg, dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(pkgs) != 1 {
|
||||
return "", errors.New("error")
|
||||
}
|
||||
return pkgs[0].ID, nil
|
||||
}
|
||||
|
||||
func createTestName(spec types.SpecReport) string {
|
||||
name := fmt.Sprintf("[%s]", spec.LeafNodeType)
|
||||
if spec.FullText() != "" {
|
||||
name = name + " " + spec.FullText()
|
||||
}
|
||||
labels := spec.Labels()
|
||||
if len(labels) > 0 {
|
||||
name = name + " [" + strings.Join(labels, ", ") + "]"
|
||||
}
|
||||
semVerConstraints := spec.SemVerConstraints()
|
||||
if len(semVerConstraints) > 0 {
|
||||
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
|
||||
}
|
||||
name = strings.TrimSpace(name)
|
||||
return name
|
||||
}
|
||||
111
vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_event_writer.go
generated
vendored
Normal file
111
vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_event_writer.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
package reporters
|
||||
|
||||
type GoJSONEventWriter struct {
|
||||
enc encoder
|
||||
specSystemErrFn specSystemExtractFn
|
||||
specSystemOutFn specSystemExtractFn
|
||||
}
|
||||
|
||||
func NewGoJSONEventWriter(enc encoder, errFn specSystemExtractFn, outFn specSystemExtractFn) *GoJSONEventWriter {
|
||||
return &GoJSONEventWriter{
|
||||
enc: enc,
|
||||
specSystemErrFn: errFn,
|
||||
specSystemOutFn: outFn,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) writeEvent(e *gojsonEvent) error {
|
||||
return r.enc.Encode(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSuiteStart(report *gojsonReport) error {
|
||||
e := &gojsonEvent{
|
||||
Time: &report.o.StartTime,
|
||||
Action: GoJSONStart,
|
||||
Package: report.goPkg,
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSuiteResult(report *gojsonReport) error {
|
||||
var action GoJSONAction
|
||||
switch {
|
||||
case report.o.PreRunStats.SpecsThatWillRun == 0:
|
||||
action = GoJSONSkip
|
||||
case report.o.SuiteSucceeded:
|
||||
action = GoJSONPass
|
||||
default:
|
||||
action = GoJSONFail
|
||||
}
|
||||
e := &gojsonEvent{
|
||||
Time: &report.o.EndTime,
|
||||
Action: action,
|
||||
Package: report.goPkg,
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
Elapsed: ptr(report.elapsed),
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSpecStart(report *gojsonReport, specReport *gojsonSpecReport) error {
|
||||
e := &gojsonEvent{
|
||||
Time: &specReport.o.StartTime,
|
||||
Action: GoJSONRun,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSpecOut(report *gojsonReport, specReport *gojsonSpecReport) error {
|
||||
events := []*gojsonEvent{}
|
||||
|
||||
stdErr := r.specSystemErrFn(specReport.o)
|
||||
if stdErr != "" {
|
||||
events = append(events, &gojsonEvent{
|
||||
Time: &specReport.o.EndTime,
|
||||
Action: GoJSONOutput,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Output: ptr(stdErr),
|
||||
FailedBuild: "",
|
||||
})
|
||||
}
|
||||
stdOut := r.specSystemOutFn(specReport.o)
|
||||
if stdOut != "" {
|
||||
events = append(events, &gojsonEvent{
|
||||
Time: &specReport.o.EndTime,
|
||||
Action: GoJSONOutput,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Output: ptr(stdOut),
|
||||
FailedBuild: "",
|
||||
})
|
||||
}
|
||||
|
||||
for _, ev := range events {
|
||||
err := r.writeEvent(ev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSpecResult(report *gojsonReport, specReport *gojsonSpecReport) error {
|
||||
e := &gojsonEvent{
|
||||
Time: &specReport.o.EndTime,
|
||||
Action: specReport.action,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Elapsed: ptr(specReport.elapsed),
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
45
vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_reporter.go
generated
vendored
Normal file
45
vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_reporter.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package reporters
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
)
|
||||
|
||||
type GoJSONReporter struct {
|
||||
ev *GoJSONEventWriter
|
||||
}
|
||||
|
||||
type specSystemExtractFn func (spec types.SpecReport) string
|
||||
|
||||
func NewGoJSONReporter(enc encoder, errFn specSystemExtractFn, outFn specSystemExtractFn) *GoJSONReporter {
|
||||
return &GoJSONReporter{
|
||||
ev: NewGoJSONEventWriter(enc, errFn, outFn),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *GoJSONReporter) Write(originalReport types.Report) error {
|
||||
// suite start events
|
||||
report := newReport(originalReport)
|
||||
err := report.Fill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.ev.WriteSuiteStart(report)
|
||||
for _, originalSpecReport := range originalReport.SpecReports {
|
||||
specReport := newSpecReport(originalSpecReport)
|
||||
err := specReport.Fill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if specReport.o.LeafNodeType == types.NodeTypeIt {
|
||||
// handle any It leaf node as a spec
|
||||
r.ev.WriteSpecStart(report, specReport)
|
||||
r.ev.WriteSpecOut(report, specReport)
|
||||
r.ev.WriteSpecResult(report, specReport)
|
||||
} else {
|
||||
// handle any other leaf node as generic output
|
||||
r.ev.WriteSpecOut(report, specReport)
|
||||
}
|
||||
}
|
||||
r.ev.WriteSuiteResult(report)
|
||||
return nil
|
||||
}
|
||||
61
vendor/github.com/onsi/ginkgo/v2/reporters/gojson_report.go
generated
vendored
Normal file
61
vendor/github.com/onsi/ginkgo/v2/reporters/gojson_report.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package reporters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/internal/reporters"
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
)
|
||||
|
||||
// GenerateGoTestJSONReport produces a JSON-formatted in the test2json format used by `go test -json`
|
||||
func GenerateGoTestJSONReport(report types.Report, destination string) error {
|
||||
// walk report and generate test2json-compatible objects
|
||||
// JSON-encode the objects into filename
|
||||
if err := os.MkdirAll(path.Dir(destination), 0770); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
enc := json.NewEncoder(f)
|
||||
r := reporters.NewGoJSONReporter(
|
||||
enc,
|
||||
systemErrForUnstructuredReporters,
|
||||
systemOutForUnstructuredReporters,
|
||||
)
|
||||
return r.Write(report)
|
||||
}
|
||||
|
||||
// MergeJSONReports produces a single JSON-formatted report at the passed in destination by merging the JSON-formatted reports provided in sources
|
||||
// It skips over reports that fail to decode but reports on them via the returned messages []string
|
||||
func MergeAndCleanupGoTestJSONReports(sources []string, destination string) ([]string, error) {
|
||||
messages := []string{}
|
||||
if err := os.MkdirAll(path.Dir(destination), 0770); err != nil {
|
||||
return messages, err
|
||||
}
|
||||
f, err := os.Create(destination)
|
||||
if err != nil {
|
||||
return messages, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for _, source := range sources {
|
||||
data, err := os.ReadFile(source)
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("Could not open %s:\n%s", source, err.Error()))
|
||||
continue
|
||||
}
|
||||
_, err = f.Write(data)
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("Could not write to %s:\n%s", destination, err.Error()))
|
||||
continue
|
||||
}
|
||||
os.Remove(source)
|
||||
}
|
||||
return messages, nil
|
||||
}
|
||||
11
vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
generated
vendored
11
vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
generated
vendored
@@ -165,7 +165,7 @@ ReportAfterSuite nodes must be created at the top-level (i.e. not nested in a Co
|
||||
When running in parallel, Ginkgo ensures that only one of the parallel nodes runs the ReportAfterSuite and that it is passed a report that is aggregated across
|
||||
all parallel nodes
|
||||
|
||||
In addition to using ReportAfterSuite to programmatically generate suite reports, you can also generate JSON, JUnit, and Teamcity formatted reports using the --json-report, --junit-report, and --teamcity-report ginkgo CLI flags.
|
||||
In addition to using ReportAfterSuite to programmatically generate suite reports, you can also generate JSON, GoJSON, JUnit, and Teamcity formatted reports using the --json-report, --gojson-report, --junit-report, and --teamcity-report ginkgo CLI flags.
|
||||
|
||||
You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure.
|
||||
You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
|
||||
@@ -188,6 +188,12 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
|
||||
Fail(fmt.Sprintf("Failed to generate JSON report:\n%s", err.Error()))
|
||||
}
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
err := reporters.GenerateGoTestJSONReport(report, reporterConfig.GoJSONReport)
|
||||
if err != nil {
|
||||
Fail(fmt.Sprintf("Failed to generate Go JSON report:\n%s", err.Error()))
|
||||
}
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
err := reporters.GenerateJUnitReport(report, reporterConfig.JUnitReport)
|
||||
if err != nil {
|
||||
@@ -206,6 +212,9 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
|
||||
if reporterConfig.JSONReport != "" {
|
||||
flags = append(flags, "--json-report")
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
flags = append(flags, "--gojson-report")
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
flags = append(flags, "--junit-report")
|
||||
}
|
||||
|
||||
5
vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
5
vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
@@ -96,6 +96,7 @@ type ReporterConfig struct {
|
||||
ForceNewlines bool
|
||||
|
||||
JSONReport string
|
||||
GoJSONReport string
|
||||
JUnitReport string
|
||||
TeamcityReport string
|
||||
}
|
||||
@@ -112,7 +113,7 @@ func (rc ReporterConfig) Verbosity() VerbosityLevel {
|
||||
}
|
||||
|
||||
func (rc ReporterConfig) WillGenerateReport() bool {
|
||||
return rc.JSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != ""
|
||||
return rc.JSONReport != "" || rc.GoJSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != ""
|
||||
}
|
||||
|
||||
func NewDefaultReporterConfig() ReporterConfig {
|
||||
@@ -359,6 +360,8 @@ var ReporterConfigFlags = GinkgoFlags{
|
||||
|
||||
{KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output",
|
||||
Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},
|
||||
{KeyPath: "R.GoJSONReport", Name: "gojson-report", UsageArgument: "filename.json", SectionKey: "output",
|
||||
Usage: "If set, Ginkgo will generate a Go JSON-formatted test report at the specified location."},
|
||||
{KeyPath: "R.JUnitReport", Name: "junit-report", UsageArgument: "filename.xml", SectionKey: "output", DeprecatedName: "reportFile", DeprecatedDocLink: "improved-reporting-infrastructure",
|
||||
Usage: "If set, Ginkgo will generate a conformant junit test report in the specified file."},
|
||||
{KeyPath: "R.TeamcityReport", Name: "teamcity-report", UsageArgument: "filename", SectionKey: "output",
|
||||
|
||||
2
vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.25.3"
|
||||
const VERSION = "2.26.0"
|
||||
|
||||
27
vendor/golang.org/x/xerrors/LICENSE
generated
vendored
27
vendor/golang.org/x/xerrors/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2019 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.
|
||||
22
vendor/golang.org/x/xerrors/PATENTS
generated
vendored
22
vendor/golang.org/x/xerrors/PATENTS
generated
vendored
@@ -1,22 +0,0 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
2
vendor/golang.org/x/xerrors/README
generated
vendored
2
vendor/golang.org/x/xerrors/README
generated
vendored
@@ -1,2 +0,0 @@
|
||||
This repository holds the transition packages for the new Go 1.13 error values.
|
||||
See golang.org/design/29934-error-values.
|
||||
193
vendor/golang.org/x/xerrors/adaptor.go
generated
vendored
193
vendor/golang.org/x/xerrors/adaptor.go
generated
vendored
@@ -1,193 +0,0 @@
|
||||
// Copyright 2018 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 xerrors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// FormatError calls the FormatError method of f with an errors.Printer
|
||||
// configured according to s and verb, and writes the result to s.
|
||||
func FormatError(f Formatter, s fmt.State, verb rune) {
|
||||
// Assuming this function is only called from the Format method, and given
|
||||
// that FormatError takes precedence over Format, it cannot be called from
|
||||
// any package that supports errors.Formatter. It is therefore safe to
|
||||
// disregard that State may be a specific printer implementation and use one
|
||||
// of our choice instead.
|
||||
|
||||
// limitations: does not support printing error as Go struct.
|
||||
|
||||
var (
|
||||
sep = " " // separator before next error
|
||||
p = &state{State: s}
|
||||
direct = true
|
||||
)
|
||||
|
||||
var err error = f
|
||||
|
||||
switch verb {
|
||||
// Note that this switch must match the preference order
|
||||
// for ordinary string printing (%#v before %+v, and so on).
|
||||
|
||||
case 'v':
|
||||
if s.Flag('#') {
|
||||
if stringer, ok := err.(fmt.GoStringer); ok {
|
||||
io.WriteString(&p.buf, stringer.GoString())
|
||||
goto exit
|
||||
}
|
||||
// proceed as if it were %v
|
||||
} else if s.Flag('+') {
|
||||
p.printDetail = true
|
||||
sep = "\n - "
|
||||
}
|
||||
case 's':
|
||||
case 'q', 'x', 'X':
|
||||
// Use an intermediate buffer in the rare cases that precision,
|
||||
// truncation, or one of the alternative verbs (q, x, and X) are
|
||||
// specified.
|
||||
direct = false
|
||||
|
||||
default:
|
||||
p.buf.WriteString("%!")
|
||||
p.buf.WriteRune(verb)
|
||||
p.buf.WriteByte('(')
|
||||
switch {
|
||||
case err != nil:
|
||||
p.buf.WriteString(reflect.TypeOf(f).String())
|
||||
default:
|
||||
p.buf.WriteString("<nil>")
|
||||
}
|
||||
p.buf.WriteByte(')')
|
||||
io.Copy(s, &p.buf)
|
||||
return
|
||||
}
|
||||
|
||||
loop:
|
||||
for {
|
||||
switch v := err.(type) {
|
||||
case Formatter:
|
||||
err = v.FormatError((*printer)(p))
|
||||
case fmt.Formatter:
|
||||
v.Format(p, 'v')
|
||||
break loop
|
||||
default:
|
||||
io.WriteString(&p.buf, v.Error())
|
||||
break loop
|
||||
}
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if p.needColon || !p.printDetail {
|
||||
p.buf.WriteByte(':')
|
||||
p.needColon = false
|
||||
}
|
||||
p.buf.WriteString(sep)
|
||||
p.inDetail = false
|
||||
p.needNewline = false
|
||||
}
|
||||
|
||||
exit:
|
||||
width, okW := s.Width()
|
||||
prec, okP := s.Precision()
|
||||
|
||||
if !direct || (okW && width > 0) || okP {
|
||||
// Construct format string from State s.
|
||||
format := []byte{'%'}
|
||||
if s.Flag('-') {
|
||||
format = append(format, '-')
|
||||
}
|
||||
if s.Flag('+') {
|
||||
format = append(format, '+')
|
||||
}
|
||||
if s.Flag(' ') {
|
||||
format = append(format, ' ')
|
||||
}
|
||||
if okW {
|
||||
format = strconv.AppendInt(format, int64(width), 10)
|
||||
}
|
||||
if okP {
|
||||
format = append(format, '.')
|
||||
format = strconv.AppendInt(format, int64(prec), 10)
|
||||
}
|
||||
format = append(format, string(verb)...)
|
||||
fmt.Fprintf(s, string(format), p.buf.String())
|
||||
} else {
|
||||
io.Copy(s, &p.buf)
|
||||
}
|
||||
}
|
||||
|
||||
var detailSep = []byte("\n ")
|
||||
|
||||
// state tracks error printing state. It implements fmt.State.
|
||||
type state struct {
|
||||
fmt.State
|
||||
buf bytes.Buffer
|
||||
|
||||
printDetail bool
|
||||
inDetail bool
|
||||
needColon bool
|
||||
needNewline bool
|
||||
}
|
||||
|
||||
func (s *state) Write(b []byte) (n int, err error) {
|
||||
if s.printDetail {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if s.inDetail && s.needColon {
|
||||
s.needNewline = true
|
||||
if b[0] == '\n' {
|
||||
b = b[1:]
|
||||
}
|
||||
}
|
||||
k := 0
|
||||
for i, c := range b {
|
||||
if s.needNewline {
|
||||
if s.inDetail && s.needColon {
|
||||
s.buf.WriteByte(':')
|
||||
s.needColon = false
|
||||
}
|
||||
s.buf.Write(detailSep)
|
||||
s.needNewline = false
|
||||
}
|
||||
if c == '\n' {
|
||||
s.buf.Write(b[k:i])
|
||||
k = i + 1
|
||||
s.needNewline = true
|
||||
}
|
||||
}
|
||||
s.buf.Write(b[k:])
|
||||
if !s.inDetail {
|
||||
s.needColon = true
|
||||
}
|
||||
} else if !s.inDetail {
|
||||
s.buf.Write(b)
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// printer wraps a state to implement an xerrors.Printer.
|
||||
type printer state
|
||||
|
||||
func (s *printer) Print(args ...interface{}) {
|
||||
if !s.inDetail || s.printDetail {
|
||||
fmt.Fprint((*state)(s), args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *printer) Printf(format string, args ...interface{}) {
|
||||
if !s.inDetail || s.printDetail {
|
||||
fmt.Fprintf((*state)(s), format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *printer) Detail() bool {
|
||||
s.inDetail = true
|
||||
return s.printDetail
|
||||
}
|
||||
1
vendor/golang.org/x/xerrors/codereview.cfg
generated
vendored
1
vendor/golang.org/x/xerrors/codereview.cfg
generated
vendored
@@ -1 +0,0 @@
|
||||
issuerepo: golang/go
|
||||
23
vendor/golang.org/x/xerrors/doc.go
generated
vendored
23
vendor/golang.org/x/xerrors/doc.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
// Copyright 2019 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 xerrors implements functions to manipulate errors.
|
||||
//
|
||||
// This package is based on the Go 2 proposal for error values:
|
||||
//
|
||||
// https://golang.org/design/29934-error-values
|
||||
//
|
||||
// These functions were incorporated into the standard library's errors package
|
||||
// in Go 1.13:
|
||||
// - Is
|
||||
// - As
|
||||
// - Unwrap
|
||||
//
|
||||
// Also, Errorf's %w verb was incorporated into fmt.Errorf.
|
||||
//
|
||||
// Use this package to get equivalent behavior in all supported Go versions.
|
||||
//
|
||||
// No other features of this package were included in Go 1.13, and at present
|
||||
// there are no plans to include any of them.
|
||||
package xerrors // import "golang.org/x/xerrors"
|
||||
33
vendor/golang.org/x/xerrors/errors.go
generated
vendored
33
vendor/golang.org/x/xerrors/errors.go
generated
vendored
@@ -1,33 +0,0 @@
|
||||
// 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.
|
||||
|
||||
package xerrors
|
||||
|
||||
import "fmt"
|
||||
|
||||
// errorString is a trivial implementation of error.
|
||||
type errorString struct {
|
||||
s string
|
||||
frame Frame
|
||||
}
|
||||
|
||||
// New returns an error that formats as the given text.
|
||||
//
|
||||
// The returned error contains a Frame set to the caller's location and
|
||||
// implements Formatter to show this information when printed with details.
|
||||
func New(text string) error {
|
||||
return &errorString{text, Caller(1)}
|
||||
}
|
||||
|
||||
func (e *errorString) Error() string {
|
||||
return e.s
|
||||
}
|
||||
|
||||
func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) }
|
||||
|
||||
func (e *errorString) FormatError(p Printer) (next error) {
|
||||
p.Print(e.s)
|
||||
e.frame.Format(p)
|
||||
return nil
|
||||
}
|
||||
190
vendor/golang.org/x/xerrors/fmt.go
generated
vendored
190
vendor/golang.org/x/xerrors/fmt.go
generated
vendored
@@ -1,190 +0,0 @@
|
||||
// Copyright 2018 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 xerrors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/xerrors/internal"
|
||||
)
|
||||
|
||||
const percentBangString = "%!"
|
||||
|
||||
// Errorf formats according to a format specifier and returns the string as a
|
||||
// value that satisfies error.
|
||||
//
|
||||
// The returned error includes the file and line number of the caller when
|
||||
// formatted with additional detail enabled. If the last argument is an error
|
||||
// the returned error's Format method will return it if the format string ends
|
||||
// with ": %s", ": %v", or ": %w". If the last argument is an error and the
|
||||
// format string ends with ": %w", the returned error implements an Unwrap
|
||||
// method returning it.
|
||||
//
|
||||
// If the format specifier includes a %w verb with an error operand in a
|
||||
// position other than at the end, the returned error will still implement an
|
||||
// Unwrap method returning the operand, but the error's Format method will not
|
||||
// return the wrapped error.
|
||||
//
|
||||
// It is invalid to include more than one %w verb or to supply it with an
|
||||
// operand that does not implement the error interface. The %w verb is otherwise
|
||||
// a synonym for %v.
|
||||
//
|
||||
// Note that as of Go 1.13, the fmt.Errorf function will do error formatting,
|
||||
// but it will not capture a stack backtrace.
|
||||
func Errorf(format string, a ...interface{}) error {
|
||||
format = formatPlusW(format)
|
||||
// Support a ": %[wsv]" suffix, which works well with xerrors.Formatter.
|
||||
wrap := strings.HasSuffix(format, ": %w")
|
||||
idx, format2, ok := parsePercentW(format)
|
||||
percentWElsewhere := !wrap && idx >= 0
|
||||
if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) {
|
||||
err := errorAt(a, len(a)-1)
|
||||
if err == nil {
|
||||
return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)}
|
||||
}
|
||||
// TODO: this is not entirely correct. The error value could be
|
||||
// printed elsewhere in format if it mixes numbered with unnumbered
|
||||
// substitutions. With relatively small changes to doPrintf we can
|
||||
// have it optionally ignore extra arguments and pass the argument
|
||||
// list in its entirety.
|
||||
msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
|
||||
frame := Frame{}
|
||||
if internal.EnableTrace {
|
||||
frame = Caller(1)
|
||||
}
|
||||
if wrap {
|
||||
return &wrapError{msg, err, frame}
|
||||
}
|
||||
return &noWrapError{msg, err, frame}
|
||||
}
|
||||
// Support %w anywhere.
|
||||
// TODO: don't repeat the wrapped error's message when %w occurs in the middle.
|
||||
msg := fmt.Sprintf(format2, a...)
|
||||
if idx < 0 {
|
||||
return &noWrapError{msg, nil, Caller(1)}
|
||||
}
|
||||
err := errorAt(a, idx)
|
||||
if !ok || err == nil {
|
||||
// Too many %ws or argument of %w is not an error. Approximate the Go
|
||||
// 1.13 fmt.Errorf message.
|
||||
return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)}
|
||||
}
|
||||
frame := Frame{}
|
||||
if internal.EnableTrace {
|
||||
frame = Caller(1)
|
||||
}
|
||||
return &wrapError{msg, err, frame}
|
||||
}
|
||||
|
||||
func errorAt(args []interface{}, i int) error {
|
||||
if i < 0 || i >= len(args) {
|
||||
return nil
|
||||
}
|
||||
err, ok := args[i].(error)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// formatPlusW is used to avoid the vet check that will barf at %w.
|
||||
func formatPlusW(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
// Return the index of the only %w in format, or -1 if none.
|
||||
// Also return a rewritten format string with %w replaced by %v, and
|
||||
// false if there is more than one %w.
|
||||
// TODO: handle "%[N]w".
|
||||
func parsePercentW(format string) (idx int, newFormat string, ok bool) {
|
||||
// Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go.
|
||||
idx = -1
|
||||
ok = true
|
||||
n := 0
|
||||
sz := 0
|
||||
var isW bool
|
||||
for i := 0; i < len(format); i += sz {
|
||||
if format[i] != '%' {
|
||||
sz = 1
|
||||
continue
|
||||
}
|
||||
// "%%" is not a format directive.
|
||||
if i+1 < len(format) && format[i+1] == '%' {
|
||||
sz = 2
|
||||
continue
|
||||
}
|
||||
sz, isW = parsePrintfVerb(format[i:])
|
||||
if isW {
|
||||
if idx >= 0 {
|
||||
ok = false
|
||||
} else {
|
||||
idx = n
|
||||
}
|
||||
// "Replace" the last character, the 'w', with a 'v'.
|
||||
p := i + sz - 1
|
||||
format = format[:p] + "v" + format[p+1:]
|
||||
}
|
||||
n++
|
||||
}
|
||||
return idx, format, ok
|
||||
}
|
||||
|
||||
// Parse the printf verb starting with a % at s[0].
|
||||
// Return how many bytes it occupies and whether the verb is 'w'.
|
||||
func parsePrintfVerb(s string) (int, bool) {
|
||||
// Assume only that the directive is a sequence of non-letters followed by a single letter.
|
||||
sz := 0
|
||||
var r rune
|
||||
for i := 1; i < len(s); i += sz {
|
||||
r, sz = utf8.DecodeRuneInString(s[i:])
|
||||
if unicode.IsLetter(r) {
|
||||
return i + sz, r == 'w'
|
||||
}
|
||||
}
|
||||
return len(s), false
|
||||
}
|
||||
|
||||
type noWrapError struct {
|
||||
msg string
|
||||
err error
|
||||
frame Frame
|
||||
}
|
||||
|
||||
func (e *noWrapError) Error() string {
|
||||
return fmt.Sprint(e)
|
||||
}
|
||||
|
||||
func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }
|
||||
|
||||
func (e *noWrapError) FormatError(p Printer) (next error) {
|
||||
p.Print(e.msg)
|
||||
e.frame.Format(p)
|
||||
return e.err
|
||||
}
|
||||
|
||||
type wrapError struct {
|
||||
msg string
|
||||
err error
|
||||
frame Frame
|
||||
}
|
||||
|
||||
func (e *wrapError) Error() string {
|
||||
return fmt.Sprint(e)
|
||||
}
|
||||
|
||||
func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }
|
||||
|
||||
func (e *wrapError) FormatError(p Printer) (next error) {
|
||||
p.Print(e.msg)
|
||||
e.frame.Format(p)
|
||||
return e.err
|
||||
}
|
||||
|
||||
func (e *wrapError) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
34
vendor/golang.org/x/xerrors/format.go
generated
vendored
34
vendor/golang.org/x/xerrors/format.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
// Copyright 2018 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 xerrors
|
||||
|
||||
// A Formatter formats error messages.
|
||||
type Formatter interface {
|
||||
error
|
||||
|
||||
// FormatError prints the receiver's first error and returns the next error in
|
||||
// the error chain, if any.
|
||||
FormatError(p Printer) (next error)
|
||||
}
|
||||
|
||||
// A Printer formats error messages.
|
||||
//
|
||||
// The most common implementation of Printer is the one provided by package fmt
|
||||
// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message
|
||||
// typically provide their own implementations.
|
||||
type Printer interface {
|
||||
// Print appends args to the message output.
|
||||
Print(args ...interface{})
|
||||
|
||||
// Printf writes a formatted string.
|
||||
Printf(format string, args ...interface{})
|
||||
|
||||
// Detail reports whether error detail is requested.
|
||||
// After the first call to Detail, all text written to the Printer
|
||||
// is formatted as additional detail, or ignored when
|
||||
// detail has not been requested.
|
||||
// If Detail returns false, the caller can avoid printing the detail at all.
|
||||
Detail() bool
|
||||
}
|
||||
56
vendor/golang.org/x/xerrors/frame.go
generated
vendored
56
vendor/golang.org/x/xerrors/frame.go
generated
vendored
@@ -1,56 +0,0 @@
|
||||
// Copyright 2018 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 xerrors
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// A Frame contains part of a call stack.
|
||||
type Frame struct {
|
||||
// Make room for three PCs: the one we were asked for, what it called,
|
||||
// and possibly a PC for skipPleaseUseCallersFrames. See:
|
||||
// https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169
|
||||
frames [3]uintptr
|
||||
}
|
||||
|
||||
// Caller returns a Frame that describes a frame on the caller's stack.
|
||||
// The argument skip is the number of frames to skip over.
|
||||
// Caller(0) returns the frame for the caller of Caller.
|
||||
func Caller(skip int) Frame {
|
||||
var s Frame
|
||||
runtime.Callers(skip+1, s.frames[:])
|
||||
return s
|
||||
}
|
||||
|
||||
// location reports the file, line, and function of a frame.
|
||||
//
|
||||
// The returned function may be "" even if file and line are not.
|
||||
func (f Frame) location() (function, file string, line int) {
|
||||
frames := runtime.CallersFrames(f.frames[:])
|
||||
if _, ok := frames.Next(); !ok {
|
||||
return "", "", 0
|
||||
}
|
||||
fr, ok := frames.Next()
|
||||
if !ok {
|
||||
return "", "", 0
|
||||
}
|
||||
return fr.Function, fr.File, fr.Line
|
||||
}
|
||||
|
||||
// Format prints the stack as error detail.
|
||||
// It should be called from an error's Format implementation
|
||||
// after printing any other error detail.
|
||||
func (f Frame) Format(p Printer) {
|
||||
if p.Detail() {
|
||||
function, file, line := f.location()
|
||||
if function != "" {
|
||||
p.Printf("%s\n ", function)
|
||||
}
|
||||
if file != "" {
|
||||
p.Printf("%s:%d\n", file, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
8
vendor/golang.org/x/xerrors/internal/internal.go
generated
vendored
8
vendor/golang.org/x/xerrors/internal/internal.go
generated
vendored
@@ -1,8 +0,0 @@
|
||||
// Copyright 2018 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 internal
|
||||
|
||||
// EnableTrace indicates whether stack information should be recorded in errors.
|
||||
var EnableTrace = true
|
||||
112
vendor/golang.org/x/xerrors/wrap.go
generated
vendored
112
vendor/golang.org/x/xerrors/wrap.go
generated
vendored
@@ -1,112 +0,0 @@
|
||||
// Copyright 2018 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 xerrors
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// A Wrapper provides context around another error.
|
||||
type Wrapper interface {
|
||||
// Unwrap returns the next error in the error chain.
|
||||
// If there is no next error, Unwrap returns nil.
|
||||
Unwrap() error
|
||||
}
|
||||
|
||||
// Opaque returns an error with the same error formatting as err
|
||||
// but that does not match err and cannot be unwrapped.
|
||||
func Opaque(err error) error {
|
||||
return noWrapper{err}
|
||||
}
|
||||
|
||||
type noWrapper struct {
|
||||
error
|
||||
}
|
||||
|
||||
func (e noWrapper) FormatError(p Printer) (next error) {
|
||||
if f, ok := e.error.(Formatter); ok {
|
||||
return f.FormatError(p)
|
||||
}
|
||||
p.Print(e.error)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unwrap returns the result of calling the Unwrap method on err, if err implements
|
||||
// Unwrap. Otherwise, Unwrap returns nil.
|
||||
//
|
||||
// Deprecated: As of Go 1.13, use errors.Unwrap instead.
|
||||
func Unwrap(err error) error {
|
||||
u, ok := err.(Wrapper)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return u.Unwrap()
|
||||
}
|
||||
|
||||
// Is reports whether any error in err's chain matches target.
|
||||
//
|
||||
// An error is considered to match a target if it is equal to that target or if
|
||||
// it implements a method Is(error) bool such that Is(target) returns true.
|
||||
//
|
||||
// Deprecated: As of Go 1.13, use errors.Is instead.
|
||||
func Is(err, target error) bool {
|
||||
if target == nil {
|
||||
return err == target
|
||||
}
|
||||
|
||||
isComparable := reflect.TypeOf(target).Comparable()
|
||||
for {
|
||||
if isComparable && err == target {
|
||||
return true
|
||||
}
|
||||
if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
|
||||
return true
|
||||
}
|
||||
// TODO: consider supporing target.Is(err). This would allow
|
||||
// user-definable predicates, but also may allow for coping with sloppy
|
||||
// APIs, thereby making it easier to get away with them.
|
||||
if err = Unwrap(err); err == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// As finds the first error in err's chain that matches the type to which target
|
||||
// points, and if so, sets the target to its value and returns true. An error
|
||||
// matches a type if it is assignable to the target type, or if it has a method
|
||||
// As(interface{}) bool such that As(target) returns true. As will panic if target
|
||||
// is not a non-nil pointer to a type which implements error or is of interface type.
|
||||
//
|
||||
// The As method should set the target to its value and return true if err
|
||||
// matches the type to which target points.
|
||||
//
|
||||
// Deprecated: As of Go 1.13, use errors.As instead.
|
||||
func As(err error, target interface{}) bool {
|
||||
if target == nil {
|
||||
panic("errors: target cannot be nil")
|
||||
}
|
||||
val := reflect.ValueOf(target)
|
||||
typ := val.Type()
|
||||
if typ.Kind() != reflect.Ptr || val.IsNil() {
|
||||
panic("errors: target must be a non-nil pointer")
|
||||
}
|
||||
if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) {
|
||||
panic("errors: *target must be interface or implement error")
|
||||
}
|
||||
targetType := typ.Elem()
|
||||
for err != nil {
|
||||
if reflect.TypeOf(err).AssignableTo(targetType) {
|
||||
val.Elem().Set(reflect.ValueOf(err))
|
||||
return true
|
||||
}
|
||||
if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
|
||||
return true
|
||||
}
|
||||
err = Unwrap(err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var errorType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
12
vendor/modules.txt
vendored
12
vendor/modules.txt
vendored
@@ -679,11 +679,12 @@ github.com/goccy/go-json/internal/encoder/vm_color_indent
|
||||
github.com/goccy/go-json/internal/encoder/vm_indent
|
||||
github.com/goccy/go-json/internal/errors
|
||||
github.com/goccy/go-json/internal/runtime
|
||||
# github.com/goccy/go-yaml v1.12.0
|
||||
## explicit; go 1.19
|
||||
# github.com/goccy/go-yaml v1.18.0
|
||||
## explicit; go 1.21.0
|
||||
github.com/goccy/go-yaml
|
||||
github.com/goccy/go-yaml/ast
|
||||
github.com/goccy/go-yaml/internal/errors
|
||||
github.com/goccy/go-yaml/internal/format
|
||||
github.com/goccy/go-yaml/lexer
|
||||
github.com/goccy/go-yaml/parser
|
||||
github.com/goccy/go-yaml/printer
|
||||
@@ -1199,7 +1200,7 @@ github.com/onsi/ginkgo/reporters/stenographer
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
|
||||
github.com/onsi/ginkgo/types
|
||||
# github.com/onsi/ginkgo/v2 v2.25.3
|
||||
# github.com/onsi/ginkgo/v2 v2.26.0
|
||||
## explicit; go 1.23.0
|
||||
github.com/onsi/ginkgo/v2
|
||||
github.com/onsi/ginkgo/v2/config
|
||||
@@ -1218,6 +1219,7 @@ github.com/onsi/ginkgo/v2/internal
|
||||
github.com/onsi/ginkgo/v2/internal/global
|
||||
github.com/onsi/ginkgo/v2/internal/interrupt_handler
|
||||
github.com/onsi/ginkgo/v2/internal/parallel_support
|
||||
github.com/onsi/ginkgo/v2/internal/reporters
|
||||
github.com/onsi/ginkgo/v2/internal/testingtproxy
|
||||
github.com/onsi/ginkgo/v2/reporters
|
||||
github.com/onsi/ginkgo/v2/types
|
||||
@@ -2498,10 +2500,6 @@ golang.org/x/tools/internal/stdlib
|
||||
golang.org/x/tools/internal/typeparams
|
||||
golang.org/x/tools/internal/typesinternal
|
||||
golang.org/x/tools/internal/versions
|
||||
# golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
|
||||
## explicit; go 1.17
|
||||
golang.org/x/xerrors
|
||||
golang.org/x/xerrors/internal
|
||||
# google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb
|
||||
## explicit; go 1.23.0
|
||||
google.golang.org/genproto/protobuf/field_mask
|
||||
|
||||
Reference in New Issue
Block a user