mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f43a4a265 | ||
|
|
bb6f07d147 | ||
|
|
759456e375 | ||
|
|
5e59803037 | ||
|
|
a0cb691601 | ||
|
|
086f0ec6b9 | ||
|
|
89cbe63343 | ||
|
|
07cd3d4b8b | ||
|
|
b7b6988e76 | ||
|
|
9de2039c31 | ||
|
|
767709fef5 | ||
|
|
d9ae8e1e5a | ||
|
|
b0fa0e5b86 | ||
|
|
6777d639c0 | ||
|
|
de8dcff803 | ||
|
|
765ada4dc6 | ||
|
|
1405584892 | ||
|
|
8c9c326342 | ||
|
|
e90b00957b | ||
|
|
71f5f76213 | ||
|
|
b9e304e7a4 | ||
|
|
d473c39a44 | ||
|
|
9624410add | ||
|
|
b55fe48bd8 | ||
|
|
721dd57ed4 | ||
|
|
6fc3566acd | ||
|
|
4b63d92a3c | ||
|
|
3ccd32a47e | ||
|
|
3f913afbb9 | ||
|
|
ff598e1933 | ||
|
|
23de61a8d7 | ||
|
|
64135a16e1 | ||
|
|
06d8715cbe | ||
|
|
e15633023f | ||
|
|
6f0a329331 | ||
|
|
55511de9af | ||
|
|
2db69c91c9 | ||
|
|
33e35d10dd | ||
|
|
dfdbbbb24a | ||
|
|
55c4d01a91 | ||
|
|
7dc3d62bb6 | ||
|
|
11116804c5 | ||
|
|
f68b24323e | ||
|
|
8f166a9848 | ||
|
|
3c36db9285 | ||
|
|
605d6fab9b | ||
|
|
1f9a3f5f6c | ||
|
|
a06320f13c | ||
|
|
279996533d | ||
|
|
efe942727d | ||
|
|
e4dc70cc84 | ||
|
|
8ade1275e2 | ||
|
|
e1e05d85e3 | ||
|
|
b99467432e | ||
|
|
6b07143af7 | ||
|
|
ed234e37ce | ||
|
|
c0e4917d52 | ||
|
|
2713893f87 | ||
|
|
6bb221e973 | ||
|
|
7eb01a81da | ||
|
|
5c117204fa | ||
|
|
a4fa8f1341 | ||
|
|
69caccd2d3 | ||
|
|
67fb924e0e | ||
|
|
b64187fe32 | ||
|
|
8e6ceba2ac | ||
|
|
6ef04e1e77 | ||
|
|
10029420a5 | ||
|
|
f91093d5fe | ||
|
|
090432d241 | ||
|
|
22d5bd3615 | ||
|
|
0d477841da | ||
|
|
1f72817d74 | ||
|
|
125d04a75b | ||
|
|
08f6a90603 | ||
|
|
da398765b8 | ||
|
|
d356fa0d0b | ||
|
|
d22bfc241b | ||
|
|
954affea23 | ||
|
|
b0d1afb601 | ||
|
|
b286636909 | ||
|
|
bdf47c9797 | ||
|
|
1cc20d52bb | ||
|
|
651d9edf88 | ||
|
|
903605df39 | ||
|
|
0f9facc84b | ||
|
|
5af86b1333 |
48
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
48
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
version of yq:
|
||||||
|
operating system:
|
||||||
|
|
||||||
|
**Input Yaml**
|
||||||
|
Concise yaml document(s) (as simple as possible to show the bug)
|
||||||
|
data1.yml:
|
||||||
|
```yaml
|
||||||
|
this: should really work
|
||||||
|
```
|
||||||
|
|
||||||
|
data2.yml:
|
||||||
|
```yaml
|
||||||
|
but: it strangely didn't
|
||||||
|
```
|
||||||
|
|
||||||
|
**Command**
|
||||||
|
The command you ran:
|
||||||
|
```
|
||||||
|
yq merge data1.yml data2.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Actual behavior**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
cat: meow
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
this: should really work
|
||||||
|
but: it strangely didn't
|
||||||
|
```
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
36
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
If we have data1.yml like:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
country: Australia
|
||||||
|
```
|
||||||
|
|
||||||
|
And we run a command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yq predictWeather data1.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
it could output
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
temp: 32
|
||||||
|
```
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
34
.github/workflows/go.yml
vendored
Normal file
34
.github/workflows/go.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: Build
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Set up Go 1.15
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.15
|
||||||
|
id: go
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: |
|
||||||
|
go get -v -t -d ./...
|
||||||
|
if [ -f Gopkg.toml ]; then
|
||||||
|
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||||
|
dep ensure
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Download deps
|
||||||
|
run: |
|
||||||
|
export PATH=${PATH}:`go env GOPATH`/bin
|
||||||
|
scripts/devtools.sh
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
export PATH=${PATH}:`go env GOPATH`/bin
|
||||||
|
make local build
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
language: go
|
|
||||||
go:
|
|
||||||
- 1.13.x
|
|
||||||
script:
|
|
||||||
- scripts/devtools.sh
|
|
||||||
- make local build
|
|
||||||
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at mikefarah@gmail.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
||||||
8
CONTRIBUTING.md
Normal file
8
CONTRIBUTING.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
1. Install (golang)[https://golang.org/]
|
||||||
|
1. Run `scripts/devtools.sh` to install the required devtools
|
||||||
|
2. Run `make [local] vendor` to install the vendor dependencies
|
||||||
|
2. Run `make [local] test` to ensure you can run the existing tests
|
||||||
|
3. Write unit tests - (see existing examples). Changes will not be accepted without corresponding unit tests.
|
||||||
|
4. Make the code changes.
|
||||||
|
5. `make [local] test` to lint code and run tests
|
||||||
|
6. Profit! ok no profit, but raise a PR and get kudos :)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.13 as builder
|
FROM golang:1.15 as builder
|
||||||
|
|
||||||
WORKDIR /go/src/mikefarah/yq
|
WORKDIR /go/src/mikefarah/yq
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.13
|
FROM golang:1.15
|
||||||
|
|
||||||
COPY scripts/devtools.sh /opt/devtools.sh
|
COPY scripts/devtools.sh /opt/devtools.sh
|
||||||
|
|
||||||
@@ -9,15 +9,15 @@ RUN set -e -x \
|
|||||||
RUN set -ex \
|
RUN set -ex \
|
||||||
&& buildDeps=' \
|
&& buildDeps=' \
|
||||||
build-essential \
|
build-essential \
|
||||||
python-dev \
|
python3-dev \
|
||||||
' \
|
' \
|
||||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||||
$buildDeps \
|
$buildDeps \
|
||||||
python2.7 \
|
python3 \
|
||||||
python-setuptools \
|
python3-setuptools \
|
||||||
python-wheel \
|
python3-wheel \
|
||||||
python-pip \
|
python3-pip \
|
||||||
&& pip install --upgrade \
|
&& pip3 install --upgrade \
|
||||||
pip \
|
pip \
|
||||||
'Markdown>=2.6.9' \
|
'Markdown>=2.6.9' \
|
||||||
'mkdocs>=0.16.3' \
|
'mkdocs>=0.16.3' \
|
||||||
|
|||||||
60
README.md
60
README.md
@@ -1,6 +1,6 @@
|
|||||||
# yq
|
# yq
|
||||||
|
|
||||||
[](https://travis-ci.com/mikefarah/yq/)   
|
   
|
||||||
|
|
||||||
|
|
||||||
a lightweight and portable command-line YAML processor
|
a lightweight and portable command-line YAML processor
|
||||||
@@ -12,21 +12,26 @@ V3 is officially out - if you've been using v2 and want/need to upgrade, checkou
|
|||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
### Download the latest binary
|
### [Download the latest binary](https://github.com/mikefarah/yq/releases/latest)
|
||||||
|
|
||||||
[Here](https://github.com/mikefarah/yq/releases/latest)
|
### MacOS:
|
||||||
|
|
||||||
### On MacOS:
|
|
||||||
```
|
```
|
||||||
brew install yq
|
brew install yq
|
||||||
```
|
```
|
||||||
### On Ubuntu and other Linux distros supporting `snap` packages:
|
|
||||||
|
### Windows:
|
||||||
|
```
|
||||||
|
choco install yq
|
||||||
|
```
|
||||||
|
Supported by @chillum
|
||||||
|
|
||||||
|
### Ubuntu and other Linux distros supporting `snap` packages:
|
||||||
```
|
```
|
||||||
snap install yq
|
snap install yq
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Snap notes
|
#### Snap notes
|
||||||
`yq` installs with with [_strict confinement_](https://docs.snapcraft.io/snap-confinement/6233) in snap, this means it doesn't have direct access to root files. To read root files you can:
|
`yq` installs with [_strict confinement_](https://docs.snapcraft.io/snap-confinement/6233) in snap, this means it doesn't have direct access to root files. To read root files you can:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo cat /etc/myfile | yq r - a.path
|
sudo cat /etc/myfile | yq r - a.path
|
||||||
@@ -50,6 +55,8 @@ sudo add-apt-repository ppa:rmescandon/yq
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install yq -y
|
sudo apt install yq -y
|
||||||
```
|
```
|
||||||
|
Supported by @rmescandon
|
||||||
|
|
||||||
### Go Get:
|
### Go Get:
|
||||||
```
|
```
|
||||||
GO111MODULE=on go get github.com/mikefarah/yq/v3
|
GO111MODULE=on go get github.com/mikefarah/yq/v3
|
||||||
@@ -60,27 +67,29 @@ GO111MODULE=on go get github.com/mikefarah/yq/v3
|
|||||||
Oneshot use:
|
Oneshot use:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --rm -v ${PWD}:/workdir mikefarah/yq yq [flags] <command> FILE...
|
docker run --rm -v "${PWD}":/workdir mikefarah/yq yq [flags] <command> FILE...
|
||||||
```
|
```
|
||||||
|
|
||||||
Run commands interactively:
|
Run commands interactively:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --rm -it -v ${PWD}:/workdir mikefarah/yq sh
|
docker run --rm -it -v "${PWD}":/workdir mikefarah/yq sh
|
||||||
```
|
```
|
||||||
|
|
||||||
It can be useful to have a bash function to avoid typing the whole docker command:
|
It can be useful to have a bash function to avoid typing the whole docker command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yq() {
|
yq() {
|
||||||
docker run --rm -i -v ${PWD}:/workdir mikefarah/yq yq $@
|
docker run --rm -i -v "${PWD}":/workdir mikefarah/yq yq "$@"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Written in portable go, so you can download a lovely dependency free binary
|
- Written in portable go, so you can download a lovely dependency free binary
|
||||||
|
- [Colorize the output](https://mikefarah.gitbook.io/yq/usage/output-format#colorize-output)
|
||||||
- [Deep read a yaml file with a given path expression](https://mikefarah.gitbook.io/yq/commands/read#basic)
|
- [Deep read a yaml file with a given path expression](https://mikefarah.gitbook.io/yq/commands/read#basic)
|
||||||
- [List matching paths of a given path expression](https://mikefarah.gitbook.io/yq/commands/read#path-only)
|
- [List matching paths of a given path expression](https://mikefarah.gitbook.io/yq/commands/read#path-only)
|
||||||
|
- [Return the lengths of arrays/object/scalars](https://mikefarah.gitbook.io/yq/commands/read#printing-length-of-the-results)
|
||||||
- Update a yaml file given a [path expression](https://mikefarah.gitbook.io/yq/commands/write-update#basic) or [script file](https://mikefarah.gitbook.io/yq/commands/write-update#basic)
|
- Update a yaml file given a [path expression](https://mikefarah.gitbook.io/yq/commands/write-update#basic) or [script file](https://mikefarah.gitbook.io/yq/commands/write-update#basic)
|
||||||
- Update creates any missing entries in the path on the fly
|
- Update creates any missing entries in the path on the fly
|
||||||
- Deeply [compare](https://mikefarah.gitbook.io/yq/commands/compare) yaml files
|
- Deeply [compare](https://mikefarah.gitbook.io/yq/commands/compare) yaml files
|
||||||
@@ -92,6 +101,7 @@ yq() {
|
|||||||
- [Pipe data in by using '-'](https://mikefarah.gitbook.io/yq/commands/read#from-stdin)
|
- [Pipe data in by using '-'](https://mikefarah.gitbook.io/yq/commands/read#from-stdin)
|
||||||
- [Merge](https://mikefarah.gitbook.io/yq/commands/merge) multiple yaml files with various options for [overriding](https://mikefarah.gitbook.io/yq/commands/merge#overwrite-values) and [appending](https://mikefarah.gitbook.io/yq/commands/merge#append-values-with-arrays)
|
- [Merge](https://mikefarah.gitbook.io/yq/commands/merge) multiple yaml files with various options for [overriding](https://mikefarah.gitbook.io/yq/commands/merge#overwrite-values) and [appending](https://mikefarah.gitbook.io/yq/commands/merge#append-values-with-arrays)
|
||||||
- Supports multiple documents in a single yaml file for [reading](https://mikefarah.gitbook.io/yq/commands/read#multiple-documents), [writing](https://mikefarah.gitbook.io/yq/commands/write-update#multiple-documents) and [merging](https://mikefarah.gitbook.io/yq/commands/merge#multiple-documents)
|
- Supports multiple documents in a single yaml file for [reading](https://mikefarah.gitbook.io/yq/commands/read#multiple-documents), [writing](https://mikefarah.gitbook.io/yq/commands/write-update#multiple-documents) and [merging](https://mikefarah.gitbook.io/yq/commands/merge#multiple-documents)
|
||||||
|
- General shell completion scripts (bash/zsh/fish/powershell) (https://mikefarah.gitbook.io/yq/commands/shell-completion)
|
||||||
|
|
||||||
## [Usage](https://mikefarah.gitbook.io/yq/)
|
## [Usage](https://mikefarah.gitbook.io/yq/)
|
||||||
|
|
||||||
@@ -103,17 +113,19 @@ Usage:
|
|||||||
yq [command]
|
yq [command]
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
compare yq x [--prettyPrint/-P] dataA.yaml dataB.yaml 'b.e(name==fr*).value'
|
compare yq x [--prettyPrint/-P] dataA.yaml dataB.yaml 'b.e(name==fr*).value'
|
||||||
delete yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)'
|
delete yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)'
|
||||||
help Help about any command
|
help Help about any command
|
||||||
merge yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml
|
merge yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml
|
||||||
new yq n [--script/-s script_file] a.b.c newValue
|
new yq n [--script/-s script_file] a.b.c newValue
|
||||||
prefix yq p [--inplace/-i] [--doc/-d index] sample.yaml a.b.c
|
prefix yq p [--inplace/-i] [--doc/-d index] sample.yaml a.b.c
|
||||||
read yq r [--printMode/-p pv] sample.yaml 'b.e(name==fr*).value'
|
read yq r [--printMode/-p pv] sample.yaml 'b.e(name==fr*).value'
|
||||||
validate yq v sample.yaml
|
shell-completion Generates shell completion scripts
|
||||||
write yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue
|
validate yq v sample.yaml
|
||||||
|
write yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
-C, --colors print with colors
|
||||||
-h, --help help for yq
|
-h, --help help for yq
|
||||||
-I, --indent int sets indent level for output (default 2)
|
-I, --indent int sets indent level for output (default 2)
|
||||||
-P, --prettyPrint pretty print
|
-P, --prettyPrint pretty print
|
||||||
@@ -124,11 +136,5 @@ Flags:
|
|||||||
Use "yq [command] --help" for more information about a command.
|
Use "yq [command] --help" for more information about a command.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contribute
|
## Known Issues
|
||||||
|
- `yq` attempts to preserve comment positions and whitespace as much as possible, but it does not handle all scenarios (see https://github.com/go-yaml/yaml/tree/v3 for details)
|
||||||
1. `scripts/devtools.sh`
|
|
||||||
2. `make [local] vendor`
|
|
||||||
3. add unit tests
|
|
||||||
4. apply changes to go.mod
|
|
||||||
5. `make [local] build`
|
|
||||||
7. profit
|
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
|
|
||||||
Major release! Upgraded underlying yaml parser, re-written majority of yq. This has brought on a number of features that have been in demand for a while (see below).
|
|
||||||
|
|
||||||
This is in beta and needs some community feedback and testing :)
|
|
||||||
|
|
||||||
# New Features
|
|
||||||
- Keeps yaml comments and formatting, can specify yaml tags when updating. https://github.com/mikefarah/yq/issues/19, https://github.com/mikefarah/yq/issues/169, https://github.com/mikefarah/yq/issues/107, https://github.com/mikefarah/yq/issues/171, https://github.com/mikefarah/yq/issues/245, https://github.com/mikefarah/yq/issues/303,https://github.com/mikefarah/yq/issues/308,https://github.com/mikefarah/yq/issues/314
|
|
||||||
- Handles anchors! https://github.com/mikefarah/yq/issues/310, https://github.com/mikefarah/yq/issues/178
|
|
||||||
- Can print out matching paths and values when splatting https://github.com/mikefarah/yq/issues/20
|
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
# Breaking changes
|
|
||||||
|
|
||||||
## Update scripts file format has changed to be more powerful.
|
|
||||||
Comments can be added, and delete commands have been introduced.
|
|
||||||
|
|
||||||
Before:
|
|
||||||
```yaml
|
|
||||||
b.e[+].name: Mike Farah
|
|
||||||
```
|
|
||||||
|
|
||||||
After:
|
|
||||||
```yaml
|
|
||||||
- command: update
|
|
||||||
path: b.e[+].thing
|
|
||||||
value:
|
|
||||||
#great
|
|
||||||
things: frog # wow!
|
|
||||||
- command: delete
|
|
||||||
path: b.d
|
|
||||||
```
|
|
||||||
|
|
||||||
https://github.com/mikefarah/yq/issues/305
|
|
||||||
|
|
||||||
## Reading and splatting, matching results are printed once per line.
|
|
||||||
e.g:
|
|
||||||
|
|
||||||
```json
|
|
||||||
parent:
|
|
||||||
childA:
|
|
||||||
no: matches here
|
|
||||||
childB:
|
|
||||||
there: matches
|
|
||||||
hi: no match
|
|
||||||
there2: also matches
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yq r sample.yaml 'parent.*.there*'
|
|
||||||
```
|
|
||||||
|
|
||||||
old
|
|
||||||
```yaml
|
|
||||||
- null
|
|
||||||
- - matches
|
|
||||||
- also matches
|
|
||||||
```
|
|
||||||
|
|
||||||
new
|
|
||||||
```yaml
|
|
||||||
matches
|
|
||||||
also matches
|
|
||||||
```
|
|
||||||
|
|
||||||
and you can print the matching paths:
|
|
||||||
|
|
||||||
yq r --printMode pv sample.yaml 'parent.*.there*'
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
parent.childB.there: matches
|
|
||||||
parent.childB.there2: also matches
|
|
||||||
```
|
|
||||||
13
action.yml
Normal file
13
action.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
name: 'yq - portable yaml processor'
|
||||||
|
description: 'create, read, update, delete, merge, validate and do more with yaml'
|
||||||
|
icon: command
|
||||||
|
color: gray-dark
|
||||||
|
inputs:
|
||||||
|
cmd:
|
||||||
|
description: 'The Command which should be run'
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: 'docker'
|
||||||
|
image: 'github-action/Dockerfile'
|
||||||
|
args:
|
||||||
|
- ${{ inputs.cmd }}
|
||||||
2121
cmd/commands_test.go
2121
cmd/commands_test.go
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/kylelemons/godebug/diff"
|
"github.com/kylelemons/godebug/diff"
|
||||||
@@ -11,6 +12,9 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// turn off for unit tests :(
|
||||||
|
var forceOsExit = true
|
||||||
|
|
||||||
func createCompareCmd() *cobra.Command {
|
func createCompareCmd() *cobra.Command {
|
||||||
var cmdCompare = &cobra.Command{
|
var cmdCompare = &cobra.Command{
|
||||||
Use: "compare [yaml_file_a] [yaml_file_b]",
|
Use: "compare [yaml_file_a] [yaml_file_b]",
|
||||||
@@ -27,6 +31,8 @@ yq x -d1 dataA.yaml dataB.yaml 'a.b.c'
|
|||||||
cmdCompare.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdCompare.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
cmdCompare.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
cmdCompare.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
||||||
cmdCompare.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
cmdCompare.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
||||||
|
cmdCompare.PersistentFlags().BoolVarP(&stripComments, "stripComments", "", false, "strip comments out before comparing")
|
||||||
|
cmdCompare.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
||||||
return cmdCompare
|
return cmdCompare
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +76,14 @@ func compareDocuments(cmd *cobra.Command, args []string) error {
|
|||||||
return errorDoingThings
|
return errorDoingThings
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Print(diff.Diff(strings.TrimSuffix(dataBufferA.String(), "\n"), strings.TrimSuffix(dataBufferB.String(), "\n")))
|
diffString := diff.Diff(strings.TrimSuffix(dataBufferA.String(), "\n"), strings.TrimSuffix(dataBufferB.String(), "\n"))
|
||||||
cmd.Print("\n")
|
|
||||||
|
if len(diffString) > 1 {
|
||||||
|
cmd.Print(diffString)
|
||||||
|
cmd.Print("\n")
|
||||||
|
if forceOsExit {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
115
cmd/compare_test.go
Normal file
115
cmd/compare_test.go
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCompareSameCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := ``
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareIgnoreCommentsCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare --stripComments ../examples/data1.yaml ../examples/data1-no-comments.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := ``
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareDontIgnoreCommentsCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1-no-comments.yaml")
|
||||||
|
|
||||||
|
expectedOutput := `-a: simple # just the best
|
||||||
|
+a: simple
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareExplodeAnchorsCommentsCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare --explodeAnchors ../examples/simple-anchor.yaml ../examples/simple-anchor-exploded.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := ``
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareDontExplodeAnchorsCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare ../examples/simple-anchor.yaml ../examples/simple-anchor-exploded.yaml")
|
||||||
|
|
||||||
|
expectedOutput := `-foo: &foo
|
||||||
|
+foo:
|
||||||
|
a: 1
|
||||||
|
foobar:
|
||||||
|
- !!merge <<: *foo
|
||||||
|
+ a: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareDifferentCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data3.yaml")
|
||||||
|
|
||||||
|
expectedOutput := `-a: simple # just the best
|
||||||
|
-b: [1, 2]
|
||||||
|
+a: "simple" # just the best
|
||||||
|
+b: [1, 3]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComparePrettyCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare -P ../examples/data1.yaml ../examples/data3.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := ` a: simple # just the best
|
||||||
|
b:
|
||||||
|
- 1
|
||||||
|
- - 2
|
||||||
|
+ - 3
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComparePathsCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare -P -ppv ../examples/data1.yaml ../examples/data3.yaml **")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := ` a: simple # just the best
|
||||||
|
b.[0]: 1
|
||||||
|
-b.[1]: 2
|
||||||
|
+b.[1]: 3
|
||||||
|
c.test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
@@ -7,12 +7,21 @@ import (
|
|||||||
|
|
||||||
var customTag = ""
|
var customTag = ""
|
||||||
var printMode = "v"
|
var printMode = "v"
|
||||||
|
var printLength = false
|
||||||
|
var unwrapScalar = true
|
||||||
|
var customStyle = ""
|
||||||
|
var anchorName = ""
|
||||||
|
var makeAlias = false
|
||||||
|
var stripComments = false
|
||||||
|
var collectIntoArray = false
|
||||||
var writeInplace = false
|
var writeInplace = false
|
||||||
var writeScript = ""
|
var writeScript = ""
|
||||||
var sourceYamlFile = ""
|
var sourceYamlFile = ""
|
||||||
var outputToJSON = false
|
var outputToJSON = false
|
||||||
|
var exitStatus = false
|
||||||
var prettyPrint = false
|
var prettyPrint = false
|
||||||
var explodeAnchors = false
|
var explodeAnchors = false
|
||||||
|
var colorsEnabled = false
|
||||||
var defaultValue = ""
|
var defaultValue = ""
|
||||||
var indent = 2
|
var indent = 2
|
||||||
var overwriteFlag = false
|
var overwriteFlag = false
|
||||||
|
|||||||
246
cmd/delete_test.go
Normal file
246
cmd/delete_test.go
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDeleteYamlCmd(t *testing.T) {
|
||||||
|
content := `a: 2
|
||||||
|
b:
|
||||||
|
c: things
|
||||||
|
d: something else
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `a: 2
|
||||||
|
b:
|
||||||
|
d: something else
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteDeepDoesNotExistCmd(t *testing.T) {
|
||||||
|
content := `a: 2`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `a: 2
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteSplatYaml(t *testing.T) {
|
||||||
|
content := `a: other
|
||||||
|
b: [3, 4]
|
||||||
|
c:
|
||||||
|
toast: leave
|
||||||
|
test: 1
|
||||||
|
tell: 1
|
||||||
|
tasty.taco: cool
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s c.te*", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `a: other
|
||||||
|
b: [3, 4]
|
||||||
|
c:
|
||||||
|
toast: leave
|
||||||
|
tasty.taco: cool
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteSplatArrayYaml(t *testing.T) {
|
||||||
|
content := `a: 2
|
||||||
|
b:
|
||||||
|
hi:
|
||||||
|
- thing: item1
|
||||||
|
name: fred
|
||||||
|
- thing: item2
|
||||||
|
name: sam
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.hi[*].thing", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `a: 2
|
||||||
|
b:
|
||||||
|
hi:
|
||||||
|
- name: fred
|
||||||
|
- name: sam
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteDeepSplatArrayYaml(t *testing.T) {
|
||||||
|
content := `thing: 123
|
||||||
|
b:
|
||||||
|
hi:
|
||||||
|
- thing: item1
|
||||||
|
name: fred
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s **.thing", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `b:
|
||||||
|
hi:
|
||||||
|
- name: fred
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteSplatPrefixYaml(t *testing.T) {
|
||||||
|
content := `a: 2
|
||||||
|
b:
|
||||||
|
hi:
|
||||||
|
c: things
|
||||||
|
d: something else
|
||||||
|
there:
|
||||||
|
c: more things
|
||||||
|
d: more something else
|
||||||
|
there2:
|
||||||
|
c: more things also
|
||||||
|
d: more something else also
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.there*.c", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `a: 2
|
||||||
|
b:
|
||||||
|
hi:
|
||||||
|
c: things
|
||||||
|
d: something else
|
||||||
|
there:
|
||||||
|
d: more something else
|
||||||
|
there2:
|
||||||
|
d: more something else also
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteYamlArrayCmd(t *testing.T) {
|
||||||
|
content := `- 1
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s [1]", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `- 1
|
||||||
|
- 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteYamlArrayExpressionCmd(t *testing.T) {
|
||||||
|
content := `- name: fred
|
||||||
|
- name: cat
|
||||||
|
- name: thing
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s (name==cat)", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `- name: fred
|
||||||
|
- name: thing
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteYamlMulti(t *testing.T) {
|
||||||
|
content := `apples: great
|
||||||
|
---
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete -d 1 %s [1]", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `apples: great
|
||||||
|
---
|
||||||
|
- 1
|
||||||
|
- 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteYamlMultiAllCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
apples: great
|
||||||
|
---
|
||||||
|
apples: great
|
||||||
|
something: else
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("delete %s -d * apples", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
something: else`
|
||||||
|
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||||
|
}
|
||||||
337
cmd/merge_test.go
Normal file
337
cmd/merge_test.go
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMergeCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge ../examples/data1.yaml ../examples/data2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
toast: leave
|
||||||
|
tell: 1
|
||||||
|
tasty.taco: cool
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeOneFileCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge ../examples/data1.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeNoAutoCreateCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge -c=false ../examples/data1.yaml ../examples/data2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeOverwriteCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge -c=false --overwrite ../examples/data1.yaml ../examples/data2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: other # better than the original
|
||||||
|
b: [3, 4]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeAppendCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge --autocreate=false --append ../examples/data1.yaml ../examples/data2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b: [1, 2, 3, 4]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeAppendArraysCmd(t *testing.T) {
|
||||||
|
content := `people:
|
||||||
|
- name: Barry
|
||||||
|
age: 21`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `people:
|
||||||
|
- name: Roger
|
||||||
|
age: 44`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge --append -d* %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `people:
|
||||||
|
- name: Barry
|
||||||
|
age: 21
|
||||||
|
- name: Roger
|
||||||
|
age: 44
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeOverwriteAndAppendCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge --autocreate=false --append --overwrite ../examples/data1.yaml ../examples/data2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: other # better than the original
|
||||||
|
b: [1, 2, 3, 4]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeArraysCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge --append ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `[1, 2, 3, 4, 5]
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeCmd_Multi(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge -d1 ../examples/multiple_docs_small.yaml ../examples/data1.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: Easy! as one two three
|
||||||
|
---
|
||||||
|
another:
|
||||||
|
document: here
|
||||||
|
a: simple # just the best
|
||||||
|
b:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
---
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeYamlMultiAllCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
apples: green
|
||||||
|
---
|
||||||
|
something: else`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `apples: red
|
||||||
|
something: good`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge -d* %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
apples: green
|
||||||
|
something: good
|
||||||
|
---
|
||||||
|
something: else
|
||||||
|
apples: red
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeSpecialCharacterKeysCmd(t *testing.T) {
|
||||||
|
content := ``
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `key[bracket]: value
|
||||||
|
key.bracket: value
|
||||||
|
key"value": value
|
||||||
|
key'value': value
|
||||||
|
`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, mergeContent, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeYamlMultiAllOverwriteCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
apples: green
|
||||||
|
---
|
||||||
|
something: else`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `apples: red
|
||||||
|
something: good`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge --overwrite -d* %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
apples: red
|
||||||
|
something: good
|
||||||
|
---
|
||||||
|
something: good
|
||||||
|
apples: red
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeYamlNullMapCmd(t *testing.T) {
|
||||||
|
content := `b:`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `b:
|
||||||
|
thing: a frog
|
||||||
|
`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, mergeContent, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeCmd_Error(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to missing arg")
|
||||||
|
}
|
||||||
|
expectedOutput := `Must provide at least 1 yaml file`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeCmd_ErrorUnreadableFile(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge ../examples/data1.yaml fake-unknown")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to unknown file")
|
||||||
|
}
|
||||||
|
var expectedOutput string
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||||
|
} else {
|
||||||
|
expectedOutput = `open fake-unknown: no such file or directory`
|
||||||
|
}
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeCmd_Inplace(t *testing.T) {
|
||||||
|
filename := test.WriteTempYamlFile(test.ReadTempYamlFile("../examples/data1.yaml"))
|
||||||
|
err := os.Chmod(filename, os.FileMode(int(0666)))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge -i %s ../examples/data2.yaml", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
info, _ := os.Stat(filename)
|
||||||
|
gotOutput := test.ReadTempYamlFile(filename)
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
toast: leave
|
||||||
|
tell: 1
|
||||||
|
tasty.taco: cool
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, gotOutput)
|
||||||
|
test.AssertResult(t, os.FileMode(int(0666)), info.Mode())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeAllowEmptyTargetCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge ../examples/empty.yaml ../examples/data1.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeAllowEmptyMergeCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge ../examples/data1.yaml ../examples/empty.yaml")
|
||||||
|
expectedOutput := `a: simple # just the best
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
20
cmd/new.go
20
cmd/new.go
@@ -1,8 +1,9 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||||
|
errors "github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func createNewCmd() *cobra.Command {
|
func createNewCmd() *cobra.Command {
|
||||||
@@ -27,11 +28,19 @@ Note that you can give a create script to perform more sophisticated yaml. This
|
|||||||
}
|
}
|
||||||
cmdNew.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for creating yaml")
|
cmdNew.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for creating yaml")
|
||||||
cmdNew.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
cmdNew.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||||
|
cmdNew.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||||
|
cmdNew.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||||
|
cmdNew.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||||
return cmdNew
|
return cmdNew
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProperty(cmd *cobra.Command, args []string) error {
|
func newProperty(cmd *cobra.Command, args []string) error {
|
||||||
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, "Must provide <path_to_update> <value>")
|
var badArgsMessage = "Must provide <path_to_update> <value>"
|
||||||
|
if len(args) != 2 {
|
||||||
|
return errors.New(badArgsMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, badArgsMessage)
|
||||||
if updateCommandsError != nil {
|
if updateCommandsError != nil {
|
||||||
return updateCommandsError
|
return updateCommandsError
|
||||||
}
|
}
|
||||||
@@ -46,9 +55,6 @@ func newProperty(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var encoder = yaml.NewEncoder(cmd.OutOrStdout())
|
var encoder = yqlib.NewYamlEncoder(cmd.OutOrStdout(), indent, colorsEnabled)
|
||||||
encoder.SetIndent(2)
|
return encoder.Encode(&newNode)
|
||||||
errorEncoding := encoder.Encode(&newNode)
|
|
||||||
encoder.Close()
|
|
||||||
return errorEncoding
|
|
||||||
}
|
}
|
||||||
|
|||||||
101
cmd/new_test.go
Normal file
101
cmd/new_test.go
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c 3")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewAnchorCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c 3 --anchorName=fred")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: &fred 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewAliasCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c foo --makeAlias")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: *foo
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewArrayCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b[0] 3")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
- 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewCmd_Error(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to missing arg")
|
||||||
|
}
|
||||||
|
expectedOutput := `Must provide <path_to_update> <value>`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewWithTaggedStyleCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c cat --tag=!!str --style=tagged")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: !!str cat
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewWithDoubleQuotedStyleCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c cat --style=double")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: "cat"
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewWithSingleQuotedStyleCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "new b.c cat --style=single")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 'cat'
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
189
cmd/prefix_test.go
Normal file
189
cmd/prefix_test.go
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPrefixCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `d:
|
||||||
|
b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixCmdArray(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s [+].d.[+]", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `- d:
|
||||||
|
- b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixCmd_MultiLayer(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d.e.f", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `d:
|
||||||
|
e:
|
||||||
|
f:
|
||||||
|
b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixMultiCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
apples: great
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
d:
|
||||||
|
apples: great
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
func TestPrefixInvalidDocumentIndexCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -df d", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to invalid path")
|
||||||
|
}
|
||||||
|
expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixBadDocumentIndexCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to invalid path")
|
||||||
|
}
|
||||||
|
expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
func TestPrefixMultiAllCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
apples: great
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d * d", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `d:
|
||||||
|
b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
d:
|
||||||
|
apples: great`
|
||||||
|
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixCmd_Error(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "prefix")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to missing arg")
|
||||||
|
}
|
||||||
|
expectedOutput := `Must provide <filename> <prefixed_path>`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixCmd_ErrorUnreadableFile(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "prefix fake-unknown a.b")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to unknown file")
|
||||||
|
}
|
||||||
|
var expectedOutput string
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||||
|
} else {
|
||||||
|
expectedOutput = `open fake-unknown: no such file or directory`
|
||||||
|
}
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixCmd_Inplace(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("prefix -i %s d", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
gotOutput := test.ReadTempYamlFile(filename)
|
||||||
|
expectedOutput := `d:
|
||||||
|
b:
|
||||||
|
c: 3`
|
||||||
|
test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||||
|
}
|
||||||
18
cmd/read.go
18
cmd/read.go
@@ -26,7 +26,12 @@ yq r -- things.yaml '--key-starting-with-dashes.blah'
|
|||||||
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
cmdRead.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
cmdRead.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
||||||
cmdRead.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
cmdRead.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&printLength, "length", "l", false, "print length of results")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&collectIntoArray, "collect", "c", false, "collect results into array")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&unwrapScalar, "unwrapScalar", "", true, "unwrap scalar, print the value with no quotes, colors or comments")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&stripComments, "stripComments", "", false, "print yaml without any comments")
|
||||||
cmdRead.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
cmdRead.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&exitStatus, "exitStatus", "e", false, "set exit status if no matches are found")
|
||||||
return cmdRead
|
return cmdRead
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +51,16 @@ func readProperty(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
matchingNodes, errorReadingStream := readYamlFile(args[0], path, updateAll, docIndexInt)
|
matchingNodes, errorReadingStream := readYamlFile(args[0], path, updateAll, docIndexInt)
|
||||||
|
|
||||||
if errorReadingStream != nil {
|
if exitStatus && len(matchingNodes) == 0 {
|
||||||
return errorReadingStream
|
cmd.SilenceUsage = true
|
||||||
|
return errors.New("No matches found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return printResults(matchingNodes, cmd.OutOrStdout())
|
if errorReadingStream != nil {
|
||||||
|
cmd.SilenceUsage = true
|
||||||
|
return errorReadingStream
|
||||||
|
}
|
||||||
|
out := cmd.OutOrStdout()
|
||||||
|
|
||||||
|
return printResults(matchingNodes, out)
|
||||||
}
|
}
|
||||||
|
|||||||
1381
cmd/read_test.go
Normal file
1381
cmd/read_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@ func New() *cobra.Command {
|
|||||||
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print")
|
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print")
|
||||||
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
||||||
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
||||||
|
rootCmd.PersistentFlags().BoolVarP(&colorsEnabled, "colors", "C", false, "print with colors")
|
||||||
|
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
createReadCmd(),
|
createReadCmd(),
|
||||||
@@ -53,8 +54,7 @@ func New() *cobra.Command {
|
|||||||
createDeleteCmd(),
|
createDeleteCmd(),
|
||||||
createNewCmd(),
|
createNewCmd(),
|
||||||
createMergeCmd(),
|
createMergeCmd(),
|
||||||
|
createBashCompletionCmd(rootCmd),
|
||||||
)
|
)
|
||||||
rootCmd.SetOutput(os.Stdout)
|
|
||||||
|
|
||||||
return rootCmd
|
return rootCmd
|
||||||
}
|
}
|
||||||
|
|||||||
57
cmd/shell_completion.go
Normal file
57
cmd/shell_completion.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var shellVariant = "bash"
|
||||||
|
|
||||||
|
func createBashCompletionCmd(rootCmd *cobra.Command) *cobra.Command {
|
||||||
|
var completionCmd = &cobra.Command{
|
||||||
|
Use: "shell-completion",
|
||||||
|
Short: "Generates shell completion scripts",
|
||||||
|
Long: `To load completion for:
|
||||||
|
bash:
|
||||||
|
Run
|
||||||
|
. <(yq shell-completion)
|
||||||
|
|
||||||
|
To configure your bash shell to load completions for each session add to
|
||||||
|
your bashrc
|
||||||
|
|
||||||
|
# ~/.bashrc or ~/.profile
|
||||||
|
. <(yq shell-completion)
|
||||||
|
|
||||||
|
zsh:
|
||||||
|
The generated completion script should be put somewhere in your $fpath named _yq
|
||||||
|
|
||||||
|
powershell:
|
||||||
|
Users need PowerShell version 5.0 or above, which comes with Windows 10 and
|
||||||
|
can be downloaded separately for Windows 7 or 8.1. They can then write the
|
||||||
|
completions to a file and source this file from their PowerShell profile,
|
||||||
|
which is referenced by the $Profile environment variable.
|
||||||
|
|
||||||
|
fish:
|
||||||
|
Save the output to a fish file and add it to your completions directory.
|
||||||
|
|
||||||
|
`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
switch shellVariant {
|
||||||
|
case "bash", "":
|
||||||
|
return rootCmd.GenBashCompletion(os.Stdout)
|
||||||
|
case "zsh":
|
||||||
|
return rootCmd.GenZshCompletion(os.Stdout)
|
||||||
|
case "fish":
|
||||||
|
return rootCmd.GenFishCompletion(os.Stdout, true)
|
||||||
|
case "powershell":
|
||||||
|
return rootCmd.GenPowerShellCompletion(os.Stdout)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unknown variant %v", shellVariant)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
completionCmd.PersistentFlags().StringVarP(&shellVariant, "variation", "V", "", "shell variation: bash (default), zsh, fish, powershell")
|
||||||
|
return completionCmd
|
||||||
|
}
|
||||||
202
cmd/utils.go
202
cmd/utils.go
@@ -77,24 +77,59 @@ func appendDocument(originalMatchingNodes []*yqlib.NodeContext, dataBucket yaml.
|
|||||||
return append(originalMatchingNodes, matchingNodes...), nil
|
return append(originalMatchingNodes, matchingNodes...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printValue(node *yaml.Node, writer io.Writer) error {
|
func lengthOf(node *yaml.Node) int {
|
||||||
if node.Kind == yaml.ScalarNode {
|
kindToCheck := node.Kind
|
||||||
_, errorWriting := writer.Write([]byte(node.Value + "\n"))
|
if node.Kind == yaml.DocumentNode && len(node.Content) == 1 {
|
||||||
return errorWriting
|
log.Debugf("length of document node, calculating length of child")
|
||||||
|
kindToCheck = node.Content[0].Kind
|
||||||
}
|
}
|
||||||
return printNode(node, writer)
|
switch kindToCheck {
|
||||||
|
case yaml.ScalarNode:
|
||||||
|
return len(node.Value)
|
||||||
|
case yaml.MappingNode:
|
||||||
|
return len(node.Content) / 2
|
||||||
|
default:
|
||||||
|
return len(node.Content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transforms node before printing, if required
|
||||||
|
func transformNode(node *yaml.Node) *yaml.Node {
|
||||||
|
if printLength {
|
||||||
|
return &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", lengthOf(node))}
|
||||||
|
}
|
||||||
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
func printNode(node *yaml.Node, writer io.Writer) error {
|
func printNode(node *yaml.Node, writer io.Writer) error {
|
||||||
var encoder yqlib.Encoder
|
var encoder yqlib.Encoder
|
||||||
|
if node.Kind == yaml.ScalarNode && unwrapScalar && !outputToJSON {
|
||||||
|
return writeString(writer, node.Value+"\n")
|
||||||
|
}
|
||||||
if outputToJSON {
|
if outputToJSON {
|
||||||
encoder = yqlib.NewJsonEncoder(writer, prettyPrint, indent)
|
encoder = yqlib.NewJsonEncoder(writer, prettyPrint, indent)
|
||||||
} else {
|
} else {
|
||||||
encoder = yqlib.NewYamlEncoder(writer, indent)
|
encoder = yqlib.NewYamlEncoder(writer, indent, colorsEnabled)
|
||||||
}
|
}
|
||||||
return encoder.Encode(node)
|
return encoder.Encode(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeComments(matchingNodes []*yqlib.NodeContext) {
|
||||||
|
for _, nodeContext := range matchingNodes {
|
||||||
|
removeCommentOfNode(nodeContext.Node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeCommentOfNode(node *yaml.Node) {
|
||||||
|
node.HeadComment = ""
|
||||||
|
node.LineComment = ""
|
||||||
|
node.FootComment = ""
|
||||||
|
|
||||||
|
for _, child := range node.Content {
|
||||||
|
removeCommentOfNode(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setStyle(matchingNodes []*yqlib.NodeContext, style yaml.Style) {
|
func setStyle(matchingNodes []*yqlib.NodeContext, style yaml.Style) {
|
||||||
for _, nodeContext := range matchingNodes {
|
for _, nodeContext := range matchingNodes {
|
||||||
updateStyleOfNode(nodeContext.Node, style)
|
updateStyleOfNode(nodeContext.Node, style)
|
||||||
@@ -114,25 +149,91 @@ func writeString(writer io.Writer, txt string) error {
|
|||||||
return errorWriting
|
return errorWriting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setIfNotThere(node *yaml.Node, key string, value *yaml.Node) {
|
||||||
|
for index := 0; index < len(node.Content); index = index + 2 {
|
||||||
|
keyNode := node.Content[index]
|
||||||
|
if keyNode.Value == key {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// need to add it to the map
|
||||||
|
mapEntryKey := yaml.Node{Value: key, Kind: yaml.ScalarNode}
|
||||||
|
node.Content = append(node.Content, &mapEntryKey)
|
||||||
|
node.Content = append(node.Content, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyAlias(node *yaml.Node, alias *yaml.Node) {
|
||||||
|
for index := 0; index < len(alias.Content); index = index + 2 {
|
||||||
|
keyNode := alias.Content[index]
|
||||||
|
log.Debugf("applying alias key %v", keyNode.Value)
|
||||||
|
valueNode := alias.Content[index+1]
|
||||||
|
setIfNotThere(node, keyNode.Value, valueNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func explodeNode(node *yaml.Node) error {
|
||||||
|
node.Anchor = ""
|
||||||
|
switch node.Kind {
|
||||||
|
case yaml.SequenceNode, yaml.DocumentNode:
|
||||||
|
for index, contentNode := range node.Content {
|
||||||
|
log.Debugf("exploding index %v", index)
|
||||||
|
errorInContent := explodeNode(contentNode)
|
||||||
|
if errorInContent != nil {
|
||||||
|
return errorInContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case yaml.AliasNode:
|
||||||
|
log.Debugf("its an alias!")
|
||||||
|
node.Kind = node.Alias.Kind
|
||||||
|
node.Style = node.Alias.Style
|
||||||
|
node.Tag = node.Alias.Tag
|
||||||
|
node.Content = node.Alias.Content
|
||||||
|
node.Value = node.Alias.Value
|
||||||
|
node.Alias = nil
|
||||||
|
return nil
|
||||||
|
case yaml.MappingNode:
|
||||||
|
for index := 0; index < len(node.Content); index = index + 2 {
|
||||||
|
keyNode := node.Content[index]
|
||||||
|
valueNode := node.Content[index+1]
|
||||||
|
log.Debugf("traversing %v", keyNode.Value)
|
||||||
|
if keyNode.Value != "<<" {
|
||||||
|
errorInContent := explodeNode(valueNode)
|
||||||
|
if errorInContent != nil {
|
||||||
|
return errorInContent
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if valueNode.Kind == yaml.SequenceNode {
|
||||||
|
log.Debugf("an alias merge list!")
|
||||||
|
for index := len(valueNode.Content) - 1; index >= 0; index = index - 1 {
|
||||||
|
aliasNode := valueNode.Content[index]
|
||||||
|
applyAlias(node, aliasNode.Alias)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("an alias merge!")
|
||||||
|
applyAlias(node, valueNode.Alias)
|
||||||
|
}
|
||||||
|
node.Content = append(node.Content[:index], node.Content[index+2:]...)
|
||||||
|
//replay that index, since the array is shorter now.
|
||||||
|
index = index - 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func explode(matchingNodes []*yqlib.NodeContext) error {
|
func explode(matchingNodes []*yqlib.NodeContext) error {
|
||||||
log.Debug("exploding nodes")
|
log.Debug("exploding nodes")
|
||||||
for _, nodeContext := range matchingNodes {
|
for _, nodeContext := range matchingNodes {
|
||||||
var targetNode = yaml.Node{Kind: nodeContext.Node.Kind}
|
log.Debugf("exploding %v", nodeContext.Head)
|
||||||
explodedNodes, errorRetrieving := lib.Get(nodeContext.Node, "**", true)
|
errorExplodingNode := explodeNode(nodeContext.Node)
|
||||||
if errorRetrieving != nil {
|
if errorExplodingNode != nil {
|
||||||
return errorRetrieving
|
return errorExplodingNode
|
||||||
}
|
}
|
||||||
for _, matchingNode := range explodedNodes {
|
|
||||||
mergePath := lib.MergePathStackToString(matchingNode.PathStack, appendFlag)
|
|
||||||
updateCommand := yqlib.UpdateCommand{Command: "update", Path: mergePath, Value: matchingNode.Node, Overwrite: overwriteFlag}
|
|
||||||
errorUpdating := lib.Update(&targetNode, updateCommand, true)
|
|
||||||
if errorUpdating != nil {
|
|
||||||
return errorUpdating
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nodeContext.Node = &targetNode
|
|
||||||
}
|
}
|
||||||
log.Debug("done exploding nodes")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +242,10 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
|||||||
setStyle(matchingNodes, 0)
|
setStyle(matchingNodes, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if stripComments {
|
||||||
|
removeComments(matchingNodes)
|
||||||
|
}
|
||||||
|
|
||||||
//always explode anchors when printing json
|
//always explode anchors when printing json
|
||||||
if explodeAnchors || outputToJSON {
|
if explodeAnchors || outputToJSON {
|
||||||
errorExploding := explode(matchingNodes)
|
errorExploding := explode(matchingNodes)
|
||||||
@@ -160,6 +265,9 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var errorWriting error
|
var errorWriting error
|
||||||
|
|
||||||
|
var arrayCollection = yaml.Node{Kind: yaml.SequenceNode}
|
||||||
|
|
||||||
for _, mappedDoc := range matchingNodes {
|
for _, mappedDoc := range matchingNodes {
|
||||||
switch printMode {
|
switch printMode {
|
||||||
case "p":
|
case "p":
|
||||||
@@ -172,17 +280,27 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
|||||||
var parentNode = yaml.Node{Kind: yaml.MappingNode}
|
var parentNode = yaml.Node{Kind: yaml.MappingNode}
|
||||||
parentNode.Content = make([]*yaml.Node, 2)
|
parentNode.Content = make([]*yaml.Node, 2)
|
||||||
parentNode.Content[0] = &yaml.Node{Kind: yaml.ScalarNode, Value: lib.PathStackToString(mappedDoc.PathStack)}
|
parentNode.Content[0] = &yaml.Node{Kind: yaml.ScalarNode, Value: lib.PathStackToString(mappedDoc.PathStack)}
|
||||||
parentNode.Content[1] = mappedDoc.Node
|
parentNode.Content[1] = transformNode(mappedDoc.Node)
|
||||||
if err := printValue(&parentNode, bufferedWriter); err != nil {
|
if collectIntoArray {
|
||||||
|
arrayCollection.Content = append(arrayCollection.Content, &parentNode)
|
||||||
|
} else if err := printNode(&parentNode, bufferedWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := printValue(mappedDoc.Node, bufferedWriter); err != nil {
|
if collectIntoArray {
|
||||||
|
arrayCollection.Content = append(arrayCollection.Content, mappedDoc.Node)
|
||||||
|
} else if err := printNode(transformNode(mappedDoc.Node), bufferedWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if collectIntoArray {
|
||||||
|
if err := printNode(transformNode(&arrayCollection), bufferedWriter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,11 +417,22 @@ func updateDoc(inputFile string, updateCommands []yqlib.UpdateCommand, writer io
|
|||||||
func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn) error {
|
func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn) error {
|
||||||
var destination io.Writer
|
var destination io.Writer
|
||||||
var destinationName string
|
var destinationName string
|
||||||
|
var completedSuccessfully = false
|
||||||
if writeInplace {
|
if writeInplace {
|
||||||
info, err := os.Stat(inputFile)
|
info, err := os.Stat(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// mkdir temp dir as some docker images does not have temp dir
|
||||||
|
_, err = os.Stat(os.TempDir())
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(os.TempDir(), 0700)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
tempFile, err := ioutil.TempFile("", "temp")
|
tempFile, err := ioutil.TempFile("", "temp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -316,7 +445,9 @@ func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn)
|
|||||||
destination = tempFile
|
destination = tempFile
|
||||||
defer func() {
|
defer func() {
|
||||||
safelyCloseFile(tempFile)
|
safelyCloseFile(tempFile)
|
||||||
safelyRenameFile(tempFile.Name(), inputFile)
|
if completedSuccessfully {
|
||||||
|
safelyRenameFile(tempFile.Name(), inputFile)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
destination = stdOut
|
destination = stdOut
|
||||||
@@ -332,9 +463,12 @@ func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn)
|
|||||||
if outputToJSON {
|
if outputToJSON {
|
||||||
encoder = yqlib.NewJsonEncoder(bufferedWriter, prettyPrint, indent)
|
encoder = yqlib.NewJsonEncoder(bufferedWriter, prettyPrint, indent)
|
||||||
} else {
|
} else {
|
||||||
encoder = yqlib.NewYamlEncoder(bufferedWriter, indent)
|
encoder = yqlib.NewYamlEncoder(bufferedWriter, indent, colorsEnabled)
|
||||||
}
|
}
|
||||||
return readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
|
||||||
|
var errorProcessing = readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||||
|
completedSuccessfully = errorProcessing == nil
|
||||||
|
return errorProcessing
|
||||||
}
|
}
|
||||||
|
|
||||||
type updateCommandParsed struct {
|
type updateCommandParsed struct {
|
||||||
@@ -372,15 +506,21 @@ func readUpdateCommands(args []string, expectedArgs int, badArgsMessage string)
|
|||||||
log.Debug("args %v", args[expectedArgs-2])
|
log.Debug("args %v", args[expectedArgs-2])
|
||||||
updateCommands = make([]yqlib.UpdateCommand, 1)
|
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||||
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value.Content[0], Overwrite: true}
|
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value.Content[0], Overwrite: true}
|
||||||
|
} else if len(args) == expectedArgs {
|
||||||
} else if len(args) < expectedArgs {
|
|
||||||
return nil, errors.New(badArgsMessage)
|
|
||||||
} else {
|
|
||||||
updateCommands = make([]yqlib.UpdateCommand, 1)
|
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||||
log.Debug("args %v", args)
|
log.Debug("args %v", args)
|
||||||
log.Debug("path %v", args[expectedArgs-2])
|
log.Debug("path %v", args[expectedArgs-2])
|
||||||
log.Debug("Value %v", args[expectedArgs-1])
|
log.Debug("Value %v", args[expectedArgs-1])
|
||||||
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: valueParser.Parse(args[expectedArgs-1], customTag), Overwrite: true}
|
value := valueParser.Parse(args[expectedArgs-1], customTag, customStyle, anchorName, makeAlias)
|
||||||
|
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value, Overwrite: true, DontUpdateComments: true}
|
||||||
|
} else if len(args) == expectedArgs-1 {
|
||||||
|
// don't update the value
|
||||||
|
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||||
|
log.Debug("args %v", args)
|
||||||
|
log.Debug("path %v", args[expectedArgs-2])
|
||||||
|
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: valueParser.Parse("", customTag, customStyle, anchorName, makeAlias), Overwrite: true, DontUpdateNodeValue: true}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(badArgsMessage)
|
||||||
}
|
}
|
||||||
return updateCommands, nil
|
return updateCommands, nil
|
||||||
}
|
}
|
||||||
|
|||||||
31
cmd/validate_test.go
Normal file
31
cmd/validate_test.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidateCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "validate ../examples/sample.yaml b.c")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateBadDataCmd(t *testing.T) {
|
||||||
|
content := `[!Whatever]`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("validate %s", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail")
|
||||||
|
}
|
||||||
|
expectedOutput := `yaml: line 1: did not find expected ',' or ']'`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ var (
|
|||||||
GitDescribe string
|
GitDescribe string
|
||||||
|
|
||||||
// Version is main version number that is being run at the moment.
|
// Version is main version number that is being run at the moment.
|
||||||
Version = "3.1.2"
|
Version = "3.3.2"
|
||||||
|
|
||||||
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
|
// 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
|
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ format is list of update commands (update or delete) like so:
|
|||||||
cmdWrite.PersistentFlags().StringVarP(&sourceYamlFile, "from", "f", "", "yaml file for updating yaml (as-is)")
|
cmdWrite.PersistentFlags().StringVarP(&sourceYamlFile, "from", "f", "", "yaml file for updating yaml (as-is)")
|
||||||
cmdWrite.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
cmdWrite.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||||
cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
|
cmdWrite.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||||
|
cmdWrite.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||||
|
cmdWrite.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||||
return cmdWrite
|
return cmdWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
611
cmd/write_test.go
Normal file
611
cmd/write_test.go
Normal file
@@ -0,0 +1,611 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/v3/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWriteCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 7
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteKeepCommentsCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3 # comment
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 7 # comment
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteWithTaggedStyleCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: dog
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --tag=!!str --style=tagged", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: !!str cat
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteWithDoubleQuotedStyleCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: dog
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=double", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: "cat"
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteUpdateStyleOnlyCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: dog
|
||||||
|
d: things
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.* --style=single", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 'dog'
|
||||||
|
d: 'things'
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteUpdateTagOnlyCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: true
|
||||||
|
d: false
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.* --tag=!!str", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: "true"
|
||||||
|
d: "false"
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteWithSingleQuotedStyleCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: dog
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=single", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 'cat'
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteWithLiteralStyleCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: dog
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=literal", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: |-
|
||||||
|
cat
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteWithFoldedStyleCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: dog
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=folded", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: >-
|
||||||
|
cat
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteEmptyMultiDocCmd(t *testing.T) {
|
||||||
|
content := `# this is empty
|
||||||
|
---
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s c 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `c: 7
|
||||||
|
|
||||||
|
# this is empty
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteSurroundingEmptyMultiDocCmd(t *testing.T) {
|
||||||
|
content := `---
|
||||||
|
# empty
|
||||||
|
---
|
||||||
|
cat: frog
|
||||||
|
---
|
||||||
|
|
||||||
|
# empty
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s -d1 c 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `
|
||||||
|
|
||||||
|
# empty
|
||||||
|
---
|
||||||
|
cat: frog
|
||||||
|
c: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
# empty
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteFromFileCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
source := `kittens: are cute # sure are!`
|
||||||
|
fromFilename := test.WriteTempYamlFile(source)
|
||||||
|
defer test.RemoveTempYamlFile(fromFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c -f %s", filename, fromFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c:
|
||||||
|
kittens: are cute # sure are!
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteEmptyCmd(t *testing.T) {
|
||||||
|
content := ``
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 7
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteAutoCreateCmd(t *testing.T) {
|
||||||
|
content := `applications:
|
||||||
|
- name: app
|
||||||
|
env:`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s applications[0].env.hello world", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `applications:
|
||||||
|
- name: app
|
||||||
|
env:
|
||||||
|
hello: world
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmdScript(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
updateScript := `- command: update
|
||||||
|
path: b.c
|
||||||
|
value: 7`
|
||||||
|
scriptFilename := test.WriteTempYamlFile(updateScript)
|
||||||
|
defer test.RemoveTempYamlFile(scriptFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write --script %s %s", scriptFilename, filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 7
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmdEmptyScript(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
updateScript := ``
|
||||||
|
scriptFilename := test.WriteTempYamlFile(updateScript)
|
||||||
|
defer test.RemoveTempYamlFile(scriptFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write --script %s %s", scriptFilename, filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteMultiCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
apples: great
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
apples: ok
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
func TestWriteInvalidDocumentIndexCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s -df apples ok", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to invalid path")
|
||||||
|
}
|
||||||
|
expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteBadDocumentIndexCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to invalid path")
|
||||||
|
}
|
||||||
|
expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
func TestWriteMultiAllCmd(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
---
|
||||||
|
apples: great
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s -d * apples ok", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 3
|
||||||
|
apples: ok
|
||||||
|
---
|
||||||
|
apples: ok`
|
||||||
|
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_EmptyArray(t *testing.T) {
|
||||||
|
content := `b: 3`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s a []", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b: 3
|
||||||
|
a: []
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_Error(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "write")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to missing arg")
|
||||||
|
}
|
||||||
|
expectedOutput := `Must provide <filename> <path_to_update> <value>`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_ErrorUnreadableFile(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "write fake-unknown a.b 3")
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail due to unknown file")
|
||||||
|
}
|
||||||
|
var expectedOutput string
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||||
|
} else {
|
||||||
|
expectedOutput = `open fake-unknown: no such file or directory`
|
||||||
|
}
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_Inplace(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write -i %s b.c 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
gotOutput := test.ReadTempYamlFile(filename)
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: 7`
|
||||||
|
test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_InplaceError(t *testing.T) {
|
||||||
|
content := `b: cat
|
||||||
|
c: 3
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write -i %s b.c 7", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected Error to occur!")
|
||||||
|
}
|
||||||
|
gotOutput := test.ReadTempYamlFile(filename)
|
||||||
|
test.AssertResult(t, content, gotOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_Append(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
- foo
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
- foo
|
||||||
|
- 7
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_AppendInline(t *testing.T) {
|
||||||
|
content := `b: [foo]`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b: [foo, 7]
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_AppendInlinePretty(t *testing.T) {
|
||||||
|
content := `b: [foo]`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s -P b[+] 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
- foo
|
||||||
|
- 7
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_AppendEmptyArray(t *testing.T) {
|
||||||
|
content := `a: 2
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] v", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: 2
|
||||||
|
b:
|
||||||
|
- v
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_SplatArray(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
- c: thing
|
||||||
|
- c: another thing
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b[*].c new", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
- c: new
|
||||||
|
- c: new
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_SplatMap(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: thing
|
||||||
|
d: another thing
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.* new", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: new
|
||||||
|
d: new
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_SplatMapEmpty(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
c: thing
|
||||||
|
d: another thing
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c.* new", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
c: {}
|
||||||
|
d: another thing
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
40
debian/changelog
vendored
40
debian/changelog
vendored
@@ -1,9 +1,41 @@
|
|||||||
yq (3.1.1) eoan; urgency=medium
|
yq (3.3.2) focal; urgency=medium
|
||||||
|
|
||||||
|
* Bug fix: existStatus bug (#459)
|
||||||
|
* Automatically makes a 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.
|
* Keeps yaml comments and formatting, can specify yaml tags when updating.
|
||||||
* Handles anchors! https://github.com/mikefarah/yq/issues/310, https://github.com/mikefarah/yq/issues/178
|
* Handles anchors
|
||||||
* Can print out matching paths and values when splatting https://github.com/mikefarah/yq/issues/20
|
* 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.
|
* 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
|
* Deep splat (**) to match arbitrary paths
|
||||||
* Update scripts file format has changed to be more powerful
|
* Update scripts file format has changed to be more powerful
|
||||||
* Reading and splatting, matching results are printed once per line
|
* Reading and splatting, matching results are printed once per line
|
||||||
|
|||||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
|||||||
9
|
10
|
||||||
|
|||||||
5
debian/control
vendored
5
debian/control
vendored
@@ -5,9 +5,8 @@ Maintainer: Roberto Mier EscandĂłn <rmescandon@gmail.com>
|
|||||||
Build-Depends: debhelper (>=10),
|
Build-Depends: debhelper (>=10),
|
||||||
dh-golang (>=1.34),
|
dh-golang (>=1.34),
|
||||||
golang-1.13,
|
golang-1.13,
|
||||||
dpkg-dev,
|
|
||||||
rsync
|
rsync
|
||||||
Standards-Version: 3.9.6
|
Standards-Version: 4.1.4
|
||||||
Homepage: https://github.com/mikefarah/yq.git
|
Homepage: https://github.com/mikefarah/yq.git
|
||||||
Vcs-Browser: https://github.com/mikefarah/yq.git
|
Vcs-Browser: https://github.com/mikefarah/yq.git
|
||||||
Vcs-Git: https://github.com/mikefarah/yq.git
|
Vcs-Git: https://github.com/mikefarah/yq.git
|
||||||
@@ -17,7 +16,7 @@ XSBC-Original-Maintainer: Roberto Mier EscandĂłn <rmescandon@gmail.com>
|
|||||||
Package: yq
|
Package: yq
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
Description: a lightweight and portable command-line YAML processor
|
Description: lightweight and portable command-line YAML processor
|
||||||
.
|
.
|
||||||
The aim of the project is to be the
|
The aim of the project is to be the
|
||||||
[jq](https://github.com/stedolan/jq) or sed of yaml files.
|
[jq](https://github.com/stedolan/jq) or sed of yaml files.
|
||||||
|
|||||||
21
debian/copyright
vendored
21
debian/copyright
vendored
@@ -3,5 +3,22 @@ Upstream-Name: yq
|
|||||||
Source: https://github.com/mikefarah/yq.git
|
Source: https://github.com/mikefarah/yq.git
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2017 Mike Farah Ltd. All rights reserved
|
Copyright: 2017 Mike Farah
|
||||||
License: Proprietary
|
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.
|
||||||
4
debian/rules
vendored
4
debian/rules
vendored
@@ -40,7 +40,7 @@ override_dh_auto_build:
|
|||||||
mkdir -p ${SRCDIR}
|
mkdir -p ${SRCDIR}
|
||||||
mkdir -p ${GOBIN}
|
mkdir -p ${GOBIN}
|
||||||
# copy project to local srcdir to build from there
|
# copy project to local srcdir to build from there
|
||||||
rsync -avz --progress --exclude=_build --exclude=debian --exclude=tmp. --exclude=go.mod . $(SRCDIR)
|
rsync -avz --progress --exclude=_build --exclude=debian --exclude=tmp. --exclude=go.mod --exclude=docs . $(SRCDIR)
|
||||||
# build go code
|
# build go code
|
||||||
(cd ${SRCDIR} && go install -buildmode=pie ./...)
|
(cd ${SRCDIR} && go install -buildmode=pie ./...)
|
||||||
|
|
||||||
@@ -48,8 +48,6 @@ override_dh_auto_test:
|
|||||||
(cd ${SRCDIR} && go test -v ./...)
|
(cd ${SRCDIR} && go test -v ./...)
|
||||||
|
|
||||||
override_dh_auto_install:
|
override_dh_auto_install:
|
||||||
mkdir -p ${DESTDIR}/${BINDIR}
|
|
||||||
mkdir -p ${DESTDIR}/${ASSETSDIR}
|
|
||||||
cp ${GOBIN}/yq ${DESTDIR}/${BINDIR}
|
cp ${GOBIN}/yq ${DESTDIR}/${BINDIR}
|
||||||
cp -f ${SRCDIR}/LICENSE ${DESTDIR}/${ASSETSDIR}
|
cp -f ${SRCDIR}/LICENSE ${DESTDIR}/${ASSETSDIR}
|
||||||
chmod a+x ${DESTDIR}/${BINDIR}/yq
|
chmod a+x ${DESTDIR}/${BINDIR}/yq
|
||||||
|
|||||||
3
debian/yq.dirs
vendored
Normal file
3
debian/yq.dirs
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
usr/bin
|
||||||
|
usr/share/yq
|
||||||
|
usr/share/man/man1
|
||||||
4
examples/data1-no-comments.yaml
Normal file
4
examples/data1-no-comments.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
a: simple
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
b:
|
|
||||||
c: things
|
|
||||||
5
examples/simple-anchor-exploded.yaml
Normal file
5
examples/simple-anchor-exploded.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
foo:
|
||||||
|
a: 1
|
||||||
|
|
||||||
|
foobar:
|
||||||
|
a: 1
|
||||||
5
github-action/Dockerfile
Normal file
5
github-action/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
FROM mikefarah/yq:3
|
||||||
|
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
4
github-action/entrypoint.sh
Executable file
4
github-action/entrypoint.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh -l
|
||||||
|
|
||||||
|
echo "$1"
|
||||||
|
eval $1
|
||||||
27
go.mod
27
go.mod
@@ -1,26 +1,17 @@
|
|||||||
module github.com/mikefarah/yq/v3
|
module github.com/mikefarah/yq/v3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cosiner/argv v0.0.1 // indirect
|
github.com/fatih/color v1.9.0
|
||||||
github.com/go-delve/delve v1.4.0 // indirect
|
github.com/goccy/go-yaml v1.8.1
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
|
||||||
github.com/kylelemons/godebug v1.1.0
|
github.com/kylelemons/godebug v1.1.0
|
||||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
github.com/mattn/go-colorable v0.1.7 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/mattn/go-runewidth v0.0.8 // indirect
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/peterh/liner v1.2.0 // indirect
|
|
||||||
github.com/pkg/errors v0.8.1
|
|
||||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
|
||||||
github.com/spf13/cobra v0.0.5
|
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
go.starlark.net v0.0.0-20200203144150-6677ee5c7211 // indirect
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f // indirect
|
||||||
golang.org/x/arch v0.0.0-20191126211547-368ea8f32fff // indirect
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678 // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 // indirect
|
|
||||||
golang.org/x/tools v0.0.0-20191213221258-04c2e8eff935 // indirect
|
|
||||||
gopkg.in/imdario/mergo.v0 v0.3.7 // indirect
|
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.13
|
go 1.15
|
||||||
|
|||||||
224
go.sum
224
go.sum
@@ -1,150 +1,180 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/cosiner/argv v0.0.0-20170225145430-13bacc38a0a5 h1:rIXlvz2IWiupMFlC45cZCXZFvKX/ExBcSLrDy2G0Lp8=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/cosiner/argv v0.0.0-20170225145430-13bacc38a0a5/go.mod h1:p/NrK5tF6ICIly4qwEDsf6VDirFiWWz0FenfYBwJaKQ=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cosiner/argv v0.0.1 h1:2iAFN+sWPktbZ4tvxm33Ei8VY66FPCxdOxpncUGpAXE=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cosiner/argv v0.0.1/go.mod h1:p/NrK5tF6ICIly4qwEDsf6VDirFiWWz0FenfYBwJaKQ=
|
|
||||||
github.com/cpuguy83/go-md2man v1.0.8/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY=
|
|
||||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||||
|
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/go-delve/delve v1.4.0 h1:O+1dw1XBZXqhC6fIPQwGxLlbd2wDRau7NxNhVpw02ag=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-delve/delve v1.4.0/go.mod h1:gQM0ReOJLNAvPuKAXfjHngtE93C2yc/ekTbo7YbAHSo=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/goccy/go-yaml v1.8.1 h1:JuZRFlqLM5cWF6A+waL8AKVuCcqvKOuhJtUQI+L3ez0=
|
||||||
|
github.com/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mattn/go-colorable v0.0.0-20170327083344-ded68f7a9561 h1:isR/L+BIZ+rqODWYR/f526ygrBMGKZYFhaaFRDGvuZ8=
|
|
||||||
github.com/mattn/go-colorable v0.0.0-20170327083344-ded68f7a9561/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
|
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
|
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||||
|
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
|
||||||
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
|
||||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
|
||||||
github.com/mikefarah/yaml v2.1.0+incompatible h1:nu2cqmzk4WlWJNgnevY88faMcdrDzYGcsUjYFxEpB7Y=
|
|
||||||
github.com/mikefarah/yaml/v2 v2.4.0 h1:eYqfooY0BnvKTJxr7+ABJs13n3dg9n347GScDaU2Lww=
|
|
||||||
github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU=
|
|
||||||
github.com/mikefarah/yq v2.4.0+incompatible h1:oBxbWy8R9hI3BIUUxEf0CzikWa2AgnGrGhvGQt5jgjk=
|
|
||||||
github.com/mikefarah/yq/v2 v2.4.1 h1:tajDonaFK6WqitSZExB6fKlWQy/yCkptqxh2AXEe3N4=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b h1:8uaXtUkxiy+T/zdLWuxa/PG4so0TPZDZfafFNNSaptE=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/profile v0.0.0-20170413231811-06b906832ed0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
github.com/sirupsen/logrus v0.0.0-20180523074243-ea8897e79973 h1:3AJZYTzw3gm3TNTt30x0CCKD7GOn2sdd50Hn35fQkGY=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/sirupsen/logrus v0.0.0-20180523074243-ea8897e79973/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.0-20170417170307-b6cb39589372/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/pflag v0.0.0-20170417173400-9e4c21054fa1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
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/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
go.starlark.net v0.0.0-20190702223751-32f345186213 h1:lkYv5AKwvvduv5XWP6szk/bvvgO6aDeUujhZQXIFTes=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.starlark.net v0.0.0-20190702223751-32f345186213/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.starlark.net v0.0.0-20200203144150-6677ee5c7211 h1:Qoe+9POtDT51UBQ8XEnS9QKeHDQzEl2QRh3eok9R4aw=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.starlark.net v0.0.0-20200203144150-6677ee5c7211/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 h1:QlVATYS7JBoZMVaf+cNjb90WD/beKVHnIxFKT4QaHVI=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
|
||||||
golang.org/x/arch v0.0.0-20191126211547-368ea8f32fff h1:k/MrR0lKiCokRu1JUDDAWhWZinfBAOZRzz3LkPOkFMs=
|
|
||||||
golang.org/x/arch v0.0.0-20191126211547-368ea8f32fff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc=
|
||||||
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20191030203535-5e247c9ad0a0 h1:s5lp4ug7qHzUccgyFdjsX7OZDzHXRaePrF3B3vmUiuM=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20191030203535-5e247c9ad0a0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191213221258-04c2e8eff935 h1:kJQZhwFzSwJS2BxboKjdZzWczQOZx8VuH7Y8hhuGUtM=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191213221258-04c2e8eff935/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/imdario/mergo.v0 v0.3.7 h1:QDotlIZtaO/p+Um0ok18HRTpq5i5/SAk/qprsor+9c8=
|
|
||||||
gopkg.in/imdario/mergo.v0 v0.3.7/go.mod h1:9qPP6AGrlC1G2PTNXko614FwGZvorN7MiBU0Eppok+U=
|
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
|
||||||
|
|||||||
61
pkg/yqlib/color_print.go
Normal file
61
pkg/yqlib/color_print.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/goccy/go-yaml/lexer"
|
||||||
|
"github.com/goccy/go-yaml/printer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Thanks @risentveber!
|
||||||
|
|
||||||
|
const escape = "\x1b"
|
||||||
|
|
||||||
|
func format(attr color.Attribute) string {
|
||||||
|
return fmt.Sprintf("%s[%dm", escape, attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ColorizeAndPrint(bytes []byte, writer io.Writer) error {
|
||||||
|
tokens := lexer.Tokenize(string(bytes))
|
||||||
|
var p printer.Printer
|
||||||
|
p.Bool = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiMagenta),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.Number = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiMagenta),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.MapKey = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgCyan),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.Anchor = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiYellow),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.Alias = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiYellow),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.String = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgGreen),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := writer.Write([]byte(p.PrintTokens(tokens) + "\n"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ func NewDataNavigator(NavigationStrategy NavigationStrategy) DataNavigator {
|
|||||||
func (n *navigator) Traverse(value *yaml.Node, path []interface{}) error {
|
func (n *navigator) Traverse(value *yaml.Node, path []interface{}) error {
|
||||||
realValue := value
|
realValue := value
|
||||||
emptyArray := make([]interface{}, 0)
|
emptyArray := make([]interface{}, 0)
|
||||||
|
log.Debugf("Traversing path %v", pathStackToString(path))
|
||||||
if realValue.Kind == yaml.DocumentNode {
|
if realValue.Kind == yaml.DocumentNode {
|
||||||
log.Debugf("its a document! returning the first child")
|
log.Debugf("its a document! returning the first child")
|
||||||
return n.doTraverse(value.Content[0], "", path, emptyArray)
|
return n.doTraverse(value.Content[0], "", path, emptyArray)
|
||||||
@@ -68,6 +69,16 @@ func (n *navigator) getOrReplace(original *yaml.Node, expectedKind yaml.Kind) *y
|
|||||||
|
|
||||||
func (n *navigator) recurse(value *yaml.Node, head interface{}, tail []interface{}, pathStack []interface{}) error {
|
func (n *navigator) recurse(value *yaml.Node, head interface{}, tail []interface{}, pathStack []interface{}) error {
|
||||||
log.Debug("recursing, processing %v, pathStack %v", head, pathStackToString(pathStack))
|
log.Debug("recursing, processing %v, pathStack %v", head, pathStackToString(pathStack))
|
||||||
|
|
||||||
|
nodeContext := NewNodeContext(value, head, tail, pathStack)
|
||||||
|
|
||||||
|
if head == "**" && !n.navigationStrategy.ShouldOnlyDeeplyVisitLeaves(nodeContext) {
|
||||||
|
errorVisitingDeeply := n.navigationStrategy.Visit(nodeContext)
|
||||||
|
if errorVisitingDeeply != nil {
|
||||||
|
return errorVisitingDeeply
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch value.Kind {
|
switch value.Kind {
|
||||||
case yaml.MappingNode:
|
case yaml.MappingNode:
|
||||||
log.Debug("its a map with %v entries", len(value.Content)/2)
|
log.Debug("its a map with %v entries", len(value.Content)/2)
|
||||||
@@ -85,20 +96,20 @@ func (n *navigator) recurse(value *yaml.Node, head interface{}, tail []interface
|
|||||||
if head == "+" {
|
if head == "+" {
|
||||||
return n.appendArray(value, head, tail, pathStack)
|
return n.appendArray(value, head, tail, pathStack)
|
||||||
} else if len(value.Content) == 0 && head == "**" {
|
} else if len(value.Content) == 0 && head == "**" {
|
||||||
return n.navigationStrategy.Visit(NewNodeContext(value, head, tail, pathStack))
|
return n.navigationStrategy.Visit(nodeContext)
|
||||||
}
|
}
|
||||||
return n.splatArray(value, head, tail, pathStack)
|
return n.splatArray(value, head, tail, pathStack)
|
||||||
}
|
}
|
||||||
case yaml.AliasNode:
|
case yaml.AliasNode:
|
||||||
log.Debug("its an alias!")
|
log.Debug("its an alias!")
|
||||||
DebugNode(value.Alias)
|
DebugNode(value.Alias)
|
||||||
if n.navigationStrategy.FollowAlias(NewNodeContext(value, head, tail, pathStack)) {
|
if n.navigationStrategy.FollowAlias(nodeContext) {
|
||||||
log.Debug("following the alias")
|
log.Debug("following the alias")
|
||||||
return n.recurse(value.Alias, head, tail, pathStack)
|
return n.recurse(value.Alias, head, tail, pathStack)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return n.navigationStrategy.Visit(NewNodeContext(value, head, tail, pathStack))
|
return n.navigationStrategy.Visit(nodeContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,11 +271,22 @@ func (n *navigator) appendArray(value *yaml.Node, head interface{}, tail []inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *navigator) recurseArray(value *yaml.Node, index int64, head interface{}, tail []interface{}, pathStack []interface{}) error {
|
func (n *navigator) recurseArray(value *yaml.Node, index int64, head interface{}, tail []interface{}, pathStack []interface{}) error {
|
||||||
for int64(len(value.Content)) <= index {
|
var contentLength = int64(len(value.Content))
|
||||||
|
for contentLength <= index {
|
||||||
value.Content = append(value.Content, &yaml.Node{Kind: guessKind(head, tail, 0)})
|
value.Content = append(value.Content, &yaml.Node{Kind: guessKind(head, tail, 0)})
|
||||||
|
contentLength = int64(len(value.Content))
|
||||||
|
}
|
||||||
|
var indexToUse = index
|
||||||
|
|
||||||
|
if indexToUse < 0 {
|
||||||
|
indexToUse = contentLength + indexToUse
|
||||||
}
|
}
|
||||||
|
|
||||||
value.Content[index] = n.getOrReplace(value.Content[index], guessKind(head, tail, value.Content[index].Kind))
|
if indexToUse < 0 {
|
||||||
|
return fmt.Errorf("Index [%v] out of range, array size is %v", index, contentLength)
|
||||||
|
}
|
||||||
|
|
||||||
return n.doTraverse(value.Content[index], head, tail, append(pathStack, index))
|
value.Content[indexToUse] = n.getOrReplace(value.Content[indexToUse], guessKind(head, tail, value.Content[indexToUse].Kind))
|
||||||
|
|
||||||
|
return n.doTraverse(value.Content[indexToUse], head, tail, append(pathStack, index))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,12 @@ func DeleteNavigationStrategy(pathElementToDelete interface{}) NavigationStrateg
|
|||||||
followAlias: func(nodeContext NodeContext) bool {
|
followAlias: func(nodeContext NodeContext) bool {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
autoCreateMap: func(nodeContext NodeContext) bool {
|
shouldOnlyDeeplyVisitLeaves: func(nodeContext NodeContext) bool {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
shouldDeeplyTraverse: func(nodeContext NodeContext) bool {
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
visit: func(nodeContext NodeContext) error {
|
visit: func(nodeContext NodeContext) error {
|
||||||
node := nodeContext.Node
|
node := nodeContext.Node
|
||||||
log.Debug("need to find and delete %v in here", pathElementToDelete)
|
log.Debug("need to find and delete %v in here (%v)", pathElementToDelete, pathStackToString(nodeContext.PathStack))
|
||||||
DebugNode(node)
|
DebugNode(node)
|
||||||
if node.Kind == yaml.SequenceNode {
|
if node.Kind == yaml.SequenceNode {
|
||||||
newContent := deleteFromArray(parser, node.Content, nodeContext.PathStack, pathElementToDelete)
|
newContent := deleteFromArray(parser, node.Content, nodeContext.PathStack, pathElementToDelete)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
@@ -12,20 +13,45 @@ type Encoder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type yamlEncoder struct {
|
type yamlEncoder struct {
|
||||||
encoder *yaml.Encoder
|
destination io.Writer
|
||||||
|
indent int
|
||||||
|
colorise bool
|
||||||
|
firstDoc bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYamlEncoder(destination io.Writer, indent int) Encoder {
|
func NewYamlEncoder(destination io.Writer, indent int, colorise bool) Encoder {
|
||||||
var encoder = yaml.NewEncoder(destination)
|
|
||||||
if indent < 0 {
|
if indent < 0 {
|
||||||
indent = 0
|
indent = 0
|
||||||
}
|
}
|
||||||
encoder.SetIndent(indent)
|
return &yamlEncoder{destination, indent, colorise, true}
|
||||||
return &yamlEncoder{encoder}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
|
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
|
||||||
return ye.encoder.Encode(node)
|
|
||||||
|
destination := ye.destination
|
||||||
|
tempBuffer := bytes.NewBuffer(nil)
|
||||||
|
if ye.colorise {
|
||||||
|
destination = tempBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
var encoder = yaml.NewEncoder(destination)
|
||||||
|
|
||||||
|
encoder.SetIndent(ye.indent)
|
||||||
|
// TODO: work out if the first doc had a separator or not.
|
||||||
|
if ye.firstDoc {
|
||||||
|
ye.firstDoc = false
|
||||||
|
} else if _, err := destination.Write([]byte("---\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := encoder.Encode(node); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ye.colorise {
|
||||||
|
return ColorizeAndPrint(tempBuffer.Bytes(), ye.destination)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonEncoder struct {
|
type jsonEncoder struct {
|
||||||
|
|||||||
@@ -4,12 +4,6 @@ func FilterMatchingNodesNavigationStrategy(value string) NavigationStrategy {
|
|||||||
return &NavigationStrategyImpl{
|
return &NavigationStrategyImpl{
|
||||||
visitedNodes: []*NodeContext{},
|
visitedNodes: []*NodeContext{},
|
||||||
pathParser: NewPathParser(),
|
pathParser: NewPathParser(),
|
||||||
followAlias: func(nodeContext NodeContext) bool {
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
autoCreateMap: func(nodeContext NodeContext) bool {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
visit: func(nodeContext NodeContext) error {
|
visit: func(nodeContext NodeContext) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import (
|
|||||||
var log = logging.MustGetLogger("yq")
|
var log = logging.MustGetLogger("yq")
|
||||||
|
|
||||||
type UpdateCommand struct {
|
type UpdateCommand struct {
|
||||||
Command string
|
Command string
|
||||||
Path string
|
Path string
|
||||||
Value *yaml.Node
|
Value *yaml.Node
|
||||||
Overwrite bool
|
Overwrite bool
|
||||||
|
DontUpdateNodeValue bool
|
||||||
|
DontUpdateComments bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func KindString(kind yaml.Kind) string {
|
func KindString(kind yaml.Kind) string {
|
||||||
@@ -47,7 +49,7 @@ func DebugNode(value *yaml.Node) {
|
|||||||
log.Error("Error debugging node, %v", errorEncoding.Error())
|
log.Error("Error debugging node, %v", errorEncoding.Error())
|
||||||
}
|
}
|
||||||
encoder.Close()
|
encoder.Close()
|
||||||
log.Debug("Tag: %v, Kind: %v", value.Tag, KindString(value.Kind))
|
log.Debug("Tag: %v, Kind: %v, Anchor: %v", value.Tag, KindString(value.Kind), value.Anchor)
|
||||||
log.Debug("%v", buf.String())
|
log.Debug("%v", buf.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,19 +35,22 @@ type NavigationStrategy interface {
|
|||||||
// we use it to match against the pathExpression in head.
|
// we use it to match against the pathExpression in head.
|
||||||
ShouldTraverse(nodeContext NodeContext, nodeKey string) bool
|
ShouldTraverse(nodeContext NodeContext, nodeKey string) bool
|
||||||
ShouldDeeplyTraverse(nodeContext NodeContext) bool
|
ShouldDeeplyTraverse(nodeContext NodeContext) bool
|
||||||
|
// when deeply traversing, should we visit all matching nodes, or just leaves?
|
||||||
|
ShouldOnlyDeeplyVisitLeaves(NodeContext) bool
|
||||||
GetVisitedNodes() []*NodeContext
|
GetVisitedNodes() []*NodeContext
|
||||||
DebugVisitedNodes()
|
DebugVisitedNodes()
|
||||||
GetPathParser() PathParser
|
GetPathParser() PathParser
|
||||||
}
|
}
|
||||||
|
|
||||||
type NavigationStrategyImpl struct {
|
type NavigationStrategyImpl struct {
|
||||||
followAlias func(nodeContext NodeContext) bool
|
followAlias func(nodeContext NodeContext) bool
|
||||||
autoCreateMap func(nodeContext NodeContext) bool
|
autoCreateMap func(nodeContext NodeContext) bool
|
||||||
visit func(nodeContext NodeContext) error
|
visit func(nodeContext NodeContext) error
|
||||||
shouldVisitExtraFn func(nodeContext NodeContext) bool
|
shouldVisitExtraFn func(nodeContext NodeContext) bool
|
||||||
shouldDeeplyTraverse func(nodeContext NodeContext) bool
|
shouldDeeplyTraverse func(nodeContext NodeContext) bool
|
||||||
visitedNodes []*NodeContext
|
shouldOnlyDeeplyVisitLeaves func(nodeContext NodeContext) bool
|
||||||
pathParser PathParser
|
visitedNodes []*NodeContext
|
||||||
|
pathParser PathParser
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NavigationStrategyImpl) GetPathParser() PathParser {
|
func (ns *NavigationStrategyImpl) GetPathParser() PathParser {
|
||||||
@@ -59,15 +62,32 @@ func (ns *NavigationStrategyImpl) GetVisitedNodes() []*NodeContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NavigationStrategyImpl) FollowAlias(nodeContext NodeContext) bool {
|
func (ns *NavigationStrategyImpl) FollowAlias(nodeContext NodeContext) bool {
|
||||||
return ns.followAlias(nodeContext)
|
if ns.followAlias != nil {
|
||||||
|
return ns.followAlias(nodeContext)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NavigationStrategyImpl) AutoCreateMap(nodeContext NodeContext) bool {
|
func (ns *NavigationStrategyImpl) AutoCreateMap(nodeContext NodeContext) bool {
|
||||||
return ns.autoCreateMap(nodeContext)
|
if ns.autoCreateMap != nil {
|
||||||
|
return ns.autoCreateMap(nodeContext)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NavigationStrategyImpl) ShouldDeeplyTraverse(nodeContext NodeContext) bool {
|
func (ns *NavigationStrategyImpl) ShouldDeeplyTraverse(nodeContext NodeContext) bool {
|
||||||
return ns.shouldDeeplyTraverse(nodeContext)
|
if ns.shouldDeeplyTraverse != nil {
|
||||||
|
return ns.shouldDeeplyTraverse(nodeContext)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *NavigationStrategyImpl) ShouldOnlyDeeplyVisitLeaves(nodeContext NodeContext) bool {
|
||||||
|
if ns.shouldOnlyDeeplyVisitLeaves != nil {
|
||||||
|
return ns.shouldOnlyDeeplyVisitLeaves(nodeContext)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NavigationStrategyImpl) ShouldTraverse(nodeContext NodeContext, nodeKey string) bool {
|
func (ns *NavigationStrategyImpl) ShouldTraverse(nodeContext NodeContext, nodeKey string) bool {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PathParser interface {
|
type PathParser interface {
|
||||||
@@ -45,7 +47,7 @@ func (p *pathParser) MatchesNextPathElement(nodeContext NodeContext, nodeKey str
|
|||||||
}
|
}
|
||||||
var headString = fmt.Sprintf("%v", head)
|
var headString = fmt.Sprintf("%v", head)
|
||||||
|
|
||||||
if strings.Contains(headString, "==") {
|
if strings.Contains(headString, "==") && nodeContext.Node.Kind != yaml.ScalarNode {
|
||||||
log.Debug("ooh deep recursion time")
|
log.Debug("ooh deep recursion time")
|
||||||
result := strings.SplitN(headString, "==", 2)
|
result := strings.SplitN(headString, "==", 2)
|
||||||
path := strings.TrimSpace(result[0])
|
path := strings.TrimSpace(result[0])
|
||||||
@@ -63,6 +65,14 @@ func (p *pathParser) MatchesNextPathElement(nodeContext NodeContext, nodeKey str
|
|||||||
}
|
}
|
||||||
log.Debug("done deep recursing, found %v matches", len(navigationStrategy.GetVisitedNodes()))
|
log.Debug("done deep recursing, found %v matches", len(navigationStrategy.GetVisitedNodes()))
|
||||||
return len(navigationStrategy.GetVisitedNodes()) > 0
|
return len(navigationStrategy.GetVisitedNodes()) > 0
|
||||||
|
} else if strings.Contains(headString, "==") && nodeContext.Node.Kind == yaml.ScalarNode {
|
||||||
|
result := strings.SplitN(headString, "==", 2)
|
||||||
|
path := strings.TrimSpace(result[0])
|
||||||
|
value := strings.TrimSpace(result[1])
|
||||||
|
if path == "." {
|
||||||
|
log.Debug("need to match scalar")
|
||||||
|
return matchesString(value, nodeContext.Node.Value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if head == "+" {
|
if head == "+" {
|
||||||
|
|||||||
@@ -4,12 +4,6 @@ func ReadNavigationStrategy(deeplyTraverseArrays bool) NavigationStrategy {
|
|||||||
return &NavigationStrategyImpl{
|
return &NavigationStrategyImpl{
|
||||||
visitedNodes: []*NodeContext{},
|
visitedNodes: []*NodeContext{},
|
||||||
pathParser: NewPathParser(),
|
pathParser: NewPathParser(),
|
||||||
followAlias: func(nodeContext NodeContext) bool {
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
autoCreateMap: func(nodeContext NodeContext) bool {
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
visit: func(nodeContext NodeContext) error {
|
visit: func(nodeContext NodeContext) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ func UpdateNavigationStrategy(updateCommand UpdateCommand, autoCreate bool) Navi
|
|||||||
autoCreateMap: func(nodeContext NodeContext) bool {
|
autoCreateMap: func(nodeContext NodeContext) bool {
|
||||||
return autoCreate
|
return autoCreate
|
||||||
},
|
},
|
||||||
shouldDeeplyTraverse: func(nodeContext NodeContext) bool {
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
visit: func(nodeContext NodeContext) error {
|
visit: func(nodeContext NodeContext) error {
|
||||||
node := nodeContext.Node
|
node := nodeContext.Node
|
||||||
changesToApply := updateCommand.Value
|
changesToApply := updateCommand.Value
|
||||||
@@ -21,14 +18,20 @@ func UpdateNavigationStrategy(updateCommand UpdateCommand, autoCreate bool) Navi
|
|||||||
DebugNode(node)
|
DebugNode(node)
|
||||||
log.Debug("with")
|
log.Debug("with")
|
||||||
DebugNode(changesToApply)
|
DebugNode(changesToApply)
|
||||||
node.Value = changesToApply.Value
|
if !updateCommand.DontUpdateNodeValue {
|
||||||
|
node.Value = changesToApply.Value
|
||||||
|
}
|
||||||
node.Tag = changesToApply.Tag
|
node.Tag = changesToApply.Tag
|
||||||
node.Kind = changesToApply.Kind
|
node.Kind = changesToApply.Kind
|
||||||
node.Style = changesToApply.Style
|
node.Style = changesToApply.Style
|
||||||
node.Content = changesToApply.Content
|
node.Content = changesToApply.Content
|
||||||
node.HeadComment = changesToApply.HeadComment
|
node.Anchor = changesToApply.Anchor
|
||||||
node.LineComment = changesToApply.LineComment
|
node.Alias = changesToApply.Alias
|
||||||
node.FootComment = changesToApply.FootComment
|
if !updateCommand.DontUpdateComments {
|
||||||
|
node.HeadComment = changesToApply.HeadComment
|
||||||
|
node.LineComment = changesToApply.LineComment
|
||||||
|
node.FootComment = changesToApply.FootComment
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Debug("skipping update as node already has value %v and overwriteFlag is ", node.Value, updateCommand.Overwrite)
|
log.Debug("skipping update as node already has value %v and overwriteFlag is ", node.Value, updateCommand.Overwrite)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ValueParser interface {
|
type ValueParser interface {
|
||||||
Parse(argument string, customTag string) *yaml.Node
|
Parse(argument string, customTag string, customStyle string, anchorName string, createAlias bool) *yaml.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
type valueParser struct {
|
type valueParser struct {
|
||||||
@@ -15,9 +15,32 @@ func NewValueParser() ValueParser {
|
|||||||
return &valueParser{}
|
return &valueParser{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *valueParser) Parse(argument string, customTag string) *yaml.Node {
|
func (v *valueParser) Parse(argument string, customTag string, customStyle string, anchorName string, createAlias bool) *yaml.Node {
|
||||||
if argument == "[]" {
|
var style yaml.Style
|
||||||
return &yaml.Node{Tag: "!!seq", Kind: yaml.SequenceNode}
|
if customStyle == "tagged" {
|
||||||
|
style = yaml.TaggedStyle
|
||||||
|
} else if customStyle == "double" {
|
||||||
|
style = yaml.DoubleQuotedStyle
|
||||||
|
} else if customStyle == "single" {
|
||||||
|
style = yaml.SingleQuotedStyle
|
||||||
|
} else if customStyle == "literal" {
|
||||||
|
style = yaml.LiteralStyle
|
||||||
|
} else if customStyle == "folded" {
|
||||||
|
style = yaml.FoldedStyle
|
||||||
|
} else if customStyle == "flow" {
|
||||||
|
style = yaml.FlowStyle
|
||||||
|
} else if customStyle != "" {
|
||||||
|
log.Error("Unknown style %v, ignoring", customStyle)
|
||||||
}
|
}
|
||||||
return &yaml.Node{Value: argument, Tag: customTag, Kind: yaml.ScalarNode}
|
if argument == "[]" {
|
||||||
|
return &yaml.Node{Tag: "!!seq", Kind: yaml.SequenceNode, Style: style}
|
||||||
|
}
|
||||||
|
|
||||||
|
kind := yaml.ScalarNode
|
||||||
|
|
||||||
|
if createAlias {
|
||||||
|
kind = yaml.AliasNode
|
||||||
|
}
|
||||||
|
|
||||||
|
return &yaml.Node{Value: argument, Tag: customTag, Kind: kind, Style: style, Anchor: anchorName}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,26 @@ import (
|
|||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var parseStyleTests = []struct {
|
||||||
|
customStyle string
|
||||||
|
expectedStyle yaml.Style
|
||||||
|
}{
|
||||||
|
{"", 0},
|
||||||
|
{"tagged", yaml.TaggedStyle},
|
||||||
|
{"double", yaml.DoubleQuotedStyle},
|
||||||
|
{"single", yaml.SingleQuotedStyle},
|
||||||
|
{"folded", yaml.FoldedStyle},
|
||||||
|
{"flow", yaml.FlowStyle},
|
||||||
|
{"literal", yaml.LiteralStyle},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValueParserStyleTag(t *testing.T) {
|
||||||
|
for _, tt := range parseStyleTests {
|
||||||
|
actual := NewValueParser().Parse("cat", "", tt.customStyle, "", false)
|
||||||
|
test.AssertResultWithContext(t, tt.expectedStyle, actual.Style, tt.customStyle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var parseValueTests = []struct {
|
var parseValueTests = []struct {
|
||||||
argument string
|
argument string
|
||||||
customTag string
|
customTag string
|
||||||
@@ -20,7 +40,7 @@ var parseValueTests = []struct {
|
|||||||
|
|
||||||
func TestValueParserParse(t *testing.T) {
|
func TestValueParserParse(t *testing.T) {
|
||||||
for _, tt := range parseValueTests {
|
for _, tt := range parseValueTests {
|
||||||
actual := NewValueParser().Parse(tt.argument, tt.customTag)
|
actual := NewValueParser().Parse(tt.argument, tt.customTag, "", "", false)
|
||||||
test.AssertResultWithContext(t, tt.argument, actual.Value, tt.testDescription)
|
test.AssertResultWithContext(t, tt.argument, actual.Value, tt.testDescription)
|
||||||
test.AssertResultWithContext(t, tt.expectedTag, actual.Tag, tt.testDescription)
|
test.AssertResultWithContext(t, tt.expectedTag, actual.Tag, tt.testDescription)
|
||||||
test.AssertResult(t, yaml.ScalarNode, actual.Kind)
|
test.AssertResult(t, yaml.ScalarNode, actual.Kind)
|
||||||
@@ -28,7 +48,18 @@ func TestValueParserParse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValueParserParseEmptyArray(t *testing.T) {
|
func TestValueParserParseEmptyArray(t *testing.T) {
|
||||||
actual := NewValueParser().Parse("[]", "")
|
actual := NewValueParser().Parse("[]", "", "", "", false)
|
||||||
test.AssertResult(t, "!!seq", actual.Tag)
|
test.AssertResult(t, "!!seq", actual.Tag)
|
||||||
test.AssertResult(t, yaml.SequenceNode, actual.Kind)
|
test.AssertResult(t, yaml.SequenceNode, actual.Kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValueParserParseAlias(t *testing.T) {
|
||||||
|
actual := NewValueParser().Parse("bob", "", "", "", true)
|
||||||
|
test.AssertResult(t, "bob", actual.Value)
|
||||||
|
test.AssertResult(t, yaml.AliasNode, actual.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValueParserAnchorname(t *testing.T) {
|
||||||
|
actual := NewValueParser().Parse("caterpillar", "", "", "foo", false)
|
||||||
|
test.AssertResult(t, "foo", actual.Anchor)
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
- docker build . -t mikefarah/yq:latest -t mikefarah/yq:VERSION
|
- docker build . -t mikefarah/yq:latest -t mikefarah/yq:VERSION
|
||||||
|
|
||||||
- debian package
|
- debian package
|
||||||
|
- ensure you get all vendor dependencies before packaging
|
||||||
|
```go mod vendor```
|
||||||
- execute
|
- execute
|
||||||
```dch -i```
|
```dch -i```
|
||||||
- fill debian/changelog with changes from last version
|
- fill debian/changelog with changes from last version
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -ex
|
||||||
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.23.1
|
|
||||||
go get golang.org/x/tools/cmd/goimports
|
go get golang.org/x/tools/cmd/goimports
|
||||||
|
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.24.0
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
find . \( -path ./vendor \) -prune -o -name "*.go" -exec goimports -w {} \;
|
find . \( -path ./vendor \) -prune -o -name "*.go" -exec goimports -w {} \;
|
||||||
|
go mod tidy
|
||||||
|
|||||||
@@ -7,3 +7,6 @@ gox -ldflags "${LDFLAGS}" -output="build/yq_{{.OS}}_{{.Arch}}"
|
|||||||
# include non-default linux builds too
|
# include non-default linux builds too
|
||||||
gox -ldflags "${LDFLAGS}" -os=linux -output="build/yq_{{.OS}}_{{.Arch}}"
|
gox -ldflags "${LDFLAGS}" -os=linux -output="build/yq_{{.OS}}_{{.Arch}}"
|
||||||
|
|
||||||
|
cd build
|
||||||
|
rhash -r -a . -P -o checksums
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
name: yq
|
name: yq
|
||||||
version: '3.1.2'
|
version: '3.3.2'
|
||||||
summary: A lightweight and portable command-line YAML processor
|
summary: A lightweight and portable command-line YAML processor
|
||||||
description: |
|
description: |
|
||||||
The aim of the project is to be the jq or sed of yaml files.
|
The aim of the project is to be the jq or sed of yaml files.
|
||||||
|
|
||||||
|
base: core18
|
||||||
grade: stable # devel|stable. must be 'stable' to release into candidate/stable channels
|
grade: stable # devel|stable. must be 'stable' to release into candidate/stable channels
|
||||||
confinement: strict
|
confinement: strict
|
||||||
|
|
||||||
@@ -15,8 +16,7 @@ apps:
|
|||||||
parts:
|
parts:
|
||||||
yq:
|
yq:
|
||||||
plugin: go
|
plugin: go
|
||||||
|
go-channel: 1.15/stable
|
||||||
source: .
|
source: .
|
||||||
|
source-type: git
|
||||||
go-importpath: github.com/mikefarah/yq
|
go-importpath: github.com/mikefarah/yq
|
||||||
after: [go]
|
|
||||||
go:
|
|
||||||
source-tag: go1.11
|
|
||||||
|
|||||||
3
yq.go
3
yq.go
@@ -4,14 +4,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
command "github.com/mikefarah/yq/v3/cmd"
|
command "github.com/mikefarah/yq/v3/cmd"
|
||||||
logging "gopkg.in/op/go-logging.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd := command.New()
|
cmd := command.New()
|
||||||
log := logging.MustGetLogger("yq")
|
|
||||||
if err := cmd.Execute(); err != nil {
|
if err := cmd.Execute(); err != nil {
|
||||||
log.Error(err.Error())
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user