Compare commits

..
153 Commits
Author SHA1 Message Date
Mike Farah c59fa8de59 Bumping version 2025-05-03 16:40:24 +10:00
Mike Farah ef8b520f89 Updating release notes 2025-05-03 16:39:36 +10:00
Mike Farah 20b5129120 Updating golanglint 2025-05-03 16:34:21 +10:00
Mike Farah 89518a09b8 Bumping golint 2025-05-03 15:58:14 +10:00
Mike Farah d01ac7801d Regen doc 2025-05-03 11:37:52 +10:00
Mike Farah 67520b5e7b Adding windows arm build #2344 2025-05-03 11:37:52 +10:00
Romain Lebrun ThaurontandMike Farah 7b6e61ba2c Update README.md 2025-05-03 11:36:12 +10:00
Romain Lebrun ThaurontandMike Farah cf8621d9e3 Install to /usr/local in README install instruction 2025-05-03 11:36:12 +10:00
dependabot[bot]andMike Farah 340b897252 Bump github.com/spf13/cobra from 1.8.1 to 1.9.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.1 to 1.9.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.1...v1.9.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-03 11:28:22 +10:00
n4zukkerandMike Farah 4155c99a12 Typo in cats example
The quotation mark and closing parenthesis were swapped.

Before:
```
$ echo "Hello kitty" | yq eval 'test("(?i)cats)"'
Error: bad expression - probably missing close bracket on TEST
```

After:
```
$ echo "Hello kitty" | yq eval 'test("(?i)cats")'
false
```
2025-05-03 11:27:51 +10:00
dependabot[bot]andMike Farah b26de94758 Bump github.com/magiconair/properties from 1.8.9 to 1.8.10
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.9...v1.8.10)

---
updated-dependencies:
- dependency-name: github.com/magiconair/properties
  dependency-version: 1.8.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-03 11:24:22 +10:00
dependabot[bot]andMike Farah 7dc5efee62 Bump golang.org/x/net from 0.34.0 to 0.39.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.34.0 to 0.39.0.
- [Commits](https://github.com/golang/net/compare/v0.34.0...v0.39.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-03 11:24:12 +10:00
Alberto CavalcanteandMike Farah 2cb7498444 chore(release): add windows arm64 binary target for release 2025-05-03 11:23:55 +10:00
Alberto CavalcanteandMike Farah 649c9a083a chore(check): use golangci-lint from GOPATH/bin as first option 2025-05-03 11:23:55 +10:00
Alberto CavalcanteandMike Farah 074d785396 chore(devtools): use curl instead of wget for better compatibility with MacOS 2025-05-03 11:23:55 +10:00
dependabot[bot]andMike Farah de2f77b49c Bump github.com/alecthomas/participle/v2 from 2.1.1 to 2.1.4
Bumps [github.com/alecthomas/participle/v2](https://github.com/alecthomas/participle) from 2.1.1 to 2.1.4.
- [Release notes](https://github.com/alecthomas/participle/releases)
- [Changelog](https://github.com/alecthomas/participle/blob/master/CHANGES.md)
- [Commits](https://github.com/alecthomas/participle/compare/v2.1.1...v2.1.4)

---
updated-dependencies:
- dependency-name: github.com/alecthomas/participle/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-05 21:36:59 +11:00
Ashok PariyaandMike Farah fe06096514 Add s390x platform support to Docker release workflow
Updated the list of supported platforms in the GitHub Actions
Docker release workflow to include linux/s390x.

Signed-off-by: Ashok Pariya <ashok.pariya@ibm.com>
2025-04-05 20:18:39 +11:00
dependabot[bot]andMike Farah 40f2c2381b Bump golang from 1.24.1 to 1.24.2
Bumps golang from 1.24.1 to 1.24.2.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.24.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-05 20:17:56 +11:00
dependabot[bot]andMike Farah 64bee0fbe3 Bump golang from 1.24.0 to 1.24.1
Bumps golang from 1.24.0 to 1.24.1.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-25 15:45:53 +11:00
dependabot[bot]andMike Farah 6e6575d5b0 Bump golang.org/x/text from 0.22.0 to 0.23.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.22.0 to 0.23.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-25 15:45:42 +11:00
Oleksandr RedkoandMike Farah ce2ce51236 Remove mistakenly committed cover.out 2025-03-25 15:45:27 +11:00
Zoltán ReegnandMike Farah c9766c1cab Also push docker images to ghcr.io
With docker-hub starting to introduce a much stricter limit on anonymous
pulls, it makes sense to also host the image in ghcr.io as well,
allowing users flexibility in where they pull the docker images from.

Also with the github action it makes more sense hosting the docker image
on github infrastructure.

I've introduced a github action for logging into registries as well.
2025-03-25 15:45:15 +11:00
Mike Farah 337960a6d1 Fixing add when there is no node match #2325 2025-03-25 15:35:16 +11:00
damuzhi0810andMike Farah 1395d6e230 refactor: using slices.Contains to simplify the code
Signed-off-by: damuzhi0810 <rust@before.tech>
2025-03-25 15:10:25 +11:00
Mike Farah ba1b9737b6 Added recursive update map keys example 2025-03-03 15:10:42 +11:00
dependabot[bot]andMike Farah d74e70104f Bump golang.org/x/text from 0.21.0 to 0.22.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-22 11:19:34 +11:00
dependabot[bot]andMike Farah 15071ba393 Bump github.com/goccy/go-json from 0.10.4 to 0.10.5
Bumps [github.com/goccy/go-json](https://github.com/goccy/go-json) from 0.10.4 to 0.10.5.
- [Release notes](https://github.com/goccy/go-json/releases)
- [Changelog](https://github.com/goccy/go-json/blob/master/CHANGELOG.md)
- [Commits](https://github.com/goccy/go-json/compare/v0.10.4...v0.10.5)

---
updated-dependencies:
- dependency-name: github.com/goccy/go-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-22 11:19:24 +11:00
dependabot[bot]andMike Farah a9495ff395 Bump github.com/spf13/pflag from 1.0.5 to 1.0.6
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.5...v1.0.6)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-22 11:19:12 +11:00
dependabot[bot]andMike Farah e176ec649f Bump golang from 1.23.5 to 1.24.0
Bumps golang from 1.23.5 to 1.24.0.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-22 11:19:00 +11:00
dependabot[bot]andMike Farah c34d3f7805 Bump golang from 1.23.4 to 1.23.5
Bumps golang from 1.23.4 to 1.23.5.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-23 22:04:08 +11:00
dependabot[bot]andMike Farah 99e24956b3 Bump github.com/elliotchance/orderedmap from 1.7.1 to 1.8.0
Bumps [github.com/elliotchance/orderedmap](https://github.com/elliotchance/orderedmap) from 1.7.1 to 1.8.0.
- [Release notes](https://github.com/elliotchance/orderedmap/releases)
- [Commits](https://github.com/elliotchance/orderedmap/compare/v1.7.1...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/elliotchance/orderedmap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-22 14:40:05 +11:00
dependabot[bot]andMike Farah 2bce6b2608 Bump golang.org/x/net from 0.33.0 to 0.34.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.33.0 to 0.34.0.
- [Commits](https://github.com/golang/net/compare/v0.33.0...v0.34.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-22 14:39:55 +11:00
Mike Farah f202d06d82 sort_by works on maps 2025-01-22 14:36:50 +11:00
Stephen UridgeandMike Farah 1508f1fd5f Update docs and tests for --properties-separator flag 2025-01-22 09:53:51 +11:00
Mike Farah 8bf425b4d1 Bumping version 2025-01-12 14:17:39 +11:00
Mike Farah f755755bb0 Updated release notes 2025-01-12 14:17:20 +11:00
Mike Farah 0f390b27aa Bumping goccy 2025-01-12 14:13:31 +11:00
dependabot[bot]andMike Farah 31ad7fbaa2 Bump github.com/magiconair/properties from 1.8.7 to 1.8.9
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.7 to 1.8.9.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.7...v1.8.9)

---
updated-dependencies:
- dependency-name: github.com/magiconair/properties
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-12 14:03:15 +11:00
dependabot[bot]andMike Farah 566cf82d08 Bump github.com/goccy/go-json from 0.10.3 to 0.10.4
Bumps [github.com/goccy/go-json](https://github.com/goccy/go-json) from 0.10.3 to 0.10.4.
- [Release notes](https://github.com/goccy/go-json/releases)
- [Changelog](https://github.com/goccy/go-json/blob/master/CHANGELOG.md)
- [Commits](https://github.com/goccy/go-json/compare/v0.10.3...v0.10.4)

---
updated-dependencies:
- dependency-name: github.com/goccy/go-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-12 14:03:05 +11:00
dependabot[bot]andMike Farah 2c9f8331c4 Bump github.com/elliotchance/orderedmap from 1.7.0 to 1.7.1
Bumps [github.com/elliotchance/orderedmap](https://github.com/elliotchance/orderedmap) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/elliotchance/orderedmap/releases)
- [Commits](https://github.com/elliotchance/orderedmap/compare/v1.7.0...v1.7.1)

---
updated-dependencies:
- dependency-name: github.com/elliotchance/orderedmap
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-12 14:02:52 +11:00
dependabot[bot]andMike Farah c02d44de63 Bump golang.org/x/net from 0.32.0 to 0.33.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.32.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.32.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-12 14:02:38 +11:00
Rudolf ThomasandMike Farah f73c862cc5 feat: Create parent directories if --split-exp is used.
Problem: When --split-exp is used and produces filenames with slashes in
them, the target directories must already exist otherwise yq fails.

Fix/feature: Create the necessary directories with os.MkdirAll().
The permissions 0750 were chosen to satisfy the vulnerability checker.
2024-12-14 19:52:09 +11:00
Mike Farah 294a1709ad Bumping version 2024-12-07 17:33:47 +11:00
Mike Farah 342efb23ff Fixed panic on multipling string by very large number #2211 2024-12-07 16:53:40 +11:00
Mike Farah 2201381235 Fixed multiply string by negative number panic #2211 2024-12-07 16:28:59 +11:00
Mike Farah 5273715428 Fixed panic error #2211 2024-12-07 16:20:45 +11:00
Mike Farah e204677ff8 Fixed no-colors regression #2218 2024-12-07 16:05:58 +11:00
Brian EggeandMike Farah f76815959a Create docker image for armv7 / raspberry pi3 2024-12-07 11:10:20 +11:00
Jan DuboisandMike Farah c16b1800a0 Make sure to update the key when deleting array elements 2024-12-07 11:09:52 +11:00
dependabot[bot]andMike Farah 3bca3a23c0 Bump github.com/elliotchance/orderedmap from 1.6.0 to 1.7.0
Bumps [github.com/elliotchance/orderedmap](https://github.com/elliotchance/orderedmap) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/elliotchance/orderedmap/releases)
- [Commits](https://github.com/elliotchance/orderedmap/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/elliotchance/orderedmap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 11:03:57 +11:00
dependabot[bot]andMike Farah 70bef5b9d2 Bump golang.org/x/net from 0.31.0 to 0.32.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.31.0 to 0.32.0.
- [Commits](https://github.com/golang/net/compare/v0.31.0...v0.32.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 11:03:23 +11:00
dependabot[bot]andMike Farah ea2ba18ef4 Bump golang from 1.23.3 to 1.23.4
Bumps golang from 1.23.3 to 1.23.4.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-07 11:00:34 +11:00
Mike Farah 80310eaaac Removing temp docker fix 2024-11-16 20:37:27 +11:00
Mike Farah 8391193732 Temp fix docker version 2024-11-16 20:34:50 +11:00
Mike Farah d858ab1644 Removing riscv64 from docker build as its not supported by the base golang:1.23.2 image 2024-11-16 20:31:39 +11:00
Mike Farah f1c7e5ca79 Updated release notes 2024-11-16 15:45:36 +11:00
Mike Farah bc5b54cb1d Bumping version 2024-11-16 15:45:01 +11:00
Mike Farah 129e597346 Fixing release pipeline 2024-11-16 15:43:21 +11:00
Mike Farah 42db154e2e Bumping version 2024-11-16 15:25:31 +11:00
Mike Farah f06c7c6b52 Updating release notes 2024-11-16 15:24:53 +11:00
Mike Farah 1ae6ac18f9 Merge branch 'gabe565-add-comment-style' 2024-11-16 15:23:27 +11:00
Mike Farah b710fadfc0 Regenerating go mod 2024-11-16 15:23:08 +11:00
Mike Farah 6a43f17d02 Merge branch 'add-comment-style' of github.com:gabe565/yq into gabe565-add-comment-style 2024-11-16 15:19:21 +11:00
Mike FarahandGitHub 1a4b2485ff Merge branch 'master' into add-comment-style 2024-11-16 15:16:12 +11:00
Mike Farah 58cc9db721 Updated release notes 2024-11-16 15:14:43 +11:00
Mike Farah 4af292f076 Fixed handling of nulls with sort_by expressions #2164 2024-11-16 12:27:18 +11:00
dependabot[bot]andMike Farah f238f01856 Bump github.com/fatih/color from 1.17.0 to 1.18.0
Bumps [github.com/fatih/color](https://github.com/fatih/color) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: github.com/fatih/color
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-16 12:25:41 +11:00
dependabot[bot]andMike Farah 58a4d2401f Bump golang.org/x/net from 0.30.0 to 0.31.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.30.0 to 0.31.0.
- [Commits](https://github.com/golang/net/compare/v0.30.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-16 12:11:59 +11:00
Mike Farah 887b4a560f Fixed linting 2024-11-16 12:04:43 +11:00
dependabot[bot]andMike Farah f2cc2ea5a8 Bump golang from 1.23.2 to 1.23.3
Bumps golang from 1.23.2 to 1.23.3.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-16 11:59:54 +11:00
Mike Farah 95e7b35f74 Fixed spelling of coloured 2024-11-16 11:54:58 +11:00
Vladimir VarankinandMike Farah f071a25fa9 cmd: force no color output when NO_COLOR env presents 2024-11-16 11:54:19 +11:00
Mike Farah b8607bacb9 Prefer not having nolint 2024-11-16 11:52:42 +11:00
Marco Vito MoscaritoloandMike Farah 6908161f1f replace error creation 2024-11-16 11:48:53 +11:00
Marco Vito MoscaritoloandMike Farah f168172bf4 remove unused variable parameters from functions 2024-11-16 11:48:53 +11:00
Marco Vito MoscaritoloandMike Farah 3ce266bfa0 fix parameter order in error type comparison 2024-11-16 11:48:53 +11:00
Marco Vito MoscaritoloandMike Farah 7eef1a454e exclude lint errors to keep cobra params unchanged 2024-11-16 11:48:53 +11:00
Marco Vito MoscaritoloandMike Farah 072491c656 remove lint exception no longer required 2024-11-16 11:48:53 +11:00
Marco Vito MoscaritoloandMike Farah 18972b290a replace deprecated megacheck with specific linters 2024-11-16 11:48:53 +11:00
Marco Vito MoscaritoloandMike Farah 9d60c79609 update golangci-lint to the last version 2024-11-16 11:48:53 +11:00
Gabe Cook 9caeb429ac Format comments with a gray foreground 2024-11-10 03:30:03 -06:00
dependabot[bot]andMike Farah 39a81da170 Bump golang.org/x/net from 0.29.0 to 0.30.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.29.0 to 0.30.0.
- [Commits](https://github.com/golang/net/compare/v0.29.0...v0.30.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-10 13:26:42 +11:00
dependabot[bot]andMike Farah b84e23e1ec Bump golang from 1.23.1 to 1.23.2
Bumps golang from 1.23.1 to 1.23.2.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-10 13:25:50 +11:00
Mike Farah f654fbf459 Fixed array subtraction update bug #2159 2024-09-29 15:21:11 +10:00
Mike Farah 5df71072f5 Fixed index out of range error 2024-09-29 15:06:34 +10:00
dependabot[bot]andMike Farah cc7738bb8d Bump golang.org/x/net from 0.28.0 to 0.29.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.28.0 to 0.29.0.
- [Commits](https://github.com/golang/net/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-19 10:45:18 +10:00
dependabot[bot]andMike Farah 302ce1291f Bump golang from 1.23.0 to 1.23.1
Bumps golang from 1.23.0 to 1.23.1.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-19 10:45:00 +10:00
dependabot[bot]andMike Farah f57de74cfe Bump github.com/pelletier/go-toml/v2 from 2.2.2 to 2.2.3
Bumps [github.com/pelletier/go-toml/v2](https://github.com/pelletier/go-toml) from 2.2.2 to 2.2.3.
- [Release notes](https://github.com/pelletier/go-toml/releases)
- [Changelog](https://github.com/pelletier/go-toml/blob/v2/.goreleaser.yaml)
- [Commits](https://github.com/pelletier/go-toml/compare/v2.2.2...v2.2.3)

---
updated-dependencies:
- dependency-name: github.com/pelletier/go-toml/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-06 19:09:43 +10:00
dependabot[bot]andMike Farah 383cd0f182 Bump golang from 1.22.5 to 1.23.0
Bumps golang from 1.22.5 to 1.23.0.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-06 13:37:14 +10:00
Mike Farah 3727b3e664 Fixed unecessary int64 to int conversion 2024-09-06 13:24:10 +10:00
Mike Farah c477fc08cf Updated readme to include x-cmd 2024-09-06 13:11:09 +10:00
Mike Farah 1846006082 Can traverse straight from parent operator (parent.blah) 2024-09-06 12:46:23 +10:00
Mike Farah dff0122481 Regen kind docs 2024-09-06 12:33:27 +10:00
Mike Farah 42b92aff13 Added pick including all keys example 2024-09-06 12:32:36 +10:00
dependabot[bot]andMike Farah c76e432de3 Bump golang.org/x/net from 0.27.0 to 0.28.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.27.0 to 0.28.0.
- [Commits](https://github.com/golang/net/compare/v0.27.0...v0.28.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-06 12:25:19 +10:00
Tiger KaovilaiandMike Farah 19e2591b1e Only use podman if CLI can execute. Use docker if non-Linux podman has no connection to Linux system.
Solves
```
❯ make test
Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM Error: unable to connect to Podman socket: failed to read identity "/Users/tiger/.local/share/containers/podman/machine/machine": open /Users/tiger/.local/share/containers/podman/machine/machine: no such file or directory /opt/homebrew/bin/docker run --rm -e LDFLAGS=" -X main.GitCommit=bbdd974+CHANGES -X main.GitDescribe=v4 -w -s" -e GITHUB_TOKEN="" -v /Users/tiger/git/yq-k8s/vendor:/go/src -v /Users/tiger/git/yq-k8s:/yq/src/github.com/mikefarah/yq -w /yq/src/github.com/mikefarah/yq yq_dev go mod vendor
Error: podman-machine-default: VM already exists
```

Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
2024-09-06 12:25:07 +10:00
William AllenandMike Farah 6eb2ae757a Create kind.md header doc 2024-08-20 15:23:06 +10:00
Mike Farah 82fca30efa Fix cspell errors 2024-08-20 13:14:50 +10:00
Matheus MacabuandGitHub c46c1a7128 build: use goreleaser for building cross-compiled binaries and add riscv64 target (#2135)
* build: use goreleaser to cross-compile binaries for all platforms and archs

The main motivation behind it is because "gox" is unmaintained and archived
and it does not support "linux/riscv64" as a target.

Right now, goreleaser is only building the binaries, and I've tried to replicate
the exact same way the old script does.

In the future, if so desired, goreleaser could be used to further automate the
build and release pipeline by creating the release in GitHub.

* build: create binaries and OCI image for linux/riscv64
2024-08-20 13:09:12 +10:00
Mike Farah bbdd97482f Bumping version 2024-08-05 15:38:57 +10:00
Mike Farah 9940668729 Preparing release 2024-08-05 15:38:30 +10:00
95aaccee46 Add Flox to installation methods (#2117)
Co-authored-by: Bryan Honof <bryanhonof@bryans-mbp.space.flox.local>
2024-08-05 15:15:06 +10:00
ryenusandGitHub b9c3ff6f0a convert file ext to lowercase for format detection (#2121)
* convert file ext to lowercase for format detection

To ensure proper file format detection with case-insensitive file
systems.

* use filepath.Ext for more reliable file ext detection

especially for paths like index.js/foo

* add a test for file ext based format detection
2024-08-05 15:14:43 +10:00
Kian ParvinandGitHub b80e1cb35e Use static bin in snap (#2090) 2024-07-21 10:52:32 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0ff8415244 Bump golang.org/x/net from 0.26.0 to 0.27.0 (#2099)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.26.0 to 0.27.0.
- [Commits](https://github.com/golang/net/compare/v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-21 10:08:58 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
e8dcf3f1a4 Bump github.com/goccy/go-yaml from 1.11.3 to 1.12.0 (#2108)
Bumps [github.com/goccy/go-yaml](https://github.com/goccy/go-yaml) from 1.11.3 to 1.12.0.
- [Release notes](https://github.com/goccy/go-yaml/releases)
- [Changelog](https://github.com/goccy/go-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/goccy/go-yaml/compare/v1.11.3...v1.12.0)

---
updated-dependencies:
- dependency-name: github.com/goccy/go-yaml
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-21 10:08:42 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
208302cf6b Bump golang from 1.22.4 to 1.22.5 (#2091)
Bumps golang from 1.22.4 to 1.22.5.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-21 10:08:23 +10:00
Mike Farah ef6fb92e7f Log printing follow no-colors flag #2082 2024-06-29 15:26:10 +10:00
Mike Farah 28646c7b50 Skip and warn when interpolating strings and theres a unclosed bracket #2083 2024-06-29 15:20:07 +10:00
Mike Farah 0b7d4b799c Fixed CSV content starting with # issue #2076 2024-06-29 15:04:07 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
7e1722510a Bump github.com/spf13/cobra from 1.8.0 to 1.8.1 (#2075)
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-29 13:59:50 +10:00
Mike Farah f15500b20a Bumping version 2024-06-16 11:13:40 +10:00
Mike Farah b8aec71e66 Preparing release 2024-06-16 11:13:25 +10:00
Mike Farah 68aafb6a53 Handle numbers with underscores #2039 2024-06-16 11:09:52 +10:00
Mike Farah d58870b056 Adding splat[] short hand to explode,collect,flatten,groupby,path,pivot,select and more 2024-06-16 10:48:01 +10:00
Mike Farah f1964dece0 Adding splat[] short hand to collect,eval,map,omit,path,pick 2024-06-16 10:22:42 +10:00
Mike Farah 45eda8dbae Added support for shorthand splat[] for filter,reverse,sort,shuffle 2024-06-15 22:13:58 +10:00
Mike Farah d9af2dd976 Support env[] expression #2071 2024-06-15 21:56:32 +10:00
Mike Farah 7bad2f4f06 Adding back in commented tests :facepalm 2024-06-15 21:49:23 +10:00
Mike Farah 3ea19ad2ed clean code 2024-06-15 17:06:17 +10:00
Mike Farah 42120e1341 Unique now works on maps and arrays #2068 2024-06-15 17:04:48 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1147113fd3 Bump github.com/goccy/go-json from 0.10.2 to 0.10.3 (#2046)
Bumps [github.com/goccy/go-json](https://github.com/goccy/go-json) from 0.10.2 to 0.10.3.
- [Release notes](https://github.com/goccy/go-json/releases)
- [Changelog](https://github.com/goccy/go-json/blob/master/CHANGELOG.md)
- [Commits](https://github.com/goccy/go-json/compare/v0.10.2...v0.10.3)

---
updated-dependencies:
- dependency-name: github.com/goccy/go-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-15 16:00:53 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2edfa834d5 Bump github.com/elliotchance/orderedmap from 1.5.1 to 1.6.0 (#2053)
Bumps [github.com/elliotchance/orderedmap](https://github.com/elliotchance/orderedmap) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/elliotchance/orderedmap/releases)
- [Commits](https://github.com/elliotchance/orderedmap/compare/v1.5.1...v1.6.0)

---
updated-dependencies:
- dependency-name: github.com/elliotchance/orderedmap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-15 16:00:38 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8c7cfb720c Bump golang.org/x/net from 0.25.0 to 0.26.0 (#2061)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.25.0 to 0.26.0.
- [Commits](https://github.com/golang/net/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-15 16:00:16 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
356c60f40c Bump golang from 1.22.3 to 1.22.4 (#2062)
Bumps golang from 1.22.3 to 1.22.4.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-15 16:00:02 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
4cc646b16b Bump github.com/fatih/color from 1.16.0 to 1.17.0 (#2043)
Bumps [github.com/fatih/color](https://github.com/fatih/color) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/fatih/color
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-01 16:45:11 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2e44ab4512 Bump golang.org/x/net from 0.24.0 to 0.25.0 (#2035)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.24.0 to 0.25.0.
- [Commits](https://github.com/golang/net/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-01 16:45:01 +10:00
Mike Farah 557dcb87b8 Bumping version 2024-05-12 12:27:39 +10:00
Mike Farah 2daa39e306 Updating release notes 2024-05-12 12:27:06 +10:00
Mike Farah 0c15cf35a7 Added properties convert to numbers example #2023 2024-05-12 12:07:04 +10:00
Jakub JirutkaandGitHub d9adcdb668 Update instructions for Alpine Linux (#2034)
The package has been renamed from `yq` to `yq-go` to match other distros.
2024-05-12 11:55:06 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
9010809d89 Bump github.com/pelletier/go-toml/v2 from 2.2.1 to 2.2.2 (#2024)
Bumps [github.com/pelletier/go-toml/v2](https://github.com/pelletier/go-toml) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/pelletier/go-toml/releases)
- [Changelog](https://github.com/pelletier/go-toml/blob/v2/.goreleaser.yaml)
- [Commits](https://github.com/pelletier/go-toml/compare/v2.2.1...v2.2.2)

---
updated-dependencies:
- dependency-name: github.com/pelletier/go-toml/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-12 11:53:40 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8250f0c2bd Bump golang.org/x/text from 0.14.0 to 0.15.0 (#2036)
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.14.0 to 0.15.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-12 11:53:02 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8ac9f605f6 Bump golang from 1.22.2 to 1.22.3 (#2037)
Bumps golang from 1.22.2 to 1.22.3.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-12 11:52:48 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1748171463 Bump github.com/pelletier/go-toml/v2 from 2.2.0 to 2.2.1 (#2014)
Bumps [github.com/pelletier/go-toml/v2](https://github.com/pelletier/go-toml) from 2.2.0 to 2.2.1.
- [Release notes](https://github.com/pelletier/go-toml/releases)
- [Changelog](https://github.com/pelletier/go-toml/blob/v2/.goreleaser.yaml)
- [Commits](https://github.com/pelletier/go-toml/compare/v2.2.0...v2.2.1)

---
updated-dependencies:
- dependency-name: github.com/pelletier/go-toml/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 14:15:45 +10:00
Cory LatschkowskiandGitHub 21ba506edb Fix: shell-completion (#2006)
* fix: shell-completion

* update: description
2024-04-22 14:15:36 +10:00
Matt BensonandGitHub b54d7eb21c handle escaped backslashes (#1997) 2024-04-14 18:52:08 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
db6f2dc6a2 Bump golang from 1.22.1 to 1.22.2 (#1998)
Bumps golang from 1.22.1 to 1.22.2.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-14 18:51:39 +10:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1411f45055 Bump golang.org/x/net from 0.22.0 to 0.24.0 (#2008)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.24.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-14 18:51:28 +10:00
Cory LatschkowskiandGitHub c7baa8bc34 Fix: linux (w/ selinux) build (#2004)
* add: check for selinux for vol mount

* update: install packages first

build time not increased if script changes

* update: selinux check
2024-04-14 18:51:17 +10:00
Mike Farah a4b9c3049b Removed unused debian directory #2000 2024-04-13 11:00:39 +10:00
Mike Farah fe84f62288 Docs 2024-03-30 14:01:42 +11:00
Mike Farah 28c406706a Fixes npe when given filename ending with "." #1994 2024-03-30 14:00:57 +11:00
Matt BensonandGitHub 101cf14b8c min/max operators (#1992)
* min/max operators

* min, max operator headers
2024-03-30 13:34:36 +11:00
Matt BensonandGitHub 3283c65dc4 pivot operator (#1993) 2024-03-30 13:29:35 +11:00
Mike Farah 2ee7508b76 typos 2024-03-24 11:32:02 +11:00
Mike Farah 2ecd8b6092 updated contribe guide 2024-03-24 11:29:48 +11:00
Mike Farah 021d5f05f9 Fixing omit docs 2024-03-24 10:59:29 +11:00
Mike Farah 19a0e6dd8b Bumping version 2024-03-24 10:54:35 +11:00
Mike Farah fbd4c8428a Remove old JSON warning 2024-03-23 17:17:23 +11:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d9ef03a2d1 Bump github.com/pelletier/go-toml/v2 from 2.1.1 to 2.2.0 (#1986)
Bumps [github.com/pelletier/go-toml/v2](https://github.com/pelletier/go-toml) from 2.1.1 to 2.2.0.
- [Release notes](https://github.com/pelletier/go-toml/releases)
- [Changelog](https://github.com/pelletier/go-toml/blob/v2/.goreleaser.yaml)
- [Commits](https://github.com/pelletier/go-toml/compare/v2.1.1...v2.2.0)

---
updated-dependencies:
- dependency-name: github.com/pelletier/go-toml/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 17:15:56 +11:00
Matt BensonandGitHub f5bfe5a248 omit operator (#1989) 2024-03-23 17:15:45 +11:00
Matt BensonandGitHub 3b85cef340 support string X int multiplication as jq (#1988) 2024-03-22 20:44:49 +11:00
176 changed files with 3371 additions and 4996 deletions
+21 -3
View File
@@ -30,6 +30,19 @@ jobs:
- name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }} && docker version
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push image
run: |
echo "GithubRef: ${GITHUB_REF}"
@@ -38,10 +51,9 @@ jobs:
IMAGE_VERSION=${VERSION:1}
echo "IMAGE_VERSION: ${IMAGE_VERSION}"
PLATFORMS="linux/amd64,linux/ppc64le,linux/arm64"
PLATFORMS="linux/amd64,linux/ppc64le,linux/arm64,linux/arm/v7,linux/s390x"
echo "Building and pushing version ${IMAGE_VERSION} of image ${IMAGE_NAME}"
echo '${{ secrets.DOCKER_PASSWORD }}' | docker login -u '${{ secrets.DOCKER_USERNAME }}' --password-stdin
docker buildx build \
--label "org.opencontainers.image.authors=https://github.com/mikefarah/yq/graphs/contributors" \
--label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \
@@ -59,8 +71,11 @@ jobs:
-t "${IMAGE_NAME}:${IMAGE_VERSION}" \
-t "${IMAGE_NAME}:4" \
-t "${IMAGE_NAME}:latest" \
-t "ghcr.io/${IMAGE_NAME}:${IMAGE_VERSION}" \
-t "ghcr.io/${IMAGE_NAME}:4" \
-t "ghcr.io/${IMAGE_NAME}:latest" \
.
cd github-action
docker buildx build \
--label "org.opencontainers.image.authors=https://github.com/mikefarah/yq/graphs/contributors" \
@@ -79,4 +94,7 @@ jobs:
-t "${IMAGE_NAME}:${IMAGE_VERSION}-githubaction" \
-t "${IMAGE_NAME}:4-githubaction" \
-t "${IMAGE_NAME}:latest-githubaction" \
-t "ghcr.io/${IMAGE_NAME}:${IMAGE_VERSION}-githubaction" \
-t "ghrc.io/${IMAGE_NAME}:4-githubaction" \
-t "ghcr.io/${IMAGE_NAME}:latest-githubaction" \
.
+1 -3
View File
@@ -40,9 +40,7 @@ jobs:
- name: Cross compile
run: |
sudo apt-get install rhash -y
go install github.com/mitchellh/gox@v1.0.1
mkdir -p build
cp yq.1 build/yq.1
go install github.com/goreleaser/goreleaser/v2@latest
./scripts/xcompile.sh
- name: Release
+3
View File
@@ -22,6 +22,7 @@ _cgo_gotypes.go
_cgo_export.*
_testmain.go
cover.out
coverage.out
coverage.html
*.exe
@@ -44,6 +45,8 @@ test*.yml
test*.xml
test*.toml
test*.yaml
test_dir1/
test_dir2/
0.yml
1.yml
2.yml
+38
View File
@@ -0,0 +1,38 @@
run:
timeout: 5m
linters:
enable:
- asciicheck
- depguard
- errorlint
- gci
- gochecknoinits
- gofmt
- goimports
- gosec
- gosimple
- staticcheck
- unused
- misspell
- nakedret
- nolintlint
- predeclared
- revive
- unconvert
- unparam
linters-settings:
depguard:
rules:
prevent_unmaintained_packages:
list-mode: lax
files:
- $all
- "!$test"
deny:
- pkg: io/ioutil
desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
issues:
exclude-rules:
- linters:
- revive
text: "var-naming"
+37 -28
View File
@@ -1,16 +1,11 @@
run:
timeout: 5m
version: "2"
linters:
enable:
- asciicheck
- depguard
- errorlint
- gci
- gochecknoinits
- gofmt
- goimports
- gosec
- megacheck
- misspell
- nakedret
- nolintlint
@@ -18,26 +13,40 @@ linters:
- revive
- unconvert
- unparam
linters-settings:
depguard:
settings:
depguard:
rules:
prevent_unmaintained_packages:
list-mode: lax
files:
- $all
- '!$test'
deny:
- pkg: io/ioutil
desc: 'replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil'
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
prevent_unmaintained_packages:
list-mode: lax
files:
- $all
- "!$test"
deny:
- pkg: io/ioutil
desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
issues:
exclude-rules:
- linters:
- gosec
text: "Implicit memory aliasing in for loop."
path: _test\.go
- linters:
- revive
text: "unexported-return"
- linters:
- revive
text: "var-naming"
- linters:
- revive
text: var-naming
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
+48
View File
@@ -0,0 +1,48 @@
version: 2
dist: build
builds:
- id: yq
binary: yq_{{ .Os }}_{{ .Arch }}
ldflags:
- -s -w
env:
- CGO_ENABLED=0
targets:
- darwin_amd64
- darwin_arm64
- freebsd_386
- freebsd_amd64
- freebsd_arm
- linux_386
- linux_amd64
- linux_arm
- linux_arm64
- linux_mips
- linux_mips64
- linux_mips64le
- linux_mipsle
- linux_ppc64
- linux_ppc64le
- linux_riscv64
- linux_s390x
- netbsd_386
- netbsd_amd64
- netbsd_arm
- openbsd_386
- openbsd_amd64
- windows_386
- windows_amd64
- windows_arm
- windows_arm64
no_unique_dist_dir: true
release:
disable: true
skip_upload: true
+3 -1
View File
@@ -1,4 +1,4 @@
# Development
.# Development
1. Install (Golang)[https://golang.org/]
1. Run `scripts/devtools.sh` to install the required devtools
@@ -25,6 +25,8 @@ The pipeline will run the tests and automatically concatenate the files together
The first step is to find if what you want is automatically generated or not - start by looking in the master branch.
Note that PRs with small changes (e.g. minor typos) may not be merged (see https://joel.net/how-one-guy-ruined-hacktoberfest2020-drama).
### Updating dynamic documentation from master
- Search for the documentation you want to update. If you find matches in a `*_test.go` file - update that, as that will automatically update the matching `*.md` file
- Assuming you are updating a `*_test.go` file, once updated, run the test to regenerated the docs. E.g. for the 'Add' test generated docs, from the pkg/yqlib folder run:
+2 -2
View File
@@ -1,4 +1,4 @@
FROM golang:1.22.1 as builder
FROM golang:1.24.2 AS builder
WORKDIR /go/src/mikefarah/yq
@@ -10,7 +10,7 @@ RUN ./scripts/acceptance.sh
# Choose alpine as a base image to make this useful for CI, as many
# CI tools expect an interactive shell inside the container
FROM alpine:3 as production
FROM alpine:3 AS production
LABEL maintainer="Mike Farah <mikefarah@users.noreply.github.com>"
COPY --from=builder /go/src/mikefarah/yq/yq /usr/bin/yq
+8 -5
View File
@@ -1,12 +1,15 @@
FROM golang:1.22.1
FROM golang:1.24.2
RUN apt-get update && \
apt-get install -y npm && \
npm install -g npx cspell@latest
COPY scripts/devtools.sh /opt/devtools.sh
RUN set -e -x \
&& /opt/devtools.sh
ENV PATH=/go/bin:$PATH
RUN set -e -x && \
/opt/devtools.sh
RUN apt-get update && apt-get install -y npm && npm install -g npx cspell@latest
ENV PATH=/go/bin:$PATH
ENV CGO_ENABLED 0
ENV GOPATH /go:/yq
+1 -1
View File
@@ -2,7 +2,7 @@ MAKEFLAGS += --warn-undefined-variables
SHELL := /bin/bash
.SHELLFLAGS := -o pipefail -euc
.DEFAULT_GOAL := install
ENGINE := $(shell { command -v podman || command -v docker; } 2>/dev/null)
ENGINE := $(shell { (podman version > /dev/null 2>&1 && command -v podman) || command -v docker; } 2>/dev/null)
include Makefile.variables
+3 -2
View File
@@ -26,6 +26,7 @@ ifeq ($(CYG_CHECK),1)
else
# all non-windows environments
ROOT := $(shell pwd)
SELINUX := $(shell which getenforce 2>&1 >/dev/null && echo :z)
endif
DEV_IMAGE := ${PROJECT}_dev
@@ -33,7 +34,7 @@ DEV_IMAGE := ${PROJECT}_dev
ENGINERUN := ${ENGINE} run --rm \
-e LDFLAGS="${LDFLAGS}" \
-e GITHUB_TOKEN="${GITHUB_TOKEN}" \
-v ${ROOT}/vendor:/go/src \
-v ${ROOT}:/${PROJECT}/src/${IMPORT_PATH} \
-v ${ROOT}/vendor:/go/src${SELINUX} \
-v ${ROOT}:/${PROJECT}/src/${IMPORT_PATH}${SELINUX} \
-w /${PROJECT}/src/${IMPORT_PATH} \
${DEV_IMAGE}
+31 -11
View File
@@ -76,21 +76,21 @@ For instance, VERSION=v4.2.0 and BINARY=yq_linux_amd64
#### Compressed via tar.gz
```bash
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY}.tar.gz -O - |\
tar xz && mv ${BINARY} /usr/bin/yq
tar xz && mv ${BINARY} /usr/local/bin/yq
```
#### Plain binary
```bash
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY} -O /usr/bin/yq &&\
chmod +x /usr/bin/yq
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY} -O /usr/local/bin/yq &&\
chmod +x /usr/local/bin/yq
```
#### Latest version
```bash
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq &&\
chmod +x /usr/bin/yq
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq &&\
chmod +x /usr/local/bin/yq
```
### MacOS / Linux via Homebrew:
@@ -241,6 +241,14 @@ As these are supported by the community :heart: - however, they may be out of da
_Please note that the Debian package (previously supported by @rmescandon) is no longer maintained. Please use an alternative installation method._
### X-CMD
Checkout `yq` on x-cmd: https://x-cmd.com/mod/yq
- Instant Results: See the output of your yq filter in real-time.
- Error Handling: Encounter a syntax error? It will display the error message and the results of the closest valid filter
Thanks @edwinjhlee!
### Nix
```
@@ -295,13 +303,26 @@ sudo port install yq
Supported by @herbygillot (https://ports.macports.org/maintainer/github/herbygillot)
### Alpine Linux
- Enable edge/community repo by adding ```$MIRROR/alpine/edge/community``` to ```/etc/apk/repositories```
- Update database index with ```apk update```
- Install yq with ```apk add yq```
Supported by Tuan Hoang
https://pkgs.alpinelinux.org/package/edge/community/x86/yq
Alpine Linux v3.20+ (and Edge):
```
apk add yq-go
```
Alpine Linux up to v3.19:
```
apk add yq
```
Supported by Tuan Hoang (https://pkgs.alpinelinux.org/packages?name=yq-go)
### Flox:
Flox can be used to install yq on Linux, MacOS, and Windows through WSL.
```
flox install yq
```
## Features
- [Detailed documentation with many examples](https://mikefarah.gitbook.io/yq/)
@@ -349,7 +370,6 @@ Available Commands:
eval (default) Apply the expression to each document in each yaml file in sequence
eval-all Loads _all_ yaml documents of _all_ yaml files and runs expression once
help Help about any command
shell-completion Generate completion script
Flags:
-C, --colors force print with colors
+2 -2
View File
@@ -3,7 +3,7 @@
testLoadFileNotExist() {
result=$(./yq e -n 'load("cat.yml")' 2>&1)
assertEquals 1 $?
assertEquals "Error: Failed to load cat.yml: open cat.yml: no such file or directory" "$result"
assertEquals "Error: failed to load cat.yml: open cat.yml: no such file or directory" "$result"
}
testLoadFileExpNotExist() {
@@ -15,7 +15,7 @@ testLoadFileExpNotExist() {
testStrLoadFileNotExist() {
result=$(./yq e -n 'strload("cat.yml")' 2>&1)
assertEquals 1 $?
assertEquals "Error: Failed to load cat.yml: open cat.yml: no such file or directory" "$result"
assertEquals "Error: failed to load cat.yml: open cat.yml: no such file or directory" "$result"
}
testStrLoadFileExpNotExist() {
+21 -1
View File
@@ -2,6 +2,7 @@
setUp() {
rm test*.yml || true
rm -rf test_dir* || true
}
testBasicSplitWithName() {
@@ -204,4 +205,23 @@ EOM
assertEquals "$expectedDoc3" "$doc3"
}
source ./scripts/shunit2
testSplitWithDirectories() {
cat >test.yml <<EOL
f: test_dir1/test_file1
---
f: test_dir2/dir22/test_file2
---
f: test_file3
EOL
./yq e --no-doc -s ".f" test.yml
doc1=$(cat test_dir1/test_file1.yml)
assertEquals "f: test_dir1/test_file1" "$doc1"
doc2=$(cat test_dir2/dir22/test_file2.yml)
assertEquals "f: test_dir2/dir22/test_file2" "$doc2"
doc3=$(cat test_file3.yml)
assertEquals "f: test_file3" "$doc3"
}
source ./scripts/shunit2
@@ -7,19 +7,20 @@ import (
)
var completionCmd = &cobra.Command{
Use: "shell-completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
Use: "completion [bash|zsh|fish|powershell]",
Aliases: []string{"shell-completion"},
Short: "Generate the autocompletion script for the specified shell",
Long: `To load completions:
Bash:
$ source <(yq shell-completion bash)
$ source <(yq completion bash)
# To load completions for each session, execute once:
Linux:
$ yq shell-completion bash > /etc/bash_completion.d/yq
$ yq completion bash > /etc/bash_completion.d/yq
MacOS:
$ yq shell-completion bash > /usr/local/etc/bash_completion.d/yq
$ yq completion bash > /usr/local/etc/bash_completion.d/yq
Zsh:
@@ -29,16 +30,16 @@ Zsh:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ yq shell-completion zsh > "${fpath[1]}/_yq"
$ yq completion zsh > "${fpath[1]}/_yq"
# You will need to start a new shell for this setup to take effect.
Fish:
$ yq shell-completion fish | source
$ yq completion fish | source
# To load completions for each session, execute once:
$ yq shell-completion fish > ~/.config/fish/completions/yq.fish
$ yq completion fish > ~/.config/fish/completions/yq.fish
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
+4 -3
View File
@@ -12,9 +12,6 @@ var outputFormat = ""
var inputFormat = ""
var exitStatus = false
var forceColor = false
var forceNoColor = false
var colorsEnabled = false
var indent = 2
var noDocSeparators = false
var nullInput = false
@@ -23,6 +20,10 @@ var verbose = false
var version = false
var prettyPrint = false
var forceColor = false
var forceNoColor = false
var colorsEnabled = false
// can be either "" (off), "extract" or "process"
var frontMatter = ""
+1 -1
View File
@@ -12,7 +12,7 @@ func createEvaluateAllCommand() *cobra.Command {
Use: "eval-all [expression] [yaml_file1]...",
Aliases: []string{"ea"},
Short: "Loads _all_ yaml documents of _all_ yaml files and runs expression once",
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
ValidArgsFunction: func(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
+1 -1
View File
@@ -13,7 +13,7 @@ func createEvaluateSequenceCommand() *cobra.Command {
Use: "eval [expression] [yaml_file1]...",
Aliases: []string{"e"},
Short: "(default) Apply the expression to each document in each yaml file in sequence",
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
ValidArgsFunction: func(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
+24 -17
View File
@@ -5,8 +5,6 @@ import (
"os"
"strings"
"github.com/mikefarah/yq/v4/pkg/properties"
"github.com/mikefarah/yq/v4/pkg/xml"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
logging "gopkg.in/op/go-logging.v1"
@@ -68,14 +66,23 @@ yq -P -oy sample.json
return evaluateSequence(cmd, args)
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
cmd.SetOut(cmd.OutOrStdout())
level := logging.WARNING
stringFormat := `[%{level}] %{color}%{time:15:04:05}%{color:reset} %{message}`
if verbose {
// when NO_COLOR environment variable presents and not an empty string the coloured output should be disabled;
// refer to no-color.org
forceNoColor = forceNoColor || os.Getenv("NO_COLOR") != ""
if verbose && forceNoColor {
level = logging.DEBUG
stringFormat = `[%{level:5.5s}] %{time:15:04:05} %{shortfile:-33s} %{shortfunc:-25s} %{message}`
} else if verbose {
level = logging.DEBUG
stringFormat = `[%{level:5.5s}] %{color}%{time:15:04:05}%{color:bold} %{shortfile:-33s} %{shortfunc:-25s}%{color:reset} %{message}`
} else if forceNoColor {
stringFormat = `[%{level}] %{time:15:04:05} %{message}`
}
var format = logging.MustStringFormatter(stringFormat)
@@ -119,27 +126,27 @@ yq -P -oy sample.json
panic(err)
}
rootCmd.PersistentFlags().StringVar(&xml.ConfiguredXMLPreferences.AttributePrefix, "xml-attribute-prefix", xml.ConfiguredXMLPreferences.AttributePrefix, "prefix for xml attributes")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.AttributePrefix, "xml-attribute-prefix", yqlib.ConfiguredXMLPreferences.AttributePrefix, "prefix for xml attributes")
if err = rootCmd.RegisterFlagCompletionFunc("xml-attribute-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&xml.ConfiguredXMLPreferences.ContentName, "xml-content-name", xml.ConfiguredXMLPreferences.ContentName, "name for xml content (if no attribute name is present).")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ContentName, "xml-content-name", yqlib.ConfiguredXMLPreferences.ContentName, "name for xml content (if no attribute name is present).")
if err = rootCmd.RegisterFlagCompletionFunc("xml-content-name", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&xml.ConfiguredXMLPreferences.StrictMode, "xml-strict-mode", xml.ConfiguredXMLPreferences.StrictMode, "enables strict parsing of XML. See https://pkg.go.dev/encoding/xml for more details.")
rootCmd.PersistentFlags().BoolVar(&xml.ConfiguredXMLPreferences.KeepNamespace, "xml-keep-namespace", xml.ConfiguredXMLPreferences.KeepNamespace, "enables keeping namespace after parsing attributes")
rootCmd.PersistentFlags().BoolVar(&xml.ConfiguredXMLPreferences.UseRawToken, "xml-raw-token", xml.ConfiguredXMLPreferences.UseRawToken, "enables using RawToken method instead Token. Commonly disables namespace translations. See https://pkg.go.dev/encoding/xml#Decoder.RawToken for details.")
rootCmd.PersistentFlags().StringVar(&xml.ConfiguredXMLPreferences.ProcInstPrefix, "xml-proc-inst-prefix", xml.ConfiguredXMLPreferences.ProcInstPrefix, "prefix for xml processing instructions (e.g. <?xml version=\"1\"?>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.StrictMode, "xml-strict-mode", yqlib.ConfiguredXMLPreferences.StrictMode, "enables strict parsing of XML. See https://pkg.go.dev/encoding/xml for more details.")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.KeepNamespace, "xml-keep-namespace", yqlib.ConfiguredXMLPreferences.KeepNamespace, "enables keeping namespace after parsing attributes")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.UseRawToken, "xml-raw-token", yqlib.ConfiguredXMLPreferences.UseRawToken, "enables using RawToken method instead Token. Commonly disables namespace translations. See https://pkg.go.dev/encoding/xml#Decoder.RawToken for details.")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ProcInstPrefix, "xml-proc-inst-prefix", yqlib.ConfiguredXMLPreferences.ProcInstPrefix, "prefix for xml processing instructions (e.g. <?xml version=\"1\"?>)")
if err = rootCmd.RegisterFlagCompletionFunc("xml-proc-inst-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&xml.ConfiguredXMLPreferences.DirectiveName, "xml-directive-name", xml.ConfiguredXMLPreferences.DirectiveName, "name for xml directives (e.g. <!DOCTYPE thing cat>)")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.DirectiveName, "xml-directive-name", yqlib.ConfiguredXMLPreferences.DirectiveName, "name for xml directives (e.g. <!DOCTYPE thing cat>)")
if err = rootCmd.RegisterFlagCompletionFunc("xml-directive-name", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&xml.ConfiguredXMLPreferences.SkipProcInst, "xml-skip-proc-inst", xml.ConfiguredXMLPreferences.SkipProcInst, "skip over process instructions (e.g. <?xml version=\"1\"?>)")
rootCmd.PersistentFlags().BoolVar(&xml.ConfiguredXMLPreferences.SkipDirectives, "xml-skip-directives", xml.ConfiguredXMLPreferences.SkipDirectives, "skip over directives (e.g. <!DOCTYPE thing cat>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipProcInst, "xml-skip-proc-inst", yqlib.ConfiguredXMLPreferences.SkipProcInst, "skip over process instructions (e.g. <?xml version=\"1\"?>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipDirectives, "xml-skip-directives", yqlib.ConfiguredXMLPreferences.SkipDirectives, "skip over directives (e.g. <!DOCTYPE thing cat>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredCsvPreferences.AutoParse, "csv-auto-parse", yqlib.ConfiguredCsvPreferences.AutoParse, "parse CSV YAML/JSON values")
rootCmd.PersistentFlags().Var(newRuneVar(&yqlib.ConfiguredCsvPreferences.Separator), "csv-separator", "CSV Separator character")
@@ -157,8 +164,8 @@ yq -P -oy sample.json
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.UnquotedKeys, "lua-unquoted", yqlib.ConfiguredLuaPreferences.UnquotedKeys, "output unquoted string keys (e.g. {foo=\"bar\"})")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.Globals, "lua-globals", yqlib.ConfiguredLuaPreferences.Globals, "output keys as top-level global variables")
rootCmd.PersistentFlags().StringVar(&properties.ConfiguredPropertiesPreferences.KeyValueSeparator, "properties-separator", properties.ConfiguredPropertiesPreferences.KeyValueSeparator, "separator to use between keys and values")
rootCmd.PersistentFlags().BoolVar(&properties.ConfiguredPropertiesPreferences.UseArrayBrackets, "properties-array-brackets", properties.ConfiguredPropertiesPreferences.UseArrayBrackets, "use [x] in array paths (e.g. for SpringBoot)")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "properties-separator", yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "separator to use between keys and values")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "properties-array-brackets", yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "use [x] in array paths (e.g. for SpringBoot)")
rootCmd.PersistentFlags().BoolVar(&yqlib.StringInterpolationEnabled, "string-interpolation", yqlib.StringInterpolationEnabled, "Toggles strings interpolation of \\(exp)")
@@ -179,7 +186,7 @@ yq -P -oy sample.json
rootCmd.PersistentFlags().BoolVarP(&exitStatus, "exit-status", "e", false, "set exit status if there are no matches or null or false is returned")
rootCmd.PersistentFlags().BoolVarP(&forceColor, "colors", "C", false, "force print with colors")
rootCmd.PersistentFlags().BoolVarP(&forceNoColor, "no-colors", "M", false, "force print with no colors")
rootCmd.PersistentFlags().BoolVarP(&forceNoColor, "no-colors", "M", forceNoColor, "force print with no colors")
rootCmd.PersistentFlags().StringVarP(&frontMatter, "front-matter", "f", "", "(extract|process) first input as yaml front-matter. Extract will pull out the yaml content, process will run the expression against the yaml content, leaving the remaining data intact")
if err = rootCmd.RegisterFlagCompletionFunc("front-matter", cobra.FixedCompletions([]string{"extract", "process"}, cobra.ShellCompDirectiveNoFileComp)); err != nil {
panic(err)
@@ -190,7 +197,7 @@ yq -P -oy sample.json
}
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredYamlPreferences.LeadingContentPreProcessing, "header-preprocess", "", true, "Slurp any header comments and separators before processing expression.")
rootCmd.PersistentFlags().StringVarP(&splitFileExp, "split-exp", "s", "", "print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter.")
rootCmd.PersistentFlags().StringVarP(&splitFileExp, "split-exp", "s", "", "print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter. The necessary directories will be created.")
if err = rootCmd.RegisterFlagCompletionFunc("split-exp", cobra.NoFileCompletions); err != nil {
panic(err)
}
+3 -9
View File
@@ -6,8 +6,6 @@ import (
"os"
"strings"
"github.com/mikefarah/yq/v4/pkg/properties"
"github.com/mikefarah/yq/v4/pkg/xml"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
"gopkg.in/op/go-logging.v1"
@@ -77,10 +75,6 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
outputFormat = "yaml"
}
} else if isAutomaticOutputFormat() {
// automatic input worked, we can do it for output too unless specified
if inputFormat == "json" {
yqlib.GetLogger().Warning("JSON file output is now JSON by default (instead of yaml). Use '-oy' or '--output-format=yaml' for yaml output")
}
outputFormat = inputFormat
}
} else if isAutomaticOutputFormat() {
@@ -104,7 +98,7 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
yqlib.GetLogger().Debug("Using output format %v", outputFormat)
if outputFormatType == yqlib.YamlFormat ||
outputFormatType == properties.PropertiesFormat {
outputFormatType == yqlib.PropertiesFormat {
unwrapScalar = true
}
if unwrapScalarFlag.IsExplicitlySet() {
@@ -150,12 +144,12 @@ func configureEncoder() (yqlib.Encoder, error) {
if err != nil {
return nil, err
}
xml.ConfiguredXMLPreferences.Indent = indent
yqlib.ConfiguredXMLPreferences.Indent = indent
yqlib.ConfiguredYamlPreferences.Indent = indent
yqlib.ConfiguredJSONPreferences.Indent = indent
yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar
properties.ConfiguredPropertiesPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredPropertiesPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredJSONPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredYamlPreferences.ColorsEnabled = colorsEnabled
+2 -2
View File
@@ -11,7 +11,7 @@ var (
GitDescribe string
// Version is main version number that is being run at the moment.
Version = "v4.42.1"
Version = "v4.45.2"
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
@@ -45,5 +45,5 @@ func getHumanVersion() string {
}
// Strip off any single quotes added by the git information.
return strings.Replace(version, "'", "", -1)
return strings.ReplaceAll(version, "'", "")
}
-210
View File
@@ -1,210 +0,0 @@
yq (4.16.2) focal; urgency=medium
* Fixed with semicolon space issue
* Updating with documentation
* Added STDIN example to the top
* minor readme cleanup
* Help text tweak
* Fixed docker timeout - simplify docker builds
* New release with docker build fixes
* Updating to go 1.17 to fix CVE #944
* Fix a typo in root.go
* Skip the tests if the nocheck Debian build option is specified
* Fixed select bug (#958)
* Sped up explode operator
* Slight performance improvement to context.ChildContext
* Speed up multiply
* Update README with recently added / changed options
* Make deepMatch report in linear time
* Removed leadingContentPreProcessing flag - header preprocessing is stable
* Revert "Removed leadingContentPreProcessing flag - header preprocessing is stable"
* Keep flag, it is needed in corner cases
* Updated Readme
* Man page
* Fixed expression parsing bug #970
* Bumping go-lang, docker versions
* Added test release flow
* Updated github action release to generate man page
* Bumping version
* Removing no longer needed github action
* Added decoder op
* Fixed newline handling when decoding/encoding
* Fixed newline handling in encoder/decoder
* Can specify indent in encode ops
* Added group_by operator
* Added flatten operator
* Fixed flatten error message
* Improving docs
* Split printer
* Refactored command logic
* Fix JSON encoding removing null #985
* Fixed acceptance tests
* gitbook
* Update document generation script
* Updating README
* Updating release instructions
* github action no longer uses data1.yml
* Create dependabot.yml
* Bump actions/create-release from 1.0.0 to 1.1.4
* Bump actions/setup-go from 1 to 2.1.4
* Bump github.com/goccy/go-yaml from 1.8.9 to 1.9.4
* Bump github.com/jinzhu/copier from 0.2.8 to 0.3.2
* Bump github.com/fatih/color from 1.10.0 to 1.13.0
* Bump github.com/spf13/cobra from 1.1.3 to 1.2.1
* Update dependabot.yml
* Update go.yml
* add build check to PRs
* Include secure as part of build process
* Fixing bad label in github action
* fixed printer test
* remove leading content indicator
* Fixed header preprocessing!
* lint : define golangci configuration file
* Update check.sh
* Load file acceptance test
* Minor improvement on handling front matter
* Improved load doc
* feature: detect MANPATh and install there
* Update install-man-page.sh
* simplify prod stage, move version label to action
* add labels, quote some values
* enable errorlint linter
* Added errorlint to devtools
* Added key operator
* Added more tests
* Fixing comments
* Attempt to fix golint problem
* Include version query for tools
* Clean up errored file?
* enable misspell linter
* updated readme
* update Golangci version to v1.43.0
* gci linter
* Better merge array by key example
* Added credit for merge by array example
* Better formatting of merge arrays example
* Better merge example
* Add accessor for the yq logger instance (#1013)
* Fixed collect op when working with multiple nodes
* Added map, map_values
* Add support for Podman as well as Docker (#1026)
* Bump github.com/jinzhu/copier from 0.3.2 to 0.3.4 (#1027)
* Added csv, tsv output formats
* Added encoder tests
* Cleanup test
* Fixed docker permission issue #1014
* Recording release notes for next release
* Assignment op no longer clobbers anchor (#1029)
* Added sort_by operator
* Improved error message
* Improved tips and tricks
* Report while filename failed to parse #1030
* Added script for extracting checksums
* Improved extract-checksum.sh
* Bump github.com/spf13/cobra from 1.2.1 to 1.3.0 (#1039)
* enable more linters (#1043)
* Bump Golang compiler #1037
-- Roberto Mier Escandon <rmescandon@gmail.com> Tue, 21 Dec 2021 09:41:44 +0000
yq (4.13.0) focal; urgency=medium
* New `with` operator for making multiple changes to a given path
* New `contains` operator, works like the `jq` equivalent
* Subtract operator now supports subtracting elements from arrays!
* Fixed Swapping values using variables #934
* Github Action now properly supports multiline output #936, thanks @pjxiao
* Fixed missing closing bracket validation #932
* Fix processing of hex numbers #929
* Fixed alternative and union operator issues #930
* Can now convert yaml to properties properties format (`-o=props`), See [docs](https://mikefarah.gitbook.io/yq/v/v4.x/usage/properties) for more info.
* Fixed document header/footer comment handling when merging (https://github.com/mikefarah/yq/issues/919)
* pretty print yaml 1.1 compatibility (https://github.com/mikefarah/yq/issues/914)
-- Roberto Mier Escandon <rmescandon@gmail.com> Thu, 16 Sep 2021 20:58:30 +0200
yq (4.9.6) focal; urgency=medium
* Added darwin/arm64 build, thanks @alecthomas
* Incremented docker alpine base version, thanks @da6d6i7-bronga
* Bug fix: multiline expression
* Bug fix: special character
-- Roberto Mier Escandon <rmescandon@gmail.com> Tue, 29 Jun 2021 21:32:14 +0200
yq (3.3.2) focal; urgency=medium
* Bug fix: existStatus bug (#459)
* Automatically makes an os temp directory if it does not exist (#461)
-- Roberto Mier Escandon <rmescandon@gmail.com> Fri, 07 Aug 2020 18:53:01 +0200
yq (3.3-0) focal; urgency=medium
* You can control string styles (quotes) using the new --style flag
* String values now always have quotes when outputting to json
* Negative array indices now traverse the array backwards
* Added a --stripComments flag to print yaml without any comments
* Bumped go to version 1.14
-- Roberto Mier Escandon <rmescandon@gmail.com> Thu, 30 Apr 2020 20:45:44 +0200
yq (3.1-2) eoan; urgency=medium
* Bug fix: yq 3 was removing empty inline-style objects and arrays (#355)
* Bug fix: Merge option returned different output when switching order of
merging files(#347)
* Bug fix: Add new object to existing array object was failing in 3.1.1 (#361)
* Bug fix: yq 3 empty keys did not allow merging of values (#356)
* Bug fix: keys quoted during merge (#363)
* Bug fix: Correct length with wc -l (#362)
* Bug fix: Write to empty document removed path (#359)
-- Roberto Mier Escandon <rmescandon@gmail.com> Mon, 24 Feb 2020 20:31:58 +0100
yq (3.1-1) eoan; urgency=medium
* Keeps yaml comments and formatting, can specify yaml tags when updating.
* Handles anchors
* Can print out matching paths and values when splatting
* JSON output works for all commands
* Yaml files with multiple documents are printed out as one JSON
document per line.
* Deep splat (**) to match arbitrary paths
* Update scripts file format has changed to be more powerful
* Reading and splatting, matching results are printed once per line
* Bugfixing
-- Roberto Mier Escandon <rmescandon@gmail.com> Tue, 11 Feb 2020 22:18:24 +0100
yq (2.2-1) bionic; urgency=medium
* Added Windows support for the "--inplace" command flag
* Prefix now supports arrays
* Add prefix command
* Bump Alpine version to 3.8
* Improved docker build process
* Lint fixes
* Build support for all linux architectures supported by gox
-- Roberto Mier Escandon <rmescandon@gmail.com> Sat, 19 Jan 2019 15:50:47 +0100
yq (2.1-0) bionic; urgency=medium
* Ability to read multiple documents in a single file
* Ability to append list items instead of overwriting
-- Roberto Mier Escandón <rmescandon@gmail.com> Tue, 10 Jul 2018 14:02:42 +0200
yq (2.0-0) bionic; urgency=medium
* Release 2.0.0
-- Roberto Mier Escandón <rmescandon@gmail.com> Wed, 20 Jun 2018 10:29:53 +0200
yq (1.15-0) bionic; urgency=medium
* Release 1.15
-- Roberto Mier Escandón <rmescandon@gmail.com> Wed, 06 Jun 2018 11:32:03 +0200
-1
View File
@@ -1 +0,0 @@
10
-22
View File
@@ -1,22 +0,0 @@
Source: yq
Section: devel
Priority: optional
Maintainer: Roberto Mier Escandón <rmescandon@gmail.com>
Build-Depends: debhelper (>=10),
golang-1.17-go,
pandoc,
rsync
Standards-Version: 4.1.4
Homepage: https://github.com/mikefarah/yq.git
Vcs-Browser: https://github.com/mikefarah/yq.git
Vcs-Git: https://github.com/mikefarah/yq.git
XS-Go-Import-Path: github.com/mikefarah/yq
XSBC-Original-Maintainer: Roberto Mier Escandón <rmescandon@gmail.com>
Package: yq
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: lightweight and portable command-line data file processor
.
The aim of the project is to be the
[jq](https://github.com/stedolan/jq) or sed of yaml files.
-24
View File
@@ -1,24 +0,0 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: yq
Source: https://github.com/mikefarah/yq.git
Files: *
Copyright: 2017 Mike Farah
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-2
View File
@@ -1,2 +0,0 @@
[DEFAULT]
pristine-tar = True
-74
View File
@@ -1,74 +0,0 @@
#!/usr/bin/make -f
#
# Copyright (C) 2018-2021 Roberto Mier Escandón <rmescandon@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
PROJECT := yq
OWNER := mikefarah
REPO := github.com
export DH_OPTIONS
export DH_GOPKG := ${REPO}/${OWNER}/${PROJECT}
export GOROOT := /usr/local/go
export GOPATH := ${CURDIR}/_build
export GOBIN := ${GOPATH}/bin
export PATH := ${GOROOT}/bin:${GOBIN}:${PATH}
export GOCACHE := /tmp/gocache
export GOFLAGS := -mod=vendor
export GO111MODULE := on
SRCDIR := ${GOPATH}/src/${DH_GOPKG}
DESTDIR := ${CURDIR}/debian/${PROJECT}
BINDIR := /usr/bin
MANDIR := /usr/share/man/man1/
ASSETSDIR := /usr/share/${PROJECT}
%:
dh $@
override_dh_auto_build:
mkdir -p ${SRCDIR}
mkdir -p ${GOBIN}
# copy project to local srcdir to build from there
rsync -avz --progress --exclude=_build --exclude=debian --exclude=tmp. --exclude=go.mod --exclude=docs . $(SRCDIR)
# build go code
( \
cd ${SRCDIR} && \
go install -buildmode=pie ./... \
)
# build man page
( \
cd ${SRCDIR} && \
./scripts/generate-man-page-md.sh && \
./scripts/generate-man-page.sh \
)
override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
(cd ${SRCDIR} && go test -v ./...)
endif
override_dh_auto_install:
cp ${GOBIN}/yq ${DESTDIR}/${BINDIR}
cp -f ${SRCDIR}/LICENSE ${DESTDIR}/${ASSETSDIR}
chmod a+x ${DESTDIR}/${BINDIR}/yq
# man
mkdir -p "${DESTDIR}"/"${MANDIR}"
cp "${SRCDIR}"/yq.1 "${DESTDIR}"/"${MANDIR}" \
override_dh_auto_clean:
dh_clean
rm -rf ${CURDIR}/_build
-1
View File
@@ -1 +0,0 @@
3.0 (native)
-3
View File
@@ -1,3 +0,0 @@
usr/bin
usr/share/yq
usr/share/man/man1
+3 -11
View File
@@ -1,11 +1,3 @@
# block comments come through
person: # neither do comments on maps
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
- dog # comments on array values appear
- things:
- frog
food: [pizza] # comments on arrays do not
emptyArray: []
emptyMap: []
Foo: 3
apple: 1
bar: 2
+13 -14
View File
@@ -2,22 +2,22 @@ module github.com/mikefarah/yq/v4
require (
github.com/a8m/envsubst v1.4.2
github.com/alecthomas/participle/v2 v2.1.1
github.com/alecthomas/participle/v2 v2.1.4
github.com/alecthomas/repr v0.4.0
github.com/dimchansky/utfbom v1.1.1
github.com/elliotchance/orderedmap v1.5.1
github.com/fatih/color v1.16.0
github.com/goccy/go-json v0.10.2
github.com/goccy/go-yaml v1.11.3
github.com/elliotchance/orderedmap v1.8.0
github.com/fatih/color v1.18.0
github.com/goccy/go-json v0.10.5
github.com/goccy/go-yaml v1.13.3
github.com/jinzhu/copier v0.4.0
github.com/magiconair/properties v1.8.7
github.com/pelletier/go-toml/v2 v2.1.1
github.com/magiconair/properties v1.8.10
github.com/pelletier/go-toml/v2 v2.2.3
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/yuin/gopher-lua v1.1.1
golang.org/x/net v0.22.0
golang.org/x/text v0.14.0
golang.org/x/net v0.39.0
golang.org/x/text v0.24.0
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
gopkg.in/yaml.v3 v3.0.1
)
@@ -26,8 +26,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
golang.org/x/sys v0.32.0 // indirect
)
go 1.21
go 1.23.0
+43 -47
View File
@@ -1,81 +1,77 @@
github.com/a8m/envsubst v1.4.2 h1:4yWIHXOLEJHQEFd4UjrWDrYeYlV7ncFWJOCBRLOZHQg=
github.com/a8m/envsubst v1.4.2/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY=
github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0=
github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8=
github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/participle/v2 v2.1.4 h1:W/H79S8Sat/krZ3el6sQMvMaahJ+XcM9WSI2naI7w2U=
github.com/alecthomas/participle/v2 v2.1.4/go.mod h1:8tqVbpTX20Ru4NfYQgZf4mP18eXPTBViyMWiArNEgGI=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/elliotchance/orderedmap v1.5.1 h1:G1X4PYlljzimbdQ3RXmtIZiQ9d6aRQ3sH1nzjq5mECE=
github.com/elliotchance/orderedmap v1.5.1/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I=
github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/elliotchance/orderedmap v1.8.0 h1:TrOREecvh3JbS+NCgwposXG5ZTFHtEsQiCGOhPElnMw=
github.com/elliotchance/orderedmap v1.8.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
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.13.3 h1:IXRULR8mAa0MXQobzzp0VOfMUJ8EnaQ4x3jhf7S0/nI=
github.com/goccy/go-yaml v1.13.3/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
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=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
-45
View File
@@ -1,45 +0,0 @@
package properties
import "github.com/mikefarah/yq/v4/pkg/yqlib"
type PropertiesPreferences struct {
UnwrapScalar bool
KeyValueSeparator string
UseArrayBrackets bool
}
func NewDefaultPropertiesPreferences() PropertiesPreferences {
return PropertiesPreferences{
UnwrapScalar: true,
KeyValueSeparator: " = ",
UseArrayBrackets: false,
}
}
func (p *PropertiesPreferences) Copy() PropertiesPreferences {
return PropertiesPreferences{
UnwrapScalar: p.UnwrapScalar,
KeyValueSeparator: p.KeyValueSeparator,
UseArrayBrackets: p.UseArrayBrackets,
}
}
var PropertiesFormat = &yqlib.Format{"props", []string{"p", "properties"}, "properties",
func() yqlib.Encoder { return NewPropertiesEncoder(ConfiguredPropertiesPreferences) },
func() yqlib.Decoder { return NewPropertiesDecoder() },
nil,
}
var propertyYqRules = []*yqlib.ParticipleYqRule{
{"PropertiesDecode", `from_?props|@propsd`, yqlib.CreateDecodeOpYqAction(PropertiesFormat), 0},
{"PropsEncode", `to_?props|@props`, yqlib.CreateEncodeOpYqAction(PropertiesFormat, 2), 0},
{"LoadProperties", `load_?props`, yqlib.CreateLoadOpYqAction(NewPropertiesDecoder()), 0},
}
func RegisterPropertiesFormat() {
yqlib.RegisterFormat(PropertiesFormat)
yqlib.RegisterRules(propertyYqRules)
}
var ConfiguredPropertiesPreferences = NewDefaultPropertiesPreferences()
+1 -1
View File
@@ -63,7 +63,7 @@ func (e *allAtOnceEvaluator) EvaluateFiles(expression string, filenames []string
}
if allDocuments.Len() == 0 {
candidateNode := CreateScalarNode(nil, "")
candidateNode := createScalarNode(nil, "")
allDocuments.PushBack(candidateNode)
}
+32 -39
View File
@@ -27,14 +27,14 @@ const (
FlowStyle
)
func CreateStringScalarNode(stringValue string) *CandidateNode {
func createStringScalarNode(stringValue string) *CandidateNode {
var node = &CandidateNode{Kind: ScalarNode}
node.Value = stringValue
node.Tag = "!!str"
return node
}
func CreateScalarNode(value interface{}, stringValue string) *CandidateNode {
func createScalarNode(value interface{}, stringValue string) *CandidateNode {
var node = &CandidateNode{Kind: ScalarNode}
node.Value = stringValue
@@ -198,6 +198,30 @@ func (n *CandidateNode) SetParent(parent *CandidateNode) {
n.Parent = parent
}
type ValueVisitor func(*CandidateNode) error
func (n *CandidateNode) VisitValues(visitor ValueVisitor) error {
switch n.Kind {
case MappingNode:
for i := 1; i < len(n.Content); i = i + 2 {
if err := visitor(n.Content[i]); err != nil {
return err
}
}
case SequenceNode:
for i := 0; i < len(n.Content); i = i + 1 {
if err := visitor(n.Content[i]); err != nil {
return err
}
}
}
return nil
}
func (n *CandidateNode) CanVisitValues() bool {
return n.Kind == MappingNode || n.Kind == SequenceNode
}
func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawValue *CandidateNode) (*CandidateNode, *CandidateNode) {
key := rawKey.Copy()
key.SetParent(n)
@@ -219,7 +243,7 @@ func (n *CandidateNode) AddChild(rawChild *CandidateNode) {
value.Key.SetParent(n)
} else {
index := len(n.Content)
keyNode := CreateScalarNode(index, fmt.Sprintf("%v", index))
keyNode := createScalarNode(index, fmt.Sprintf("%v", index))
keyNode.SetParent(n)
value.Key = keyNode
}
@@ -243,7 +267,7 @@ func (n *CandidateNode) AddChildren(children []*CandidateNode) {
func (n *CandidateNode) GetValueRep() (interface{}, error) {
log.Debugf("GetValueRep for %v value: %v", n.GetNicePath(), n.Value)
realTag := n.GuessTagFromCustomType()
realTag := n.guessTagFromCustomType()
switch realTag {
case "!!int":
@@ -261,17 +285,17 @@ func (n *CandidateNode) GetValueRep() (interface{}, error) {
return n.Value, nil
}
func (n *CandidateNode) GuessTagFromCustomType() string {
func (n *CandidateNode) guessTagFromCustomType() string {
if strings.HasPrefix(n.Tag, "!!") {
return n.Tag
} else if n.Value == "" {
log.Debug("GuessTagFromCustomType: node has no value to guess the type with")
log.Debug("guessTagFromCustomType: node has no value to guess the type with")
return n.Tag
}
dataBucket, errorReading := parseSnippet(n.Value)
if errorReading != nil {
log.Debug("GuessTagFromCustomType: could not guess underlying tag type %v", errorReading)
log.Debug("guessTagFromCustomType: could not guess underlying tag type %v", errorReading)
return n.Tag
}
guessedTag := dataBucket.Tag
@@ -376,7 +400,7 @@ func (n *CandidateNode) UpdateFrom(other *CandidateNode, prefs assignPreferences
// if this is an empty map or empty array, use the style of other node.
if (n.Kind != ScalarNode && len(n.Content) == 0) ||
// if the tag has changed (e.g. from str to bool)
(n.GuessTagFromCustomType() != other.GuessTagFromCustomType()) {
(n.guessTagFromCustomType() != other.guessTagFromCustomType()) {
n.Style = other.Style
}
@@ -428,34 +452,3 @@ func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, prefs assignP
n.LineComment = other.LineComment
}
}
func (n *CandidateNode) CleanHeadAndLineComment() string {
return n.CleanHeadComment() + n.CleanLineComment()
}
func (n *CandidateNode) CleanHeadComment() string {
return strings.Replace(n.HeadComment, "#", "", 1)
}
func (n *CandidateNode) CleanLineComment() string {
return strings.Replace(n.LineComment, "#", "", 1)
}
func (n *CandidateNode) CleanFootComment() string {
return strings.Replace(n.FootComment, "#", "", 1)
}
func (n *CandidateNode) ConvertKeysToStrings() {
if n.Kind == MappingNode {
for index, child := range n.Content {
if index%2 == 0 { // its a map key
child.Tag = "!!str"
}
}
}
for _, child := range n.Content {
child.ConvertKeysToStrings()
}
}
+8 -8
View File
@@ -64,13 +64,13 @@ func TestCandidateNodeChildWhenParentUpdated(t *testing.T) {
test.AssertResultWithContext(t, uint(1), child.GetDocument(), "document index")
}
type CreateScalarNodeScenario struct {
type createScalarNodeScenario struct {
value interface{}
stringValue string
expectedTag string
}
var createScalarScenarios = []CreateScalarNodeScenario{
var createScalarScenarios = []createScalarNodeScenario{
{
value: "mike",
stringValue: "mike",
@@ -100,20 +100,20 @@ var createScalarScenarios = []CreateScalarNodeScenario{
func TestCreateScalarNodeScenarios(t *testing.T) {
for _, tt := range createScalarScenarios {
actual := CreateScalarNode(tt.value, tt.stringValue)
actual := createScalarNode(tt.value, tt.stringValue)
test.AssertResultWithContext(t, tt.stringValue, actual.Value, fmt.Sprintf("Value for: Value: [%v], String: %v", tt.value, tt.stringValue))
test.AssertResultWithContext(t, tt.expectedTag, actual.Tag, fmt.Sprintf("Value for: Value: [%v], String: %v", tt.value, tt.stringValue))
}
}
func TestGetKeyForMapValue(t *testing.T) {
key := CreateStringScalarNode("yourKey")
key := createStringScalarNode("yourKey")
n := CandidateNode{Key: key, Value: "meow", document: 3}
test.AssertResult(t, "3 - yourKey", n.GetKey())
}
func TestGetKeyForMapKey(t *testing.T) {
key := CreateStringScalarNode("yourKey")
key := createStringScalarNode("yourKey")
key.IsMapKey = true
key.document = 3
test.AssertResult(t, "key-yourKey-3 - ", key.GetKey())
@@ -125,7 +125,7 @@ func TestGetKeyForValue(t *testing.T) {
}
func TestGetParsedKeyForMapKey(t *testing.T) {
key := CreateStringScalarNode("yourKey")
key := createStringScalarNode("yourKey")
key.IsMapKey = true
key.document = 3
test.AssertResult(t, "yourKey", key.getParsedKey())
@@ -137,13 +137,13 @@ func TestGetParsedKeyForLooseValue(t *testing.T) {
}
func TestGetParsedKeyForMapValue(t *testing.T) {
key := CreateStringScalarNode("yourKey")
key := createStringScalarNode("yourKey")
n := CandidateNode{Key: key, Value: "meow", document: 3}
test.AssertResult(t, "yourKey", n.getParsedKey())
}
func TestGetParsedKeyForArrayValue(t *testing.T) {
key := CreateScalarNode(4, "4")
key := createScalarNode(4, "4")
n := CandidateNode{Key: key, Value: "meow", document: 3}
test.AssertResult(t, 4, n.getParsedKey())
}
+1 -1
View File
@@ -96,7 +96,7 @@ func (o *CandidateNode) UnmarshalJSON(data []byte) error {
if child == nil {
// need to represent it as a null scalar
child = CreateScalarNode(nil, "null")
child = createScalarNode(nil, "null")
}
childKey := o.CreateChild()
childKey.Kind = ScalarNode
+1 -1
View File
@@ -7,6 +7,6 @@ import (
"os"
)
func changeOwner(info fs.FileInfo, file *os.File) error {
func changeOwner(_ fs.FileInfo, _ *os.File) error {
return nil
}
+6
View File
@@ -56,6 +56,12 @@ func colorizeAndPrint(yamlBytes []byte, writer io.Writer) error {
Suffix: format(color.Reset),
}
}
p.Comment = func() *printer.Property {
return &printer.Property{
Prefix: format(color.FgHiBlack),
Suffix: format(color.Reset),
}
}
_, err := writer.Write([]byte(p.PrintTokens(tokens) + "\n"))
return err
}
-3111
View File
File diff suppressed because it is too large Load Diff
+21 -7
View File
@@ -94,7 +94,7 @@ const tsvTestExpectedSimpleCsv = `i like csv
because excel is cool
`
var csvScenarios = []FormatScenario{
var csvScenarios = []formatScenario{
{
description: "Encode CSV simple",
input: csvTestSimpleYaml,
@@ -186,6 +186,20 @@ var csvScenarios = []FormatScenario{
expected: expectedYamlFromCSVNoParsing,
scenarioType: "decode-csv-no-auto",
},
{
description: "values starting with #, no auto parse",
skipDoc: true,
input: "value\n#ffff",
expected: "- value: '#ffff'\n",
scenarioType: "decode-csv-no-auto",
},
{
description: "values starting with #",
skipDoc: true,
input: "value\n#ffff",
expected: "- value: #ffff\n",
scenarioType: "decode-csv",
},
{
description: "Scalar roundtrip",
skipDoc: true,
@@ -210,7 +224,7 @@ var csvScenarios = []FormatScenario{
},
}
func testCSVScenario(t *testing.T, s FormatScenario) {
func testCSVScenario(t *testing.T, s formatScenario) {
switch s.scenarioType {
case "encode-csv":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder(ConfiguredCsvPreferences)), s.description)
@@ -229,7 +243,7 @@ func testCSVScenario(t *testing.T, s FormatScenario) {
}
}
func documentCSVDecodeObjectScenario(w *bufio.Writer, s FormatScenario, formatType string) {
func documentCSVDecodeObjectScenario(w *bufio.Writer, s formatScenario, formatType string) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -254,7 +268,7 @@ func documentCSVDecodeObjectScenario(w *bufio.Writer, s FormatScenario, formatTy
)
}
func documentCSVDecodeObjectNoAutoScenario(w *bufio.Writer, s FormatScenario, formatType string) {
func documentCSVDecodeObjectNoAutoScenario(w *bufio.Writer, s formatScenario, formatType string) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -279,7 +293,7 @@ func documentCSVDecodeObjectNoAutoScenario(w *bufio.Writer, s FormatScenario, fo
)
}
func documentCSVEncodeScenario(w *bufio.Writer, s FormatScenario, formatType string) {
func documentCSVEncodeScenario(w *bufio.Writer, s formatScenario, formatType string) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -312,7 +326,7 @@ func documentCSVEncodeScenario(w *bufio.Writer, s FormatScenario, formatType str
)
}
func documentCSVRoundTripScenario(w *bufio.Writer, s FormatScenario, formatType string) {
func documentCSVRoundTripScenario(w *bufio.Writer, s formatScenario, formatType string) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -348,7 +362,7 @@ func documentCSVRoundTripScenario(w *bufio.Writer, s FormatScenario, formatType
}
func documentCSVScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
s := i.(FormatScenario)
s := i.(formatScenario)
if s.skipDoc {
return
}
+2 -11
View File
@@ -13,7 +13,6 @@ type DataTreeNavigator interface {
GetMatchingNodes(context Context, expressionNode *ExpressionNode) (Context, error)
DeeplyAssign(context Context, path []interface{}, rhsNode *CandidateNode) error
DeeplyAssignKey(context Context, path []interface{}, rhsNode *CandidateNode) error
}
type dataTreeNavigator struct {
@@ -24,14 +23,6 @@ func NewDataTreeNavigator() DataTreeNavigator {
}
func (d *dataTreeNavigator) DeeplyAssign(context Context, path []interface{}, rhsCandidateNode *CandidateNode) error {
return d.deeplyAssign(context, path, rhsCandidateNode, false)
}
func (d *dataTreeNavigator) DeeplyAssignKey(context Context, path []interface{}, rhsCandidateNode *CandidateNode) error {
return d.deeplyAssign(context, path, rhsCandidateNode, true)
}
func (d *dataTreeNavigator) deeplyAssign(context Context, path []interface{}, rhsCandidateNode *CandidateNode, targetKey bool) error {
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
@@ -50,7 +41,7 @@ func (d *dataTreeNavigator) deeplyAssign(context Context, path []interface{}, rh
assignmentOpNode := &ExpressionNode{
Operation: assignmentOp,
LHS: createTraversalTree(path, traversePreferences{}, targetKey),
LHS: createTraversalTree(path, traversePreferences{}, false),
RHS: &ExpressionNode{Operation: rhsOp},
}
@@ -73,6 +64,6 @@ func (d *dataTreeNavigator) GetMatchingNodes(context Context, expressionNode *Ex
if handler != nil {
return handler(d, context, expressionNode)
}
return Context{}, fmt.Errorf("Unknown operator %v", expressionNode.Operation.OperationType)
return Context{}, fmt.Errorf("unknown operator %v", expressionNode.Operation.OperationType)
}
+5 -5
View File
@@ -8,20 +8,20 @@ import (
)
type base64Padder struct {
count uint64
count int
io.Reader
}
func (c *base64Padder) pad(buf []byte) (int, error) {
pad := strings.Repeat("=", int(4-c.count%4))
pad := strings.Repeat("=", (4 - c.count%4))
n, err := strings.NewReader(pad).Read(buf)
c.count += uint64(n)
c.count += n
return n, err
}
func (c *base64Padder) Read(buf []byte) (int, error) {
n, err := c.Reader.Read(buf)
c.count += uint64(n)
c.count += n
if err == io.EOF && c.count%4 != 0 {
return c.pad(buf)
@@ -68,5 +68,5 @@ func (dec *base64Decoder) Decode() (*CandidateNode, error) {
}
}
dec.readAnything = true
return CreateStringScalarNode(buf.String()), nil
return createStringScalarNode(buf.String()), nil
}
+3 -3
View File
@@ -31,8 +31,8 @@ func (dec *csvObjectDecoder) convertToNode(content string) *CandidateNode {
node, err := parseSnippet(content)
// if we're not auto-parsing, then we wont put in parsed objects or arrays
// but we still parse scalars
if err != nil || (!dec.prefs.AutoParse && node.Kind != ScalarNode) {
return CreateScalarNode(content, content)
if err != nil || (!dec.prefs.AutoParse && (node.Kind != ScalarNode || node.Value != content)) {
return createScalarNode(content, content)
}
return node
}
@@ -41,7 +41,7 @@ func (dec *csvObjectDecoder) createObject(headerRow []string, contentRow []strin
objectNode := &CandidateNode{Kind: MappingNode, Tag: "!!map"}
for i, header := range headerRow {
objectNode.AddKeyValueChild(CreateScalarNode(header, header), dec.convertToNode(contentRow[i]))
objectNode.AddKeyValueChild(createScalarNode(header, header), dec.convertToNode(contentRow[i]))
}
return objectNode
}
@@ -1,4 +1,4 @@
package properties
package yqlib
import (
"bytes"
@@ -8,17 +8,16 @@ import (
"strings"
"github.com/magiconair/properties"
"github.com/mikefarah/yq/v4/pkg/yqlib"
)
type propertiesDecoder struct {
reader io.Reader
finished bool
d yqlib.DataTreeNavigator
d DataTreeNavigator
}
func NewPropertiesDecoder() yqlib.Decoder {
return &propertiesDecoder{d: yqlib.NewDataTreeNavigator(), finished: false}
func NewPropertiesDecoder() Decoder {
return &propertiesDecoder{d: NewDataTreeNavigator(), finished: false}
}
func (dec *propertiesDecoder) Init(reader io.Reader) error {
@@ -48,18 +47,31 @@ func (dec *propertiesDecoder) processComment(c string) string {
return "# " + c
}
func (dec *propertiesDecoder) applyPropertyComments(context yqlib.Context, path []interface{}, comments []string) error {
rhsCandidateNode := &yqlib.CandidateNode{
func (dec *propertiesDecoder) applyPropertyComments(context Context, path []interface{}, comments []string) error {
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
rhsCandidateNode := &CandidateNode{
Tag: "!!str",
Value: fmt.Sprintf("%v", path[len(path)-1]),
HeadComment: dec.processComment(strings.Join(comments, "\n")),
Kind: yqlib.ScalarNode,
Kind: ScalarNode,
}
rhsCandidateNode.Tag = rhsCandidateNode.GuessTagFromCustomType()
return dec.d.DeeplyAssignKey(context, path, rhsCandidateNode)
rhsCandidateNode.Tag = rhsCandidateNode.guessTagFromCustomType()
rhsOp := &Operation{OperationType: referenceOpType, CandidateNode: rhsCandidateNode}
assignmentOpNode := &ExpressionNode{
Operation: assignmentOp,
LHS: createTraversalTree(path, traversePreferences{}, true),
RHS: &ExpressionNode{Operation: rhsOp},
}
_, err := dec.d.GetMatchingNodes(context, assignmentOpNode)
return err
}
func (dec *propertiesDecoder) applyProperty(context yqlib.Context, properties *properties.Properties, key string) error {
func (dec *propertiesDecoder) applyProperty(context Context, properties *properties.Properties, key string) error {
value, _ := properties.Get(key)
path := parsePropKey(key)
@@ -71,13 +83,13 @@ func (dec *propertiesDecoder) applyProperty(context yqlib.Context, properties *p
}
}
rhsNode := yqlib.CreateStringScalarNode(value)
rhsNode.Tag = rhsNode.GuessTagFromCustomType()
rhsNode := createStringScalarNode(value)
rhsNode.Tag = rhsNode.guessTagFromCustomType()
return dec.d.DeeplyAssign(context, path, rhsNode)
}
func (dec *propertiesDecoder) Decode() (*yqlib.CandidateNode, error) {
func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {
if dec.finished {
return nil, io.EOF
}
@@ -96,12 +108,12 @@ func (dec *propertiesDecoder) Decode() (*yqlib.CandidateNode, error) {
}
properties.DisableExpansion = true
rootMap := &yqlib.CandidateNode{
Kind: yqlib.MappingNode,
rootMap := &CandidateNode{
Kind: MappingNode,
Tag: "!!map",
}
context := yqlib.Context{}
context := Context{}
context = context.SingleChildContext(rootMap)
for _, key := range properties.Keys() {
+3 -3
View File
@@ -7,7 +7,7 @@ import (
"strings"
)
type FormatScenario struct {
type formatScenario struct {
input string
indent int
expression string
@@ -19,7 +19,7 @@ type FormatScenario struct {
expectedError string
}
func processFormatScenario(s FormatScenario, decoder Decoder, encoder Encoder) (string, error) {
func processFormatScenario(s formatScenario, decoder Decoder, encoder Encoder) (string, error) {
var output bytes.Buffer
writer := bufio.NewWriter(&output)
@@ -64,7 +64,7 @@ func processFormatScenario(s FormatScenario, decoder Decoder, encoder Encoder) (
return output.String(), nil
}
func mustProcessFormatScenario(s FormatScenario, decoder Decoder, encoder Encoder) string {
func mustProcessFormatScenario(s formatScenario, decoder Decoder, encoder Encoder) string {
result, err := processFormatScenario(s, decoder, encoder)
if err != nil {
+11 -10
View File
@@ -145,30 +145,30 @@ func (dec *tomlDecoder) createArray(tomlNode *toml.Node) (*CandidateNode, error)
func (dec *tomlDecoder) createStringScalar(tomlNode *toml.Node) (*CandidateNode, error) {
content := string(tomlNode.Data)
return CreateScalarNode(content, content), nil
return createScalarNode(content, content), nil
}
func (dec *tomlDecoder) createBoolScalar(tomlNode *toml.Node) (*CandidateNode, error) {
content := string(tomlNode.Data)
return CreateScalarNode(content == "true", content), nil
return createScalarNode(content == "true", content), nil
}
func (dec *tomlDecoder) createIntegerScalar(tomlNode *toml.Node) (*CandidateNode, error) {
content := string(tomlNode.Data)
_, num, err := parseInt64(content)
return CreateScalarNode(num, content), err
return createScalarNode(num, content), err
}
func (dec *tomlDecoder) createDateTimeScalar(tomlNode *toml.Node) (*CandidateNode, error) {
content := string(tomlNode.Data)
val, err := parseDateTime(time.RFC3339, content)
return CreateScalarNode(val, content), err
return createScalarNode(val, content), err
}
func (dec *tomlDecoder) createFloatScalar(tomlNode *toml.Node) (*CandidateNode, error) {
content := string(tomlNode.Data)
num, err := strconv.ParseFloat(content, 64)
return CreateScalarNode(num, content), err
return createScalarNode(num, content), err
}
func (dec *tomlDecoder) decodeNode(tomlNode *toml.Node) (*CandidateNode, error) {
@@ -249,11 +249,12 @@ func (dec *tomlDecoder) processTopLevelNode(currentNode *toml.Node) (bool, error
var runAgainstCurrentExp bool
var err error
log.Debug("processTopLevelNode: Going to process %v state is current %v", currentNode.Kind, NodeToString(dec.rootMap))
if currentNode.Kind == toml.Table {
switch currentNode.Kind {
case toml.Table:
runAgainstCurrentExp, err = dec.processTable(currentNode)
} else if currentNode.Kind == toml.ArrayTable {
case toml.ArrayTable:
runAgainstCurrentExp, err = dec.processArrayTable(currentNode)
} else {
default:
runAgainstCurrentExp, err = dec.decodeKeyValuesIntoMap(dec.rootMap, currentNode)
}
@@ -286,7 +287,7 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
}
runAgainstCurrentExp, err = dec.decodeKeyValuesIntoMap(tableNodeValue, tableValue)
if err != nil && !errors.Is(io.EOF, err) {
if err != nil && !errors.Is(err, io.EOF) {
return false, err
}
}
@@ -343,7 +344,7 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
tableValue := dec.parser.Expression()
runAgainstCurrentExp, err := dec.decodeKeyValuesIntoMap(tableNodeValue, tableValue)
log.Debugf("table node err: %w", err)
if err != nil && !errors.Is(io.EOF, err) {
if err != nil && !errors.Is(err, io.EOF) {
return false, err
}
c := Context{}
+1 -1
View File
@@ -48,5 +48,5 @@ func (dec *uriDecoder) Decode() (*CandidateNode, error) {
return nil, err
}
dec.readAnything = true
return CreateStringScalarNode(newValue), nil
return createStringScalarNode(newValue), nil
}
@@ -1,6 +1,6 @@
//go:build !yq_noxml
package xml
package yqlib
import (
"encoding/xml"
@@ -11,7 +11,6 @@ import (
"strings"
"unicode"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"golang.org/x/net/html/charset"
)
@@ -22,7 +21,7 @@ type xmlDecoder struct {
prefs XmlPreferences
}
func NewXMLDecoder(prefs XmlPreferences) yqlib.Decoder {
func NewXMLDecoder(prefs XmlPreferences) Decoder {
return &xmlDecoder{
finished: false,
prefs: prefs,
@@ -36,8 +35,8 @@ func (dec *xmlDecoder) Init(reader io.Reader) error {
return nil
}
func (dec *xmlDecoder) createSequence(nodes []*xmlNode) (*yqlib.CandidateNode, error) {
yamlNode := &yqlib.CandidateNode{Kind: yqlib.SequenceNode, Tag: "!!seq"}
func (dec *xmlDecoder) createSequence(nodes []*xmlNode) (*CandidateNode, error) {
yamlNode := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
for _, child := range nodes {
yamlChild, err := dec.convertToYamlNode(child)
if err != nil {
@@ -64,14 +63,14 @@ func (dec *xmlDecoder) processComment(c string) string {
return replacement
}
func (dec *xmlDecoder) createMap(n *xmlNode) (*yqlib.CandidateNode, error) {
yqlib.GetLogger().Debug("createMap: headC: %v, lineC: %v, footC: %v", n.HeadComment, n.LineComment, n.FootComment)
yamlNode := &yqlib.CandidateNode{Kind: yqlib.MappingNode, Tag: "!!map"}
func (dec *xmlDecoder) createMap(n *xmlNode) (*CandidateNode, error) {
log.Debug("createMap: headC: %v, lineC: %v, footC: %v", n.HeadComment, n.LineComment, n.FootComment)
yamlNode := &CandidateNode{Kind: MappingNode, Tag: "!!map"}
if len(n.Data) > 0 {
yqlib.GetLogger().Debugf("creating content node for map: %v", dec.prefs.ContentName)
log.Debugf("creating content node for map: %v", dec.prefs.ContentName)
label := dec.prefs.ContentName
labelNode := yqlib.CreateScalarNode(label, label)
labelNode := createScalarNode(label, label)
labelNode.HeadComment = dec.processComment(n.HeadComment)
labelNode.LineComment = dec.processComment(n.LineComment)
labelNode.FootComment = dec.processComment(n.FootComment)
@@ -81,19 +80,19 @@ func (dec *xmlDecoder) createMap(n *xmlNode) (*yqlib.CandidateNode, error) {
for i, keyValuePair := range n.Children {
label := keyValuePair.K
children := keyValuePair.V
labelNode := yqlib.CreateScalarNode(label, label)
var valueNode *yqlib.CandidateNode
labelNode := createScalarNode(label, label)
var valueNode *CandidateNode
var err error
if i == 0 {
yqlib.GetLogger().Debugf("head comment here")
log.Debugf("head comment here")
labelNode.HeadComment = dec.processComment(n.HeadComment)
}
yqlib.GetLogger().Debugf("label=%v, i=%v, keyValuePair.FootComment: %v", label, i, keyValuePair.FootComment)
log.Debugf("label=%v, i=%v, keyValuePair.FootComment: %v", label, i, keyValuePair.FootComment)
labelNode.FootComment = dec.processComment(keyValuePair.FootComment)
yqlib.GetLogger().Debug("len of children in %v is %v", label, len(children))
log.Debug("len of children in %v is %v", label, len(children))
if len(children) > 1 {
valueNode, err = dec.createSequence(children)
if err != nil {
@@ -106,7 +105,7 @@ func (dec *xmlDecoder) createMap(n *xmlNode) (*yqlib.CandidateNode, error) {
if len(children[0].Children) == 0 && children[0].HeadComment != "" {
if len(children[0].Data) > 0 {
yqlib.GetLogger().Debug("scalar comment hack, currentlabel [%v]", labelNode.HeadComment)
log.Debug("scalar comment hack, currentlabel [%v]", labelNode.HeadComment)
labelNode.HeadComment = joinComments([]string{labelNode.HeadComment, strings.TrimSpace(children[0].HeadComment)}, "\n")
children[0].HeadComment = ""
} else {
@@ -126,33 +125,33 @@ func (dec *xmlDecoder) createMap(n *xmlNode) (*yqlib.CandidateNode, error) {
return yamlNode, nil
}
func (dec *xmlDecoder) createValueNodeFromData(values []string) *yqlib.CandidateNode {
func (dec *xmlDecoder) createValueNodeFromData(values []string) *CandidateNode {
switch len(values) {
case 0:
return yqlib.CreateScalarNode(nil, "")
return createScalarNode(nil, "")
case 1:
return yqlib.CreateScalarNode(values[0], values[0])
return createScalarNode(values[0], values[0])
default:
content := make([]*yqlib.CandidateNode, 0)
content := make([]*CandidateNode, 0)
for _, value := range values {
content = append(content, yqlib.CreateScalarNode(value, value))
content = append(content, createScalarNode(value, value))
}
return &yqlib.CandidateNode{
Kind: yqlib.SequenceNode,
return &CandidateNode{
Kind: SequenceNode,
Tag: "!!seq",
Content: content,
}
}
}
func (dec *xmlDecoder) convertToYamlNode(n *xmlNode) (*yqlib.CandidateNode, error) {
func (dec *xmlDecoder) convertToYamlNode(n *xmlNode) (*CandidateNode, error) {
if len(n.Children) > 0 {
return dec.createMap(n)
}
scalar := dec.createValueNodeFromData(n.Data)
yqlib.GetLogger().Debug("scalar (%v), headC: %v, lineC: %v, footC: %v", scalar.Tag, n.HeadComment, n.LineComment, n.FootComment)
log.Debug("scalar (%v), headC: %v, lineC: %v, footC: %v", scalar.Tag, n.HeadComment, n.LineComment, n.FootComment)
scalar.HeadComment = dec.processComment(n.HeadComment)
scalar.LineComment = dec.processComment(n.LineComment)
if scalar.Tag == "!!seq" {
@@ -165,7 +164,7 @@ func (dec *xmlDecoder) convertToYamlNode(n *xmlNode) (*yqlib.CandidateNode, erro
return scalar, nil
}
func (dec *xmlDecoder) Decode() (*yqlib.CandidateNode, error) {
func (dec *xmlDecoder) Decode() (*CandidateNode, error) {
if dec.finished {
return nil, io.EOF
}
@@ -212,17 +211,17 @@ func (n *xmlNode) AddChild(s string, c *xmlNode) {
if n.Children == nil {
n.Children = make([]*xmlChildrenKv, 0)
}
yqlib.GetLogger().Debug("looking for %s", s)
log.Debug("looking for %s", s)
// see if we can find an existing entry to add to
for _, childEntry := range n.Children {
if childEntry.K == s {
yqlib.GetLogger().Debug("found it, appending an entry%s", s)
log.Debug("found it, appending an entry%s", s)
childEntry.V = append(childEntry.V, c)
yqlib.GetLogger().Debug("yay len of children in %v is %v", s, len(childEntry.V))
log.Debug("yay len of children in %v is %v", s, len(childEntry.V))
return
}
}
yqlib.GetLogger().Debug("not there, making a new one %s", s)
log.Debug("not there, making a new one %s", s)
n.Children = append(n.Children, &xmlChildrenKv{K: s, V: []*xmlNode{c}})
}
@@ -268,7 +267,7 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
switch se := t.(type) {
case xml.StartElement:
yqlib.GetLogger().Debug("start element %v", se.Name.Local)
log.Debug("start element %v", se.Name.Local)
elem.state = "started"
// Build new a new current element and link it to its parent
elem = &element{
@@ -297,14 +296,14 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
if len(newBit) > 0 {
elem.n.Data = append(elem.n.Data, newBit)
elem.state = "chardata"
yqlib.GetLogger().Debug("chardata [%v] for %v", elem.n.Data, elem.label)
log.Debug("chardata [%v] for %v", elem.n.Data, elem.label)
}
case xml.EndElement:
if elem == nil {
yqlib.GetLogger().Debug("no element, probably bad xml")
log.Debug("no element, probably bad xml")
continue
}
yqlib.GetLogger().Debug("end element %v", elem.label)
log.Debug("end element %v", elem.label)
elem.state = "finished"
// And add it to its parent list
if elem.parent != nil {
@@ -316,14 +315,15 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
case xml.Comment:
commentStr := string(xml.CharData(se))
if elem.state == "started" {
switch elem.state {
case "started":
applyFootComment(elem, commentStr)
} else if elem.state == "chardata" {
yqlib.GetLogger().Debug("got a line comment for (%v) %v: [%v]", elem.state, elem.label, commentStr)
case "chardata":
log.Debug("got a line comment for (%v) %v: [%v]", elem.state, elem.label, commentStr)
elem.n.LineComment = joinComments([]string{elem.n.LineComment, commentStr}, " ")
} else {
yqlib.GetLogger().Debug("got a head comment for (%v) %v: [%v]", elem.state, elem.label, commentStr)
default:
log.Debug("got a head comment for (%v) %v: [%v]", elem.state, elem.label, commentStr)
elem.n.HeadComment = joinComments([]string{elem.n.HeadComment, commentStr}, " ")
}
@@ -348,7 +348,7 @@ func applyFootComment(elem *element, commentStr string) {
if len(elem.n.Children) > 0 {
lastChildIndex := len(elem.n.Children) - 1
childKv := elem.n.Children[lastChildIndex]
yqlib.GetLogger().Debug("got a foot comment, putting on last child for %v: [%v]", childKv.K, commentStr)
log.Debug("got a foot comment, putting on last child for %v: [%v]", childKv.K, commentStr)
// if it's an array of scalars, put the foot comment on the scalar itself
if len(childKv.V) > 0 && len(childKv.V[0].Children) == 0 {
nodeToUpdate := childKv.V[len(childKv.V)-1]
@@ -357,7 +357,7 @@ func applyFootComment(elem *element, commentStr string) {
childKv.FootComment = joinComments([]string{elem.n.FootComment, commentStr}, " ")
}
} else {
yqlib.GetLogger().Debug("got a foot comment for %v: [%v]", elem.label, commentStr)
log.Debug("got a foot comment for %v: [%v]", elem.label, commentStr)
elem.n.FootComment = joinComments([]string{elem.n.FootComment, commentStr}, " ")
}
}
+1 -1
View File
@@ -151,7 +151,7 @@ func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
}
func (dec *yamlDecoder) blankNodeWithComment() *CandidateNode {
node := CreateScalarNode(nil, "")
node := createScalarNode(nil, "")
node.LeadingContent = dec.leadingContent
return node
}
+24
View File
@@ -2,6 +2,8 @@
Similar to the same named functions in `jq` these functions convert to/from an object and an array of key-value pairs. This is most useful for performing operations on keys of maps.
Use `with_entries(op)` as a syntatic sugar for doing `to_entries | op | from_entries`.
## to_entries Map
Given a sample.yml file of:
```yaml
@@ -101,6 +103,28 @@ KEY_a: 1
KEY_b: 2
```
## Use with_entries to update keys recursively
We use (.. | select(tag="map")) to find all the maps in the doc, then |= to update each one of those maps. In the update, with_entries is used.
Given a sample.yml file of:
```yaml
a: 1
b:
b_a: nested
b_b: thing
```
then
```bash
yq '(.. | select(tag=="!!map")) |= with_entries(.key |= "KEY_" + .)' sample.yml
```
will output
```yaml
KEY_a: 1
KEY_b:
KEY_b_a: nested
KEY_b_b: thing
```
## Custom sort map keys
Use to_entries to convert to an array of key/value pairs, sort the array using sort/sort_by/etc, and convert it back.
@@ -1,3 +1,5 @@
# Entries
Similar to the same named functions in `jq` these functions convert to/from an object and an array of key-value pairs. This is most useful for performing operations on keys of maps.
Use `with_entries(op)` as a syntatic sugar for doing `to_entries | op | from_entries`.
+7
View File
@@ -0,0 +1,7 @@
# Kind
The `kind` operator identifies the type of a node as either `scalar`, `map`, or `seq`.
This can be used for filtering or transforming nodes based on their type.
Note that `null` values are treated as `scalar`.
+3
View File
@@ -0,0 +1,3 @@
# Max
Computes the maximum among an incoming sequence of scalar values.
+3
View File
@@ -0,0 +1,3 @@
# Min
Computes the minimum among an incoming sequence of scalar values.
+3
View File
@@ -0,0 +1,3 @@
# Omit
Works like `pick`, but instead you specify the keys/indices that you _don't_ want included.
+3
View File
@@ -0,0 +1,3 @@
# Pivot
Emulates the `PIVOT` function supported by several popular RDBMS systems.
@@ -2,4 +2,4 @@
The slice array operator takes an array as input and returns a subarray. Like the `jq` equivalent, `.[10:15]` will return an array of length 5, starting from index 10 inclusive, up to index 15 exclusive. Negative numbers count backwards from the end of the array.
You may leave out the first or second number, which will will refer to the start or end of the array respectively.
You may leave out the first or second number, which will refer to the start or end of the array respectively.
+2 -2
View File
@@ -12,5 +12,5 @@ diff file1.yml file2.yml
Note that `yq` does not yet consider anchors when sorting by keys - this may result in invalid yaml documents if you are using merge anchors.
For more advanced sorting, using `to_entries` to convert the map to an array, then sort/process the array as you like (e.g. using `sort_by`) and convert back to a map using `from_entries`.
See [here](https://mikefarah.gitbook.io/yq/operators/entries#custom-sort-map-keys) for an example.
For more advanced sorting, you can use the [sort_by](https://mikefarah.gitbook.io/yq/operators/sort) function on a map, and give it a custom function like `sort_by(key | downcase)`.
@@ -3,7 +3,7 @@
## RegEx
This uses Golang's native regex functions under the hood - See their [docs](https://github.com/google/re2/wiki/Syntax) for the supported syntax.
Case insensitive tip: prefix the regex with `(?i)` - e.g. `test("(?i)cats)"`.
Case insensitive tip: prefix the regex with `(?i)` - e.g. `test("(?i)cats")`.
### match(regEx)
This operator returns the substring match details of the given regEx.
+7
View File
@@ -1,3 +1,10 @@
# Kind
The `kind` operator identifies the type of a node as either `scalar`, `map`, or `seq`.
This can be used for filtering or transforming nodes based on their type.
Note that `null` values are treated as `scalar`.
## Get kind
Given a sample.yml file of:
+51
View File
@@ -0,0 +1,51 @@
# Max
Computes the maximum among an incoming sequence of scalar values.
## Maximum int
Given a sample.yml file of:
```yaml
- 99
- 16
- 12
- 6
- 66
```
then
```bash
yq 'max' sample.yml
```
will output
```yaml
99
```
## Maximum string
Given a sample.yml file of:
```yaml
- foo
- bar
- baz
```
then
```bash
yq 'max' sample.yml
```
will output
```yaml
foo
```
## Maximum of empty
Given a sample.yml file of:
```yaml
[]
```
then
```bash
yq 'max' sample.yml
```
will output
```yaml
```
+51
View File
@@ -0,0 +1,51 @@
# Min
Computes the minimum among an incoming sequence of scalar values.
## Minimum int
Given a sample.yml file of:
```yaml
- 99
- 16
- 12
- 6
- 66
```
then
```bash
yq 'min' sample.yml
```
will output
```yaml
6
```
## Minimum string
Given a sample.yml file of:
```yaml
- foo
- bar
- baz
```
then
```bash
yq 'min' sample.yml
```
will output
```yaml
bar
```
## Minimum of empty
Given a sample.yml file of:
```yaml
[]
```
then
```bash
yq 'min' sample.yml
```
will output
```yaml
```
+56
View File
@@ -55,6 +55,62 @@ a: 12
b: 4
```
## Multiply string node X int
Given a sample.yml file of:
```yaml
b: banana
```
then
```bash
yq '.b * 4' sample.yml
```
will output
```yaml
bananabananabananabanana
```
## Multiply int X string node
Given a sample.yml file of:
```yaml
b: banana
```
then
```bash
yq '4 * .b' sample.yml
```
will output
```yaml
bananabananabananabanana
```
## Multiply string X int node
Given a sample.yml file of:
```yaml
n: 4
```
then
```bash
yq '"banana" * .n' sample.yml
```
will output
```yaml
bananabananabananabanana
```
## Multiply int node X string
Given a sample.yml file of:
```yaml
n: 4
```
then
```bash
yq '.n * "banana"' sample.yml
```
will output
```yaml
bananabananabananabanana
```
## Merge objects together, returning merged result only
Given a sample.yml file of:
```yaml
+44
View File
@@ -0,0 +1,44 @@
# Omit
Works like `pick`, but instead you specify the keys/indices that you _don't_ want included.
## Omit keys from map
Note that non existent keys are skipped.
Given a sample.yml file of:
```yaml
myMap:
cat: meow
dog: bark
thing: hamster
hamster: squeak
```
then
```bash
yq '.myMap |= omit(["hamster", "cat", "goat"])' sample.yml
```
will output
```yaml
myMap:
dog: bark
thing: hamster
```
## Omit indices from array
Note that non existent indices are skipped.
Given a sample.yml file of:
```yaml
- cat
- leopard
- lion
```
then
```bash
yq 'omit([2, 0, 734, -5])' sample.yml
```
will output
```yaml
- leopard
```
+19
View File
@@ -37,6 +37,25 @@ fruit: banana
name: sam
```
## Get parent attribute
Given a sample.yml file of:
```yaml
a:
fruit: apple
name: bob
b:
fruit: banana
name: sam
```
then
```bash
yq '.. | select(. == "banana") | parent.name' sample.yml
```
will output
```yaml
sam
```
## N-th parent
You can optionally supply the number of levels to go up for the parent, the default being 1.
+24
View File
@@ -26,6 +26,30 @@ myMap:
cat: meow
```
## Pick keys from map, included all the keys
We create a map of the picked keys plus all the current keys, and run that through unique
Given a sample.yml file of:
```yaml
myMap:
cat: meow
dog: bark
thing: hamster
hamster: squeak
```
then
```bash
yq '.myMap |= pick( (["thing"] + keys) | unique)' sample.yml
```
will output
```yaml
myMap:
thing: hamster
cat: meow
dog: bark
hamster: squeak
```
## Pick indices from array
Note that the order of the indices matches the pick order and non existent indices are skipped.
+117
View File
@@ -0,0 +1,117 @@
# Pivot
Emulates the `PIVOT` function supported by several popular RDBMS systems.
## Pivot a sequence of sequences
Given a sample.yml file of:
```yaml
- - foo
- bar
- baz
- - sis
- boom
- bah
```
then
```bash
yq 'pivot' sample.yml
```
will output
```yaml
- - foo
- sis
- - bar
- boom
- - baz
- bah
```
## Pivot sequence of heterogeneous sequences
Missing values are "padded" to null.
Given a sample.yml file of:
```yaml
- - foo
- bar
- baz
- - sis
- boom
- bah
- blah
```
then
```bash
yq 'pivot' sample.yml
```
will output
```yaml
- - foo
- sis
- - bar
- boom
- - baz
- bah
- -
- blah
```
## Pivot sequence of maps
Given a sample.yml file of:
```yaml
- foo: a
bar: b
baz: c
- foo: x
bar: y
baz: z
```
then
```bash
yq 'pivot' sample.yml
```
will output
```yaml
foo:
- a
- x
bar:
- b
- y
baz:
- c
- z
```
## Pivot sequence of heterogeneous maps
Missing values are "padded" to null.
Given a sample.yml file of:
```yaml
- foo: a
bar: b
baz: c
- foo: x
bar: y
baz: z
what: ever
```
then
```bash
yq 'pivot' sample.yml
```
will output
```yaml
foo:
- a
- x
bar:
- b
- y
baz:
- c
- z
what:
-
- ever
```
+1 -1
View File
@@ -2,7 +2,7 @@
The slice array operator takes an array as input and returns a subarray. Like the `jq` equivalent, `.[10:15]` will return an array of length 5, starting from index 10 inclusive, up to index 15 exclusive. Negative numbers count backwards from the end of the array.
You may leave out the first or second number, which will will refer to the start or end of the array respectively.
You may leave out the first or second number, which will refer to the start or end of the array respectively.
## Slicing arrays
Given a sample.yml file of:
+2 -2
View File
@@ -12,8 +12,8 @@ diff file1.yml file2.yml
Note that `yq` does not yet consider anchors when sorting by keys - this may result in invalid yaml documents if you are using merge anchors.
For more advanced sorting, using `to_entries` to convert the map to an array, then sort/process the array as you like (e.g. using `sort_by`) and convert back to a map using `from_entries`.
See [here](https://mikefarah.gitbook.io/yq/operators/entries#custom-sort-map-keys) for an example.
For more advanced sorting, you can use the [sort_by](https://mikefarah.gitbook.io/yq/operators/sort) function on a map, and give it a custom function like `sort_by(key | downcase)`.
## Sort keys of map
Given a sample.yml file of:
+40
View File
@@ -109,6 +109,46 @@ cool:
- c: banana
```
## Sort a map
Sorting a map, by default this will sort by the values
Given a sample.yml file of:
```yaml
y: b
z: a
x: c
```
then
```bash
yq 'sort' sample.yml
```
will output
```yaml
z: a
y: b
x: c
```
## Sort a map by keys
Use sort_by to sort a map using a custom function
Given a sample.yml file of:
```yaml
Y: b
z: a
x: c
```
then
```bash
yq 'sort_by(key | downcase)' sample.yml
```
will output
```yaml
x: c
Y: b
z: a
```
## Sort is stable
Note the order of the elements in unchanged when equal in sorting.
+1 -1
View File
@@ -3,7 +3,7 @@
## RegEx
This uses Golang's native regex functions under the hood - See their [docs](https://github.com/google/re2/wiki/Syntax) for the supported syntax.
Case insensitive tip: prefix the regex with `(?i)` - e.g. `test("(?i)cats)"`.
Case insensitive tip: prefix the regex with `(?i)` - e.g. `test("(?i)cats")`.
### match(regEx)
This operator returns the substring match details of the given regEx.
+45 -1
View File
@@ -63,7 +63,29 @@ will output
- ~
```
## Unique array object fields
## Unique array objects
Given a sample.yml file of:
```yaml
- name: harry
pet: cat
- name: billy
pet: dog
- name: harry
pet: cat
```
then
```bash
yq 'unique' sample.yml
```
will output
```yaml
- name: harry
pet: cat
- name: billy
pet: dog
```
## Unique array of objects by a field
Given a sample.yml file of:
```yaml
- name: harry
@@ -85,3 +107,25 @@ will output
pet: dog
```
## Unique array of arrays
Given a sample.yml file of:
```yaml
- - cat
- dog
- - cat
- sheep
- - cat
- dog
```
then
```bash
yq 'unique' sample.yml
```
will output
```yaml
- - cat
- dog
- - cat
- sheep
```
+19 -2
View File
@@ -71,7 +71,7 @@ person.food[0] = pizza
```
## Encode properties - custom separator
Use the --properties-customer-separator flag to specify your own key/value separator.
Use the --properties-separator flag to specify your own key/value separator.
Given a sample.yml file of:
```yaml
@@ -89,7 +89,7 @@ emptyMap: []
```
then
```bash
yq -o=props --properties-customer-separator=" :@ " sample.yml
yq -o=props --properties-separator=" :@ " sample.yml
```
will output
```properties
@@ -230,6 +230,23 @@ person:
- pizza
```
## Decode properties: numbers
All values are assumed to be strings when parsing properties, but you can use the `from_yaml` operator on all the strings values to autoparse into the correct type.
Given a sample.properties file of:
```properties
a.b = 10
```
then
```bash
yq -p=props ' (.. | select(tag == "!!str")) |= from_yaml' sample.properties
```
will output
```yaml
a:
b: 10
```
## Decode properties - array should be a map
If you have a numeric map key in your property files, use array_to_map to convert them to maps.
+15
View File
@@ -10,3 +10,18 @@ type Encoder interface {
PrintLeadingContent(writer io.Writer, content string) error
CanHandleAliases() bool
}
func mapKeysToStrings(node *CandidateNode) {
if node.Kind == MappingNode {
for index, child := range node.Content {
if index%2 == 0 { // its a map key
child.Tag = "!!str"
}
}
}
for _, child := range node.Content {
mapKeysToStrings(child)
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ func (e *base64Encoder) PrintLeadingContent(_ io.Writer, _ string) error {
}
func (e *base64Encoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.GuessTagFromCustomType() != "!!str" {
if node.guessTagFromCustomType() != "!!str" {
return fmt.Errorf("cannot encode %v as base64, can only operate on strings", node.Tag)
}
_, err := writer.Write([]byte(e.encoding.EncodeToString([]byte(node.Value))))
+2 -2
View File
@@ -65,7 +65,7 @@ func (e *csvEncoder) createChildRow(child *CandidateNode, headers []*CandidateNo
childRow := make([]*CandidateNode, 0)
for _, header := range headers {
keyIndex := findKeyInMap(child, header)
value := CreateScalarNode(nil, "")
value := createScalarNode(nil, "")
if keyIndex != -1 {
value = child.Content[keyIndex+1]
}
@@ -102,7 +102,7 @@ func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*CandidateNo
func (e *csvEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.Kind == ScalarNode {
return WriteString(writer, node.Value+"\n")
return writeString(writer, node.Value+"\n")
}
csvWriter := csv.NewWriter(writer)
+1 -1
View File
@@ -41,7 +41,7 @@ func (je *jsonEncoder) Encode(writer io.Writer, node *CandidateNode) error {
log.Debugf("kids %v", len(node.Content))
if node.Kind == ScalarNode && je.prefs.UnwrapScalar {
return WriteString(writer, node.Value+"\n")
return writeString(writer, node.Value+"\n")
}
destination := writer
+35 -31
View File
@@ -86,15 +86,15 @@ func (le *luaEncoder) encodeString(writer io.Writer, node *CandidateNode) error
case LiteralStyle, FoldedStyle, FlowStyle:
for i := 0; i < 10; i++ {
if !strings.Contains(node.Value, "]"+strings.Repeat("=", i)+"]") {
err := WriteString(writer, "["+strings.Repeat("=", i)+"[\n")
err := writeString(writer, "["+strings.Repeat("=", i)+"[\n")
if err != nil {
return err
}
err = WriteString(writer, node.Value)
err = writeString(writer, node.Value)
if err != nil {
return err
}
return WriteString(writer, "]"+strings.Repeat("=", i)+"]")
return writeString(writer, "]"+strings.Repeat("=", i)+"]")
}
}
case SingleQuotedStyle:
@@ -102,22 +102,22 @@ func (le *luaEncoder) encodeString(writer io.Writer, node *CandidateNode) error
// fallthrough to regular ol' string
}
return WriteString(writer, quote+le.escape.Replace(node.Value)+quote)
return writeString(writer, quote+le.escape.Replace(node.Value)+quote)
}
func (le *luaEncoder) writeIndent(writer io.Writer) error {
if le.indentStr == "" {
return nil
}
err := WriteString(writer, "\n")
err := writeString(writer, "\n")
if err != nil {
return err
}
return WriteString(writer, strings.Repeat(le.indentStr, le.indent))
return writeString(writer, strings.Repeat(le.indentStr, le.indent))
}
func (le *luaEncoder) encodeArray(writer io.Writer, node *CandidateNode) error {
err := WriteString(writer, "{")
err := writeString(writer, "{")
if err != nil {
return err
}
@@ -131,13 +131,13 @@ func (le *luaEncoder) encodeArray(writer io.Writer, node *CandidateNode) error {
if err != nil {
return err
}
err = WriteString(writer, ",")
err = writeString(writer, ",")
if err != nil {
return err
}
if child.LineComment != "" {
sansPrefix, _ := strings.CutPrefix(child.LineComment, "#")
err = WriteString(writer, " --"+sansPrefix)
err = writeString(writer, " --"+sansPrefix)
if err != nil {
return err
}
@@ -150,7 +150,7 @@ func (le *luaEncoder) encodeArray(writer io.Writer, node *CandidateNode) error {
return err
}
}
return WriteString(writer, "}")
return writeString(writer, "}")
}
func needsQuoting(s string) bool {
@@ -167,10 +167,14 @@ func needsQuoting(s string) bool {
// [%a_][%w_]*
for i, c := range s {
if i == 0 {
// keeping for legacy reasons, upgraded linter
//nolint:staticcheck
if !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') {
return true
}
} else {
// keeping for legacy reasons, upgraded linter
//nolint:staticcheck
if !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') {
return true
}
@@ -181,7 +185,7 @@ func needsQuoting(s string) bool {
func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bool) error {
if !global {
err := WriteString(writer, "{")
err := writeString(writer, "{")
if err != nil {
return err
}
@@ -194,7 +198,7 @@ func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bo
if err != nil {
return err
}
err = WriteString(writer, ";")
err = writeString(writer, ";")
if err != nil {
return err
}
@@ -207,19 +211,19 @@ func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bo
}
}
if (le.unquoted || global) && child.Tag == "!!str" && !needsQuoting(child.Value) {
err := WriteString(writer, child.Value+" = ")
err := writeString(writer, child.Value+" = ")
if err != nil {
return err
}
} else {
if global {
// This only works in Lua 5.2+
err := WriteString(writer, "_ENV")
err := writeString(writer, "_ENV")
if err != nil {
return err
}
}
err := WriteString(writer, "[")
err := writeString(writer, "[")
if err != nil {
return err
}
@@ -227,7 +231,7 @@ func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bo
if err != nil {
return err
}
err = WriteString(writer, "] = ")
err = writeString(writer, "] = ")
if err != nil {
return err
}
@@ -235,7 +239,7 @@ func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bo
}
if child.LineComment != "" {
sansPrefix, _ := strings.CutPrefix(child.LineComment, "#")
err := WriteString(writer, strings.Repeat(" ", i%2)+"--"+sansPrefix)
err := writeString(writer, strings.Repeat(" ", i%2)+"--"+sansPrefix)
if err != nil {
return err
}
@@ -249,7 +253,7 @@ func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bo
}
}
if global {
return WriteString(writer, "\n")
return writeString(writer, "\n")
}
le.indent--
if len(node.Content) != 0 {
@@ -258,7 +262,7 @@ func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode, global bo
return err
}
}
return WriteString(writer, "}")
return writeString(writer, "}")
}
func (le *luaEncoder) encodeAny(writer io.Writer, node *CandidateNode) error {
@@ -273,41 +277,41 @@ func (le *luaEncoder) encodeAny(writer io.Writer, node *CandidateNode) error {
return le.encodeString(writer, node)
case "!!null":
// TODO reject invalid use as a table key
return WriteString(writer, "nil")
return writeString(writer, "nil")
case "!!bool":
// Yaml 1.2 has case variation e.g. True, FALSE etc but Lua only has
// lower case
return WriteString(writer, strings.ToLower(node.Value))
return writeString(writer, strings.ToLower(node.Value))
case "!!int":
if strings.HasPrefix(node.Value, "0o") {
_, octalValue, err := parseInt64(node.Value)
if err != nil {
return err
}
return WriteString(writer, fmt.Sprintf("%d", octalValue))
return writeString(writer, fmt.Sprintf("%d", octalValue))
}
return WriteString(writer, strings.ToLower(node.Value))
return writeString(writer, strings.ToLower(node.Value))
case "!!float":
switch strings.ToLower(node.Value) {
case ".inf", "+.inf":
return WriteString(writer, "(1/0)")
return writeString(writer, "(1/0)")
case "-.inf":
return WriteString(writer, "(-1/0)")
return writeString(writer, "(-1/0)")
case ".nan":
return WriteString(writer, "(0/0)")
return writeString(writer, "(0/0)")
default:
return WriteString(writer, node.Value)
return writeString(writer, node.Value)
}
default:
return fmt.Errorf("Lua encoder NYI -- %s", node.Tag)
return fmt.Errorf("lua encoder NYI -- %s", node.Tag)
}
default:
return fmt.Errorf("Lua encoder NYI -- %s", node.Tag)
return fmt.Errorf("lua encoder NYI -- %s", node.Tag)
}
}
func (le *luaEncoder) encodeTopLevel(writer io.Writer, node *CandidateNode) error {
err := WriteString(writer, le.docPrefix)
err := writeString(writer, le.docPrefix)
if err != nil {
return err
}
@@ -315,7 +319,7 @@ func (le *luaEncoder) encodeTopLevel(writer io.Writer, node *CandidateNode) erro
if err != nil {
return err
}
return WriteString(writer, le.docSuffix)
return writeString(writer, le.docSuffix)
}
func (le *luaEncoder) Encode(writer io.Writer, node *CandidateNode) error {
@@ -1,4 +1,4 @@
package properties
package yqlib
import (
"bufio"
@@ -8,14 +8,13 @@ import (
"strings"
"github.com/magiconair/properties"
"github.com/mikefarah/yq/v4/pkg/yqlib"
)
type propertiesEncoder struct {
prefs PropertiesPreferences
}
func NewPropertiesEncoder(prefs PropertiesPreferences) yqlib.Encoder {
func NewPropertiesEncoder(prefs PropertiesPreferences) Encoder {
return &propertiesEncoder{
prefs: prefs,
}
@@ -44,7 +43,7 @@ func (pe *propertiesEncoder) PrintLeadingContent(writer io.Writer, content strin
}
} else {
if err := yqlib.WriteString(writer, readline); err != nil {
if err := writeString(writer, readline); err != nil {
return err
}
}
@@ -52,7 +51,7 @@ func (pe *propertiesEncoder) PrintLeadingContent(writer io.Writer, content strin
if errors.Is(errReading, io.EOF) {
if readline != "" {
// the last comment we read didn't have a newline, put one in
if err := yqlib.WriteString(writer, "\n"); err != nil {
if err := writeString(writer, "\n"); err != nil {
return err
}
}
@@ -62,13 +61,13 @@ func (pe *propertiesEncoder) PrintLeadingContent(writer io.Writer, content strin
return nil
}
func (pe *propertiesEncoder) Encode(writer io.Writer, node *yqlib.CandidateNode) error {
func (pe *propertiesEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.Kind == yqlib.ScalarNode {
return yqlib.WriteString(writer, node.Value+"\n")
if node.Kind == ScalarNode {
return writeString(writer, node.Value+"\n")
}
node.ConvertKeysToStrings()
mapKeysToStrings(node)
p := properties.NewProperties()
p.WriteSeparator = pe.prefs.KeyValueSeparator
err := pe.doEncode(p, node, "", nil)
@@ -80,19 +79,19 @@ func (pe *propertiesEncoder) Encode(writer io.Writer, node *yqlib.CandidateNode)
return err
}
func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yqlib.CandidateNode, path string, keyNode *yqlib.CandidateNode) error {
func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *CandidateNode, path string, keyNode *CandidateNode) error {
comments := ""
if keyNode != nil {
// include the key node comments if present
comments = keyNode.CleanHeadAndLineComment()
comments = headAndLineComment(keyNode)
}
comments = comments + node.CleanHeadAndLineComment()
comments = comments + headAndLineComment(node)
commentsWithSpaces := strings.ReplaceAll(comments, "\n", "\n ")
p.SetComments(path, strings.Split(commentsWithSpaces, "\n"))
switch node.Kind {
case yqlib.ScalarNode:
case ScalarNode:
var nodeValue string
if pe.prefs.UnwrapScalar || !strings.Contains(node.Value, " ") {
nodeValue = node.Value
@@ -101,14 +100,14 @@ func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yqlib.Cand
}
_, _, err := p.Set(path, nodeValue)
return err
case yqlib.SequenceNode:
case SequenceNode:
return pe.encodeArray(p, node.Content, path)
case yqlib.MappingNode:
case MappingNode:
return pe.encodeMap(p, node.Content, path)
case yqlib.AliasNode:
case AliasNode:
return pe.doEncode(p, node.Alias, path, nil)
default:
return fmt.Errorf("Unsupported node %v", node.Tag)
return fmt.Errorf("unsupported node %v", node.Tag)
}
}
@@ -126,7 +125,7 @@ func (pe *propertiesEncoder) appendPath(path string, key interface{}) string {
return fmt.Sprintf("%v.%v", path, key)
}
func (pe *propertiesEncoder) encodeArray(p *properties.Properties, kids []*yqlib.CandidateNode, path string) error {
func (pe *propertiesEncoder) encodeArray(p *properties.Properties, kids []*CandidateNode, path string) error {
for index, child := range kids {
err := pe.doEncode(p, child, pe.appendPath(path, index), nil)
if err != nil {
@@ -136,7 +135,7 @@ func (pe *propertiesEncoder) encodeArray(p *properties.Properties, kids []*yqlib
return nil
}
func (pe *propertiesEncoder) encodeMap(p *properties.Properties, kids []*yqlib.CandidateNode, path string) error {
func (pe *propertiesEncoder) encodeMap(p *properties.Properties, kids []*CandidateNode, path string) error {
for index := 0; index < len(kids); index = index + 2 {
key := kids[index]
value := kids[index+1]
@@ -1,4 +1,4 @@
package properties
package yqlib
import (
"bufio"
+2 -2
View File
@@ -30,11 +30,11 @@ func (e *shEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
}
func (e *shEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.GuessTagFromCustomType() != "!!str" {
if node.guessTagFromCustomType() != "!!str" {
return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
}
return WriteString(writer, e.encode(node.Value))
return writeString(writer, e.encode(node.Value))
}
// put any (shell-unsafe) characters into a single-quoted block, close the block lazily
+2 -2
View File
@@ -30,7 +30,7 @@ func (pe *shellVariablesEncoder) PrintLeadingContent(_ io.Writer, _ string) erro
func (pe *shellVariablesEncoder) Encode(writer io.Writer, node *CandidateNode) error {
node.ConvertKeysToStrings()
mapKeysToStrings(node)
err := pe.doEncode(&writer, node, "")
if err != nil {
return err
@@ -75,7 +75,7 @@ func (pe *shellVariablesEncoder) doEncode(w *io.Writer, node *CandidateNode, pat
case AliasNode:
return pe.doEncode(w, node.Alias, path)
default:
return fmt.Errorf("Unsupported node %v", node.Tag)
return fmt.Errorf("unsupported node %v", node.Tag)
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ func NewTomlEncoder() Encoder {
func (te *tomlEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.Kind == ScalarNode {
return WriteString(writer, node.Value+"\n")
return writeString(writer, node.Value+"\n")
}
return fmt.Errorf("only scalars (e.g. strings, numbers, booleans) are supported for TOML output at the moment. Please use yaml output format (-oy) until the encoder has been fully implemented")
}
+1 -1
View File
@@ -26,7 +26,7 @@ func (e *uriEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
}
func (e *uriEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.GuessTagFromCustomType() != "!!str" {
if node.guessTagFromCustomType() != "!!str" {
return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
}
_, err := writer.Write([]byte(url.QueryEscape(node.Value)))
@@ -1,6 +1,6 @@
//go:build !yq_noxml
package xml
package yqlib
import (
"encoding/xml"
@@ -8,8 +8,6 @@ import (
"io"
"regexp"
"strings"
"github.com/mikefarah/yq/v4/pkg/yqlib"
)
type xmlEncoder struct {
@@ -19,7 +17,7 @@ type xmlEncoder struct {
leadingContent string
}
func NewXMLEncoder(prefs XmlPreferences) yqlib.Encoder {
func NewXMLEncoder(prefs XmlPreferences) Encoder {
var indentString = ""
for index := 0; index < prefs.Indent; index++ {
@@ -41,7 +39,7 @@ func (e *xmlEncoder) PrintLeadingContent(_ io.Writer, content string) error {
return nil
}
func (e *xmlEncoder) Encode(writer io.Writer, node *yqlib.CandidateNode) error {
func (e *xmlEncoder) Encode(writer io.Writer, node *CandidateNode) error {
encoder := xml.NewEncoder(writer)
// hack so we can manually add newlines to procInst and directives
e.writer = writer
@@ -61,7 +59,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yqlib.CandidateNode) error {
return err
}
if _, err := e.writer.Write([]byte("\n")); err != nil {
yqlib.GetLogger().Warning("Unable to write newline, skipping: %w", err)
log.Warning("Unable to write newline, skipping: %w", err)
}
}
}
@@ -81,12 +79,12 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yqlib.CandidateNode) error {
}
switch node.Kind {
case yqlib.MappingNode:
case MappingNode:
err := e.encodeTopLevelMap(encoder, node)
if err != nil {
return err
}
case yqlib.ScalarNode:
case ScalarNode:
var charData xml.CharData = []byte(node.Value)
err := encoder.EncodeToken(charData)
if err != nil {
@@ -101,8 +99,8 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yqlib.CandidateNode) error {
}
func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yqlib.CandidateNode) error {
err := e.encodeComment(encoder, node.CleanHeadAndLineComment())
func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *CandidateNode) error {
err := e.encodeComment(encoder, headAndLineComment(node))
if err != nil {
return err
}
@@ -111,12 +109,12 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yqlib.Candida
value := node.Content[i+1]
start := xml.StartElement{Name: xml.Name{Local: key.Value}}
yqlib.GetLogger().Debugf("comments of key %v", key.Value)
err := e.encodeComment(encoder, key.CleanHeadAndLineComment())
log.Debugf("comments of key %v", key.Value)
err := e.encodeComment(encoder, headAndLineComment(key))
if err != nil {
return err
}
if key.CleanHeadAndLineComment() != "" {
if headAndLineComment(key) != "" {
var newLine xml.CharData = []byte("\n")
err = encoder.EncodeToken(newLine)
if err != nil {
@@ -133,7 +131,7 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yqlib.Candida
return err
}
if _, err := e.writer.Write([]byte("\n")); err != nil {
yqlib.GetLogger().Warning("Unable to write newline, skipping: %w", err)
log.Warning("Unable to write newline, skipping: %w", err)
}
} else if key.Value == e.prefs.DirectiveName {
var directive xml.Directive = []byte(value.Value)
@@ -141,48 +139,48 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yqlib.Candida
return err
}
if _, err := e.writer.Write([]byte("\n")); err != nil {
yqlib.GetLogger().Warning("Unable to write newline, skipping: %w", err)
log.Warning("Unable to write newline, skipping: %w", err)
}
} else {
yqlib.GetLogger().Debugf("recursing")
log.Debugf("recursing")
err = e.doEncode(encoder, value, start)
if err != nil {
return err
}
}
err = e.encodeComment(encoder, key.CleanFootComment())
err = e.encodeComment(encoder, footComment(key))
if err != nil {
return err
}
}
return e.encodeComment(encoder, node.CleanFootComment())
return e.encodeComment(encoder, footComment(node))
}
func (e *xmlEncoder) encodeStart(encoder *xml.Encoder, node *yqlib.CandidateNode, start xml.StartElement) error {
func (e *xmlEncoder) encodeStart(encoder *xml.Encoder, node *CandidateNode, start xml.StartElement) error {
err := encoder.EncodeToken(start)
if err != nil {
return err
}
return e.encodeComment(encoder, node.CleanHeadComment())
return e.encodeComment(encoder, headComment(node))
}
func (e *xmlEncoder) encodeEnd(encoder *xml.Encoder, node *yqlib.CandidateNode, start xml.StartElement) error {
func (e *xmlEncoder) encodeEnd(encoder *xml.Encoder, node *CandidateNode, start xml.StartElement) error {
err := encoder.EncodeToken(start.End())
if err != nil {
return err
}
return e.encodeComment(encoder, node.CleanFootComment())
return e.encodeComment(encoder, footComment(node))
}
func (e *xmlEncoder) doEncode(encoder *xml.Encoder, node *yqlib.CandidateNode, start xml.StartElement) error {
func (e *xmlEncoder) doEncode(encoder *xml.Encoder, node *CandidateNode, start xml.StartElement) error {
switch node.Kind {
case yqlib.MappingNode:
case MappingNode:
return e.encodeMap(encoder, node, start)
case yqlib.SequenceNode:
case SequenceNode:
return e.encodeArray(encoder, node, start)
case yqlib.ScalarNode:
case ScalarNode:
err := e.encodeStart(encoder, node, start)
if err != nil {
return err
@@ -194,7 +192,7 @@ func (e *xmlEncoder) doEncode(encoder *xml.Encoder, node *yqlib.CandidateNode, s
return err
}
if err = e.encodeComment(encoder, node.CleanLineComment()); err != nil {
if err = e.encodeComment(encoder, lineComment(node)); err != nil {
return err
}
@@ -209,13 +207,13 @@ var chompRegexp = regexp.MustCompile(`\n$`)
func (e *xmlEncoder) encodeComment(encoder *xml.Encoder, commentStr string) error {
if commentStr != "" {
yqlib.GetLogger().Debugf("got comment [%v]", commentStr)
log.Debugf("got comment [%v]", commentStr)
// multi line string
if len(commentStr) > 2 && strings.Contains(commentStr[1:len(commentStr)-1], "\n") {
commentStr = chompRegexp.ReplaceAllString(commentStr, "")
yqlib.GetLogger().Debugf("chompRegexp [%v]", commentStr)
log.Debugf("chompRegexp [%v]", commentStr)
commentStr = xmlEncodeMultilineCommentRegex.ReplaceAllString(commentStr, "$1$2")
yqlib.GetLogger().Debugf("processed multiline [%v]", commentStr)
log.Debugf("processed multiline [%v]", commentStr)
// if the first line is non blank, add a space
if commentStr[0] != '\n' && commentStr[0] != ' ' {
commentStr = " " + commentStr
@@ -227,9 +225,9 @@ func (e *xmlEncoder) encodeComment(encoder *xml.Encoder, commentStr string) erro
if !strings.HasSuffix(commentStr, " ") && !strings.HasSuffix(commentStr, "\n") {
commentStr = commentStr + " "
yqlib.GetLogger().Debugf("added suffix [%v]", commentStr)
log.Debugf("added suffix [%v]", commentStr)
}
yqlib.GetLogger().Debugf("encoding comment [%v]", commentStr)
log.Debugf("encoding comment [%v]", commentStr)
var comment xml.Comment = []byte(commentStr)
err := encoder.EncodeToken(comment)
@@ -240,9 +238,9 @@ func (e *xmlEncoder) encodeComment(encoder *xml.Encoder, commentStr string) erro
return nil
}
func (e *xmlEncoder) encodeArray(encoder *xml.Encoder, node *yqlib.CandidateNode, start xml.StartElement) error {
func (e *xmlEncoder) encodeArray(encoder *xml.Encoder, node *CandidateNode, start xml.StartElement) error {
if err := e.encodeComment(encoder, node.CleanHeadAndLineComment()); err != nil {
if err := e.encodeComment(encoder, headAndLineComment(node)); err != nil {
return err
}
@@ -252,7 +250,7 @@ func (e *xmlEncoder) encodeArray(encoder *xml.Encoder, node *yqlib.CandidateNode
return err
}
}
return e.encodeComment(encoder, node.CleanFootComment())
return e.encodeComment(encoder, footComment(node))
}
func (e *xmlEncoder) isAttribute(name string) bool {
@@ -262,8 +260,8 @@ func (e *xmlEncoder) isAttribute(name string) bool {
!strings.HasPrefix(name, e.prefs.ProcInstPrefix)
}
func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yqlib.CandidateNode, start xml.StartElement) error {
yqlib.GetLogger().Debug("its a map")
func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *CandidateNode, start xml.StartElement) error {
log.Debug("its a map")
//first find all the attributes and put them on the start token
for i := 0; i < len(node.Content); i += 2 {
@@ -271,7 +269,7 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yqlib.CandidateNode,
value := node.Content[i+1]
if e.isAttribute(key.Value) {
if value.Kind == yqlib.ScalarNode {
if value.Kind == ScalarNode {
attributeName := strings.Replace(key.Value, e.prefs.AttributePrefix, "", 1)
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: attributeName}, Value: value.Value})
} else {
@@ -290,7 +288,7 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yqlib.CandidateNode,
key := node.Content[i]
value := node.Content[i+1]
err := e.encodeComment(encoder, key.CleanHeadAndLineComment())
err := e.encodeComment(encoder, headAndLineComment(key))
if err != nil {
return err
}
@@ -307,7 +305,7 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yqlib.CandidateNode,
}
} else if key.Value == e.prefs.ContentName {
// directly encode the contents
err = e.encodeComment(encoder, value.CleanHeadAndLineComment())
err = e.encodeComment(encoder, headAndLineComment(value))
if err != nil {
return err
}
@@ -316,7 +314,7 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yqlib.CandidateNode,
if err != nil {
return err
}
err = e.encodeComment(encoder, value.CleanFootComment())
err = e.encodeComment(encoder, footComment(value))
if err != nil {
return err
}
@@ -327,7 +325,7 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yqlib.CandidateNode,
return err
}
}
err = e.encodeComment(encoder, key.CleanFootComment())
err = e.encodeComment(encoder, footComment(key))
if err != nil {
return err
}
+9 -5
View File
@@ -8,7 +8,8 @@ import (
"regexp"
"strings"
yaml "gopkg.in/yaml.v3"
"github.com/fatih/color"
"gopkg.in/yaml.v3"
)
type yamlEncoder struct {
@@ -26,7 +27,7 @@ func (ye *yamlEncoder) CanHandleAliases() bool {
func (ye *yamlEncoder) PrintDocumentSeparator(writer io.Writer) error {
if ye.prefs.PrintDocSeparators {
log.Debug("writing doc sep")
if err := WriteString(writer, "---\n"); err != nil {
if err := writeString(writer, "---\n"); err != nil {
return err
}
}
@@ -54,7 +55,10 @@ func (ye *yamlEncoder) PrintLeadingContent(writer io.Writer, content string) err
if len(readline) > 0 && readline != "\n" && readline[0] != '%' && !commentLineRegEx.MatchString(readline) {
readline = "# " + readline
}
if err := WriteString(writer, readline); err != nil {
if ye.prefs.ColorsEnabled && strings.TrimSpace(readline) != "" {
readline = format(color.FgHiBlack) + readline + format(color.Reset)
}
if err := writeString(writer, readline); err != nil {
return err
}
}
@@ -62,7 +66,7 @@ func (ye *yamlEncoder) PrintLeadingContent(writer io.Writer, content string) err
if errors.Is(errReading, io.EOF) {
if readline != "" {
// the last comment we read didn't have a newline, put one in
if err := WriteString(writer, "\n"); err != nil {
if err := writeString(writer, "\n"); err != nil {
return err
}
}
@@ -80,7 +84,7 @@ func (ye *yamlEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if node.LeadingContent == "" || valueToPrint != "" {
valueToPrint = valueToPrint + "\n"
}
return WriteString(writer, valueToPrint)
return writeString(writer, valueToPrint)
}
destination := writer
+3 -2
View File
@@ -50,14 +50,15 @@ func (p *expressionParserImpl) createExpressionTree(postFixPath []*Operation) (*
log.Debugf("pathTree %v ", Operation.toString())
if Operation.OperationType.NumArgs > 0 {
numArgs := Operation.OperationType.NumArgs
if numArgs == 1 {
switch numArgs {
case 1:
if len(stack) < 1 {
return nil, fmt.Errorf("'%v' expects 1 arg but received none", strings.TrimSpace(Operation.StringValue))
}
remaining, rhs := stack[:len(stack)-1], stack[len(stack)-1]
newNode.RHS = rhs
stack = remaining
} else if numArgs == 2 {
case 2:
if len(stack) < 2 {
return nil, fmt.Errorf("'%v' expects 2 args but there is %v", strings.TrimSpace(Operation.StringValue), len(stack))
}
+5
View File
@@ -11,6 +11,11 @@ func getExpressionParser() ExpressionParserInterface {
return ExpressionParser
}
func TestParserCreateMapColonOnItsOwn(t *testing.T) {
_, err := getExpressionParser().ParseExpression(":")
test.AssertResultComplex(t, "':' expects 2 args but there is 0", err.Error())
}
func TestParserNoMatchingCloseBracket(t *testing.T) {
_, err := getExpressionParser().ParseExpression(".cat | with(.;.bob")
test.AssertResultComplex(t, "bad expression - probably missing close bracket on WITH", err.Error())
+5 -4
View File
@@ -26,11 +26,12 @@ func popOpToResult(opStack []*token, result []*Operation) ([]*token, []*Operatio
}
func validateNoOpenTokens(token *token) error {
if token.TokenType == openCollect {
switch token.TokenType {
case openCollect:
return fmt.Errorf(("bad expression, could not find matching `]`"))
} else if token.TokenType == openCollectObject {
case openCollectObject:
return fmt.Errorf(("bad expression, could not find matching `}`"))
} else if token.TokenType == openBracket {
case openBracket:
return fmt.Errorf(("bad expression, could not find matching `)`"))
}
return nil
@@ -64,7 +65,7 @@ func (p *expressionPostFixerImpl) ConvertToPostfix(infixTokens []*token) ([]*Ope
opStack, result = popOpToResult(opStack, result)
}
if len(opStack) == 0 {
return nil, errors.New("Bad path expression, got close collect brackets without matching opening bracket")
return nil, errors.New("bad path expression, got close collect brackets without matching opening bracket")
}
// now we should have [ as the last element on the opStack, get rid of it
opStack = opStack[0 : len(opStack)-1]
+39 -66
View File
@@ -2,104 +2,88 @@ package yqlib
import (
"fmt"
"path/filepath"
"slices"
"strings"
)
type EncoderFactoryFunction func() Encoder
type InDocumentEncoderFactoryFunction func(indent int) Encoder
type DecoderFactoryFunction func() Decoder
type Format struct {
FormalName string
Names []string
DefaultExtension string
EncoderFactory EncoderFactoryFunction
DecoderFactory DecoderFactoryFunction
/**
* Like the Encoder Factory, but for encoding content within the document itself.
* Should turn off colors and other settings to ensure the content comes out right.
* If this function is not configured, it will default to the EncoderFactory.
**/
InDocumentEncoderFactory InDocumentEncoderFactoryFunction
FormalName string
Names []string
EncoderFactory EncoderFactoryFunction
DecoderFactory DecoderFactoryFunction
}
var YamlFormat = &Format{"yaml", []string{"y", "yml"}, "yml",
var YamlFormat = &Format{"yaml", []string{"y", "yml"},
func() Encoder { return NewYamlEncoder(ConfiguredYamlPreferences) },
func() Decoder { return NewYamlDecoder(ConfiguredYamlPreferences) },
func(indent int) Encoder {
prefs := ConfiguredYamlPreferences.Copy()
prefs.Indent = indent
prefs.ColorsEnabled = false
return NewYamlEncoder(prefs)
},
}
var JSONFormat = &Format{"json", []string{"j"}, "json",
var JSONFormat = &Format{"json", []string{"j"},
func() Encoder { return NewJSONEncoder(ConfiguredJSONPreferences) },
func() Decoder { return NewJSONDecoder() },
func(indent int) Encoder {
prefs := ConfiguredJSONPreferences.Copy()
prefs.Indent = indent
prefs.ColorsEnabled = false
prefs.UnwrapScalar = false
return NewJSONEncoder(prefs)
},
}
var CSVFormat = &Format{"csv", []string{"c"}, "csv",
var PropertiesFormat = &Format{"props", []string{"p", "properties"},
func() Encoder { return NewPropertiesEncoder(ConfiguredPropertiesPreferences) },
func() Decoder { return NewPropertiesDecoder() },
}
var CSVFormat = &Format{"csv", []string{"c"},
func() Encoder { return NewCsvEncoder(ConfiguredCsvPreferences) },
func() Decoder { return NewCSVObjectDecoder(ConfiguredCsvPreferences) },
nil,
}
var TSVFormat = &Format{"tsv", []string{"t"}, "tsv",
var TSVFormat = &Format{"tsv", []string{"t"},
func() Encoder { return NewCsvEncoder(ConfiguredTsvPreferences) },
func() Decoder { return NewCSVObjectDecoder(ConfiguredTsvPreferences) },
nil,
}
var Base64Format = &Format{"base64", []string{}, "txt",
var XMLFormat = &Format{"xml", []string{"x"},
func() Encoder { return NewXMLEncoder(ConfiguredXMLPreferences) },
func() Decoder { return NewXMLDecoder(ConfiguredXMLPreferences) },
}
var Base64Format = &Format{"base64", []string{},
func() Encoder { return NewBase64Encoder() },
func() Decoder { return NewBase64Decoder() },
nil,
}
var UriFormat = &Format{"uri", []string{}, "txt",
var UriFormat = &Format{"uri", []string{},
func() Encoder { return NewUriEncoder() },
func() Decoder { return NewUriDecoder() },
nil,
}
var ShFormat = &Format{"", nil, "sh",
var ShFormat = &Format{"", nil,
func() Encoder { return NewShEncoder() },
nil,
nil,
}
var TomlFormat = &Format{"toml", []string{}, "toml",
var TomlFormat = &Format{"toml", []string{},
func() Encoder { return NewTomlEncoder() },
func() Decoder { return NewTomlDecoder() },
nil,
}
var ShellVariablesFormat = &Format{"shell", []string{"s", "sh"}, "sh",
var ShellVariablesFormat = &Format{"shell", []string{"s", "sh"},
func() Encoder { return NewShellVariablesEncoder() },
nil,
nil,
}
var LuaFormat = &Format{"lua", []string{"l"}, "lua",
var LuaFormat = &Format{"lua", []string{"l"},
func() Encoder { return NewLuaEncoder(ConfiguredLuaPreferences) },
func() Decoder { return NewLuaDecoder(ConfiguredLuaPreferences) },
nil,
}
var Formats = []*Format{
YamlFormat,
JSONFormat,
PropertiesFormat,
CSVFormat,
TSVFormat,
XMLFormat,
Base64Format,
UriFormat,
ShFormat,
@@ -108,36 +92,23 @@ var Formats = []*Format{
LuaFormat,
}
func RegisterFormat(f *Format) {
Formats = append(Formats, f)
}
func (f *Format) MatchesName(name string) bool {
if f.FormalName == name {
return true
}
for _, n := range f.Names {
if n == name {
return true
}
}
return false
return slices.Contains(f.Names, name)
}
func (f *Format) GetInDocumentEncoder(indent int) Encoder {
if f.InDocumentEncoderFactory != nil {
return f.InDocumentEncoderFactory(indent)
}
func (f *Format) GetConfiguredEncoder() Encoder {
return f.EncoderFactory()
}
func FormatStringFromFilename(filename string) string {
if filename != "" {
GetLogger().Debugf("checking file extension '%s' for auto format detection", filename)
nPos := strings.LastIndex(filename, ".")
if nPos > -1 {
format := filename[nPos+1:]
GetLogger().Debugf("checking filename '%s' for auto format detection", filename)
ext := filepath.Ext(filename)
if ext != "" && ext[0] == '.' {
format := strings.ToLower(ext[1:])
GetLogger().Debugf("detected format '%s'", format)
return format
}
@@ -148,9 +119,11 @@ func FormatStringFromFilename(filename string) string {
}
func FormatFromString(format string) (*Format, error) {
for _, printerFormat := range Formats {
if printerFormat.MatchesName(format) {
return printerFormat, nil
if format != "" {
for _, printerFormat := range Formats {
if printerFormat.MatchesName(format) {
return printerFormat, nil
}
}
}
return nil, fmt.Errorf("unknown format '%v' please use [%v]", format, GetAvailableOutputFormatString())
+62
View File
@@ -0,0 +1,62 @@
package yqlib
import (
"fmt"
"strings"
"testing"
"github.com/mikefarah/yq/v4/test"
)
type formatStringScenario struct {
description string
input string
expectedFormat *Format
expectedError string
}
var formatStringScenarios = []formatStringScenario{
{
description: "yaml",
input: "yaml",
expectedFormat: YamlFormat,
},
{
description: "Unknown format type",
input: "doc",
expectedError: "unknown format 'doc' please use",
},
{
description: "blank should error",
input: "",
expectedError: "unknown format '' please use",
},
}
func TestFormatFromString(t *testing.T) {
for _, tt := range formatStringScenarios {
actualFormat, actualError := FormatFromString(tt.input)
if tt.expectedError != "" {
if actualError == nil {
t.Errorf("Expected [%v] error but found none", tt.expectedError)
} else {
test.AssertResultWithContext(t, true, strings.Contains(actualError.Error(), tt.expectedError),
fmt.Sprintf("Expected [%v] to contain [%v]", actualError.Error(), tt.expectedError),
)
}
} else {
test.AssertResult(t, tt.expectedFormat, actualFormat)
}
}
}
func TestFormatStringFromFilename(t *testing.T) {
test.AssertResult(t, "yaml", FormatStringFromFilename("test.Yaml"))
test.AssertResult(t, "yaml", FormatStringFromFilename("test.index.Yaml"))
test.AssertResult(t, "yaml", FormatStringFromFilename("test"))
test.AssertResult(t, "json", FormatStringFromFilename("test.json"))
test.AssertResult(t, "json", FormatStringFromFilename("TEST.JSON"))
test.AssertResult(t, "yaml", FormatStringFromFilename("test.json/foo"))
test.AssertResult(t, "yaml", FormatStringFromFilename(""))
}
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"github.com/mikefarah/yq/v4/test"
)
var formattingExpressionScenarios = []FormatScenario{
var formattingExpressionScenarios = []formatScenario{
{
description: "Using expression files and comments",
skipDoc: true,
@@ -43,7 +43,7 @@ var formattingExpressionScenarios = []FormatScenario{
}
func documentExpressionScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
s := i.(FormatScenario)
s := i.(formatScenario)
if s.skipDoc {
return
+7 -13
View File
@@ -6,7 +6,7 @@ import (
"github.com/mikefarah/yq/v4/test"
)
var goccyYamlFormatScenarios = []FormatScenario{
var goccyYamlFormatScenarios = []formatScenario{
{
description: "basic - 3",
skipDoc: true,
@@ -20,17 +20,11 @@ var goccyYamlFormatScenarios = []FormatScenario{
expected: "3.1\n",
},
{
description: "basic - 3.1",
description: "basic - mike",
skipDoc: true,
input: "mike: 3",
expected: "mike: 3\n",
},
{
description: "basic - 3.1",
skipDoc: true,
input: "{mike: 3}",
expected: "{mike: 3}\n",
},
{
description: "basic - map multiple entries",
skipDoc: true,
@@ -40,23 +34,23 @@ var goccyYamlFormatScenarios = []FormatScenario{
{
description: "basic - 3.1",
skipDoc: true,
input: "{\nmike: 3\n}",
input: "{\n mike: 3\n}",
expected: "{mike: 3}\n",
},
{
description: "basic - 3.1",
description: "basic - tag with number",
skipDoc: true,
input: "mike: !!cat 3",
expected: "mike: !!cat 3\n",
},
{
description: "basic - 3.1",
description: "basic - array of numbers",
skipDoc: true,
input: "- 3",
expected: "- 3\n",
},
{
description: "basic - 3.1",
description: "basic - single line array",
skipDoc: true,
input: "[3]",
expected: "[3]\n",
@@ -159,7 +153,7 @@ var goccyYamlFormatScenarios = []FormatScenario{
// },
}
func testGoccyYamlScenario(t *testing.T, s FormatScenario) {
func testGoccyYamlScenario(t *testing.T, s formatScenario) {
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewGoccyYAMLDecoder(), NewYamlEncoder(ConfiguredYamlPreferences)), s.description)
}
+7 -7
View File
@@ -79,7 +79,7 @@ const roundTripMultiLineJson = `{
}
`
var jsonScenarios = []FormatScenario{
var jsonScenarios = []formatScenario{
{
description: "array empty",
skipDoc: true,
@@ -307,7 +307,7 @@ var jsonScenarios = []FormatScenario{
},
}
func documentRoundtripNdJsonScenario(w *bufio.Writer, s FormatScenario, indent int) {
func documentRoundtripNdJsonScenario(w *bufio.Writer, s formatScenario, indent int) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -335,7 +335,7 @@ func documentRoundtripNdJsonScenario(w *bufio.Writer, s FormatScenario, indent i
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(prefs))))
}
func documentDecodeNdJsonScenario(w *bufio.Writer, s FormatScenario) {
func documentDecodeNdJsonScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -385,7 +385,7 @@ func decodeJSON(t *testing.T, jsonString string) *CandidateNode {
return context.MatchingNodes.Front().Value.(*CandidateNode)
}
func testJSONScenario(t *testing.T, s FormatScenario) {
func testJSONScenario(t *testing.T, s formatScenario) {
prefs := ConfiguredJSONPreferences.Copy()
prefs.Indent = s.indent
prefs.UnwrapScalar = false
@@ -413,7 +413,7 @@ func testJSONScenario(t *testing.T, s FormatScenario) {
}
}
func documentJSONDecodeScenario(t *testing.T, w *bufio.Writer, s FormatScenario) {
func documentJSONDecodeScenario(t *testing.T, w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
@@ -443,7 +443,7 @@ func documentJSONDecodeScenario(t *testing.T, w *bufio.Writer, s FormatScenario)
}
func documentJSONScenario(t *testing.T, w *bufio.Writer, i interface{}) {
s := i.(FormatScenario)
s := i.(formatScenario)
if s.skipDoc {
return
}
@@ -464,7 +464,7 @@ func documentJSONScenario(t *testing.T, w *bufio.Writer, i interface{}) {
}
}
func documentJSONEncodeScenario(w *bufio.Writer, s FormatScenario) {
func documentJSONEncodeScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
if s.subdescription != "" {
+10 -9
View File
@@ -31,24 +31,25 @@ type token struct {
}
func (t *token) toString(detail bool) string {
if t.TokenType == operationToken {
switch t.TokenType {
case operationToken:
if detail {
return fmt.Sprintf("%v (%v)", t.Operation.toString(), t.Operation.OperationType.Precedence)
}
return t.Operation.toString()
} else if t.TokenType == openBracket {
case openBracket:
return "("
} else if t.TokenType == closeBracket {
case closeBracket:
return ")"
} else if t.TokenType == openCollect {
case openCollect:
return "["
} else if t.TokenType == closeCollect {
case closeCollect:
return "]"
} else if t.TokenType == openCollectObject {
case openCollectObject:
return "{"
} else if t.TokenType == closeCollectObject {
case closeCollectObject:
return "}"
} else if t.TokenType == traverseArrayCollect {
case traverseArrayCollect:
return ".["
}
@@ -126,7 +127,7 @@ func handleToken(tokens []*token, index int, postProcessedTokens []*token) (toke
if tokenIsOpType(currentToken, createMapOpType) {
log.Debugf("tokenIsOpType: createMapOpType")
// check the previous token is '[', means we are slice, but dont have a first number
if tokens[index-1].TokenType == traverseArrayCollect {
if index > 0 && tokens[index-1].TokenType == traverseArrayCollect {
log.Debugf("previous token is : traverseArrayOpType")
// need to put the number 0 before this token, as that is implied
postProcessedTokens = append(postProcessedTokens, &token{TokenType: operationToken, Operation: createValueOperation(0, "0")})
+51 -40
View File
@@ -7,7 +7,7 @@ import (
"github.com/alecthomas/participle/v2/lexer"
)
var participleYqRules = []*ParticipleYqRule{
var participleYqRules = []*participleYqRule{
{"LINE_COMMENT", `line_?comment|lineComment`, opTokenWithPrefs(getCommentOpType, assignCommentOpType, commentOpPreferences{LineComment: true}), 0},
{"HEAD_COMMENT", `head_?comment|headComment`, opTokenWithPrefs(getCommentOpType, assignCommentOpType, commentOpPreferences{HeadComment: true}), 0},
{"FOOT_COMMENT", `foot_?comment|footComment`, opTokenWithPrefs(getCommentOpType, assignCommentOpType, commentOpPreferences{FootComment: true}), 0},
@@ -40,6 +40,7 @@ var participleYqRules = []*ParticipleYqRule{
simpleOp("map", mapOpType),
simpleOp("filter", filterOpType),
simpleOp("pick", pickOpType),
simpleOp("omit", omitOpType),
{"FlattenWithDepth", `flatten\([0-9]+\)`, flattenWithDepth(), 0},
{"Flatten", `flatten`, opTokenWithPrefs(flattenOpType, nil, flattenPreferences{depth: -1}), 0},
@@ -57,34 +58,43 @@ var participleYqRules = []*ParticipleYqRule{
{"ArrayToMap", "array_?to_?map", expressionOpToken(`(.[] | select(. != null) ) as $i ireduce({}; .[$i | key] = $i)`), 0},
{"YamlEncodeWithIndent", `to_?yaml\([0-9]+\)`, CreateEncodeYqActionParsingIndent(YamlFormat), 0},
{"YamlEncodeWithIndent", `to_?yaml\([0-9]+\)`, encodeParseIndent(YamlFormat), 0},
{"XMLEncodeWithIndent", `to_?xml\([0-9]+\)`, encodeParseIndent(XMLFormat), 0},
{"JSONEncodeWithIndent", `to_?json\([0-9]+\)`, encodeParseIndent(JSONFormat), 0},
{"JSONEncodeWithIndent", `to_?json\([0-9]+\)`, CreateEncodeYqActionParsingIndent(JSONFormat), 0},
{"YamlDecode", `from_?yaml|@yamld|from_?json|@jsond`, decodeOp(YamlFormat), 0},
{"YamlEncode", `to_?yaml|@yaml`, encodeWithIndent(YamlFormat, 2), 0},
{"YamlDecode", `from_?yaml|@yamld|from_?json|@jsond`, CreateDecodeOpYqAction(YamlFormat), 0},
{"YamlEncode", `to_?yaml|@yaml`, CreateEncodeOpYqAction(YamlFormat, 2), 0},
{"JSONEncode", `to_?json`, encodeWithIndent(JSONFormat, 2), 0},
{"JSONEncodeNoIndent", `@json`, encodeWithIndent(JSONFormat, 0), 0},
{"JSONEncode", `to_?json`, CreateEncodeOpYqAction(JSONFormat, 2), 0},
{"JSONEncodeNoIndent", `@json`, CreateEncodeOpYqAction(JSONFormat, 0), 0},
{"PropertiesDecode", `from_?props|@propsd`, decodeOp(PropertiesFormat), 0},
{"PropsEncode", `to_?props|@props`, encodeWithIndent(PropertiesFormat, 2), 0},
{"CSVDecode", `from_?csv|@csvd`, CreateDecodeOpYqAction(CSVFormat), 0},
{"CSVEncode", `to_?csv|@csv`, CreateEncodeOpYqAction(CSVFormat, 0), 0},
{"XmlDecode", `from_?xml|@xmld`, decodeOp(XMLFormat), 0},
{"XMLEncode", `to_?xml`, encodeWithIndent(XMLFormat, 2), 0},
{"XMLEncodeNoIndent", `@xml`, encodeWithIndent(XMLFormat, 0), 0},
{"TSVDecode", `from_?tsv|@tsvd`, CreateDecodeOpYqAction(TSVFormat), 0},
{"TSVEncode", `to_?tsv|@tsv`, CreateEncodeOpYqAction(TSVFormat, 0), 0},
{"CSVDecode", `from_?csv|@csvd`, decodeOp(CSVFormat), 0},
{"CSVEncode", `to_?csv|@csv`, encodeWithIndent(CSVFormat, 0), 0},
{"Base64d", `@base64d`, CreateDecodeOpYqAction(Base64Format), 0},
{"Base64", `@base64`, CreateEncodeOpYqAction(Base64Format, 0), 0},
{"TSVDecode", `from_?tsv|@tsvd`, decodeOp(TSVFormat), 0},
{"TSVEncode", `to_?tsv|@tsv`, encodeWithIndent(TSVFormat, 0), 0},
{"Urid", `@urid`, CreateDecodeOpYqAction(UriFormat), 0},
{"Uri", `@uri`, CreateEncodeOpYqAction(UriFormat, 0), 0},
{"SH", `@sh`, CreateEncodeOpYqAction(ShFormat, 0), 0},
{"Base64d", `@base64d`, decodeOp(Base64Format), 0},
{"Base64", `@base64`, encodeWithIndent(Base64Format, 0), 0},
{"LoadBase64", `load_?base64`, CreateLoadOpYqAction(NewBase64Decoder()), 0},
{"Urid", `@urid`, decodeOp(UriFormat), 0},
{"Uri", `@uri`, encodeWithIndent(UriFormat, 0), 0},
{"SH", `@sh`, encodeWithIndent(ShFormat, 0), 0},
simpleOp(`load_?str|str_?load`, loadStringOpType),
{"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(ConfiguredXMLPreferences)), 0},
{"LoadYaml", `load`, CreateLoadOpYqAction(NewYamlDecoder(LoadYamlPreferences)), 0},
{"LoadBase64", `load_?base64`, loadOp(NewBase64Decoder()), 0},
{"LoadProperties", `load_?props`, loadOp(NewPropertiesDecoder()), 0},
simpleOp("load_?str|str_?load", loadStringOpType),
{"LoadYaml", `load`, loadOp(NewYamlDecoder(LoadYamlPreferences)), 0},
{"SplitDocument", `splitDoc|split_?doc`, opToken(splitDocumentOpType), 0},
@@ -189,6 +199,9 @@ var participleYqRules = []*ParticipleYqRule{
{"GreaterThan", `\s*>\s*`, opTokenWithPrefs(compareOpType, nil, compareTypePref{OrEqual: false, Greater: true}), 0},
{"LessThan", `\s*<\s*`, opTokenWithPrefs(compareOpType, nil, compareTypePref{OrEqual: false, Greater: false}), 0},
simpleOp("min", minOpType),
simpleOp("max", maxOpType),
{"AssignRelative", `\|=[c]*`, assignOpToken(true), 0},
{"Assign", `=[c]*`, assignOpToken(false), 0},
@@ -214,11 +227,13 @@ var participleYqRules = []*ParticipleYqRule{
{"SubtractAssign", `\-=`, opToken(subtractAssignOpType), 0},
{"Subtract", `\-`, opToken(subtractOpType), 0},
{"Comment", `#.*`, nil, 0},
simpleOp("pivot", pivotOpType),
}
type yqAction func(lexer.Token) (*token, error)
type ParticipleYqRule struct {
type participleYqRule struct {
Name string
Pattern string
CreateYqToken yqAction
@@ -229,16 +244,12 @@ type participleLexer struct {
lexerDefinition lexer.StringDefinition
}
func simpleOp(name string, opType *operationType) *ParticipleYqRule {
return &ParticipleYqRule{strings.ToUpper(string(name[1])) + name[1:], name, opToken(opType), 0}
func simpleOp(name string, opType *operationType) *participleYqRule {
return &participleYqRule{strings.ToUpper(string(name[1])) + name[1:], name, opToken(opType), 0}
}
func assignableOp(name string, opType *operationType, assignOpType *operationType) *ParticipleYqRule {
return &ParticipleYqRule{strings.ToUpper(string(name[1])) + name[1:], name, opTokenWithPrefs(opType, assignOpType, nil), 0}
}
func RegisterRules(rules []*ParticipleYqRule) {
participleYqRules = append(participleYqRules, rules...)
func assignableOp(name string, opType *operationType, assignOpType *operationType) *participleYqRule {
return &participleYqRule{strings.ToUpper(string(name[1])) + name[1:], name, opTokenWithPrefs(opType, assignOpType, nil), 0}
}
func newParticipleLexer() expressionTokeniser {
@@ -300,7 +311,7 @@ func opTokenWithPrefs(opType *operationType, assignOpType *operationType, prefer
}
func expressionOpToken(expression string) yqAction {
return func(rawToken lexer.Token) (*token, error) {
return func(_ lexer.Token) (*token, error) {
prefs := expressionOpPreferences{expression: expression}
expressionOp := &Operation{OperationType: expressionOpType, Preferences: prefs}
return &token{TokenType: operationToken, Operation: expressionOp}, nil
@@ -317,7 +328,7 @@ func flattenWithDepth() yqAction {
prefs := flattenPreferences{depth: depth}
op := &Operation{OperationType: flattenOpType, Value: flattenOpType.Type, StringValue: value, Preferences: prefs}
return &token{TokenType: operationToken, Operation: op}, nil
return &token{TokenType: operationToken, Operation: op, CheckForPostTraverse: flattenOpType.CheckForPostTraverse}, nil
}
}
@@ -395,7 +406,7 @@ func envOp(strenv bool) yqAction {
envOperation.OperationType = envOpType
envOperation.Preferences = preferences
return &token{TokenType: operationToken, Operation: envOperation}, nil
return &token{TokenType: operationToken, Operation: envOperation, CheckForPostTraverse: envOpType.CheckForPostTraverse}, nil
}
}
@@ -506,19 +517,19 @@ func parentWithLevel() yqAction {
prefs := parentOpPreferences{Level: level}
op := &Operation{OperationType: getParentOpType, Value: getParentOpType.Type, StringValue: value, Preferences: prefs}
return &token{TokenType: operationToken, Operation: op}, nil
return &token{TokenType: operationToken, Operation: op, CheckForPostTraverse: true}, nil
}
}
func parentWithDefaultLevel() yqAction {
return func(rawToken lexer.Token) (*token, error) {
return func(_ lexer.Token) (*token, error) {
prefs := parentOpPreferences{Level: 1}
op := &Operation{OperationType: getParentOpType, Value: getParentOpType.Type, StringValue: getParentOpType.Type, Preferences: prefs}
return &token{TokenType: operationToken, Operation: op}, nil
return &token{TokenType: operationToken, Operation: op, CheckForPostTraverse: true}, nil
}
}
func CreateEncodeYqActionParsingIndent(outputFormat *Format) yqAction {
func encodeParseIndent(outputFormat *Format) yqAction {
return func(rawToken lexer.Token) (*token, error) {
value := rawToken.Value
var indent, errParsingInt = extractNumberParameter(value)
@@ -532,17 +543,17 @@ func CreateEncodeYqActionParsingIndent(outputFormat *Format) yqAction {
}
}
func CreateEncodeOpYqAction(outputFormat *Format, indent int) yqAction {
func encodeWithIndent(outputFormat *Format, indent int) yqAction {
prefs := encoderPreferences{format: outputFormat, indent: indent}
return opTokenWithPrefs(encodeOpType, nil, prefs)
}
func CreateDecodeOpYqAction(format *Format) yqAction {
func decodeOp(format *Format) yqAction {
prefs := decoderPreferences{format: format}
return opTokenWithPrefs(decodeOpType, nil, prefs)
}
func CreateLoadOpYqAction(decoder Decoder) yqAction {
func loadOp(decoder Decoder) yqAction {
prefs := loadPrefs{decoder}
return opTokenWithPrefs(loadOpType, nil, prefs)
}
@@ -557,13 +568,13 @@ func literalToken(tt tokenType, checkForPost bool) yqAction {
}
}
func (p *participleLexer) getYqDefinition(rawToken lexer.Token) *ParticipleYqRule {
func (p *participleLexer) getYqDefinition(rawToken lexer.Token) *participleYqRule {
for _, yqRule := range participleYqRules {
if yqRule.ParticipleTokenType == rawToken.Type {
return yqRule
}
}
return &ParticipleYqRule{}
return &participleYqRule{}
}
func (p *participleLexer) Tokenise(expression string) ([]*token, error) {
File diff suppressed because it is too large Load Diff
+34 -4
View File
@@ -95,10 +95,20 @@ func parseSnippet(value string) (*CandidateNode, error) {
if err != nil {
return nil, err
}
if result.Kind == ScalarNode {
result.LineComment = result.LeadingContent
} else {
result.HeadComment = result.LeadingContent
}
result.LeadingContent = ""
if result.Tag == "!!str" {
// use the original string value, as
// decoding drops new lines
return CreateScalarNode(value, value), nil
newNode := createScalarNode(value, value)
newNode.LineComment = result.LineComment
return newNode, nil
}
result.Line = 0
result.Column = 0
@@ -114,8 +124,8 @@ func recursiveNodeEqual(lhs *CandidateNode, rhs *CandidateNode) bool {
//process custom tags of scalar nodes.
//dont worry about matching tags of maps or arrays.
lhsTag := lhs.GuessTagFromCustomType()
rhsTag := rhs.GuessTagFromCustomType()
lhsTag := lhs.guessTagFromCustomType()
rhsTag := rhs.guessTagFromCustomType()
if lhsTag != rhsTag {
return false
@@ -135,8 +145,12 @@ func recursiveNodeEqual(lhs *CandidateNode, rhs *CandidateNode) bool {
return false
}
// yaml numbers can be hex and octal encoded...
// yaml numbers can have underscores, be hex and octal encoded...
func parseInt64(numberString string) (string, int64, error) {
if strings.Contains(numberString, "_") {
numberString = strings.ReplaceAll(numberString, "_", "")
}
if strings.HasPrefix(numberString, "0x") ||
strings.HasPrefix(numberString, "0X") {
num, err := strconv.ParseInt(numberString[2:], 16, 64)
@@ -161,6 +175,22 @@ func parseInt(numberString string) (int, error) {
return int(parsed), err
}
func headAndLineComment(node *CandidateNode) string {
return headComment(node) + lineComment(node)
}
func headComment(node *CandidateNode) string {
return strings.Replace(node.HeadComment, "#", "", 1)
}
func lineComment(node *CandidateNode) string {
return strings.Replace(node.LineComment, "#", "", 1)
}
func footComment(node *CandidateNode) string {
return strings.Replace(node.FootComment, "#", "", 1)
}
// use for debugging only
func NodesToString(collection *list.List) string {
if !log.IsEnabledFor(logging.DEBUG) {
+25 -1
View File
@@ -62,6 +62,16 @@ var parseSnippetScenarios = []parseSnippetScenario{
Column: 0,
},
},
{
snippet: "# things",
expected: &CandidateNode{
Kind: ScalarNode,
Tag: "!!null",
LineComment: "# things",
Line: 0,
Column: 0,
},
},
{
snippet: "3.1",
expected: &CandidateNode{
@@ -106,6 +116,7 @@ func TestParseSnippet(t *testing.T) {
type parseInt64Scenario struct {
numberString string
expectedParsedNumber int64
expectedFormatString string
}
var parseInt64Scenarios = []parseInt64Scenario{
@@ -113,10 +124,20 @@ var parseInt64Scenarios = []parseInt64Scenario{
numberString: "34",
expectedParsedNumber: 34,
},
{
numberString: "10_000",
expectedParsedNumber: 10000,
expectedFormatString: "10000",
},
{
numberString: "0x10",
expectedParsedNumber: 16,
},
{
numberString: "0x10_000",
expectedParsedNumber: 65536,
expectedFormatString: "0x10000",
},
{
numberString: "0o10",
expectedParsedNumber: 8,
@@ -132,7 +153,10 @@ func TestParseInt64(t *testing.T) {
t.Error(err)
}
test.AssertResultComplexWithContext(t, tt.expectedParsedNumber, actualNumber, tt.numberString)
if tt.expectedFormatString == "" {
tt.expectedFormatString = tt.numberString
}
test.AssertResultComplexWithContext(t, tt.numberString, fmt.Sprintf(format, actualNumber), fmt.Sprintf("Formatting of: %v", tt.numberString))
test.AssertResultComplexWithContext(t, tt.expectedFormatString, fmt.Sprintf(format, actualNumber), fmt.Sprintf("Formatting of: %v", tt.numberString))
}
}

Some files were not shown because too many files have changed in this diff Show More